-
Notifications
You must be signed in to change notification settings - Fork 0
/
euage.cpp
189 lines (142 loc) · 4.91 KB
/
euage.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*
Program euage 1.0
Written by Peter Zeitler in 2014
C++ to be more easily compatible with Rich Ketcham's RDAAM code.
This program was kludged together by grabbing the wrapper from my crankfunc code,
just using that to call RDAAM/ZRDAAM. Written only for apatite and zircon.
The wrapper pulls in one input file with required sample data, and another with the
desired thermal history.
It runs in a loop across a range of eU values, having the same U/Th/Sm proportions as
the sample.
Zoning can't be modeled.
usage:
./euage <#of eU values>. <step between eU values>
*/
using namespace std;
#include <cstring>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <time.h>
#include <vector>
#include "tchar.h"
#include "ZRDAAM.h" // from Rich Ketcham
int main(int argc, char * argv[])
{
// declarations
FILE *ofp, *ifp; // for file I/O
TTPath path; // for RDAAM, custom data type
TTPathPoint mypoint; // for RDAAM, custom data type
int mineral, ttpairs_in;
long i, ieu;
double U_sample, TH_sample, SM_sample, U, TH, SM, radius;
double EUS, ZMAG;
// ***** Start up
if(argc < 3) // there are only one or fewer values and we need two (besides the program name)
{
puts("\n euage ERROR: not enough parameters");
puts(" USAGE: ./euage <#eu's< <eU-stepsize-for-zir>\n");
exit(1);
}
if(argc > 3) // there are more than two and thus extra inputs
{
puts("\n euage WARNING: too many parameters - using only first two");
puts(" USAGE: ./euage <#eu's< <eU-stepsize-for-zir>\n");
}
printf("\n");
printf("*** PROGRAM euage() 1.0alpha ***\n\n");
EUS = atoi(argv[1]);
ZMAG = atof(argv[2]);
vector<double> eu_save(EUS);
vector<double> raw_age(EUS);
vector<double> alpha_age(EUS);
// get data from files
ifp = fopen("euage.in", "r");
fscanf(ifp, "%d", &mineral);
assert((mineral >= 0) and (mineral <= 1)); // 0 apatite, 1 zircon
fscanf(ifp, "%lf", &U_sample); // ppm
fscanf(ifp, "%lf", &TH_sample); // ppm
fscanf(ifp, "%lf", &SM_sample); // ppm
fscanf(ifp, "%lf", &radius); // microns
// echo inputs as record of what should be happening
switch (mineral) // illegal values ruled out on input
{
case 0: // apatite
printf(" modeling apatite with spherical geometry, RDAAM, and alpha-ejection\n");
break;
case 1: // zircon
printf(" modeling zircon with spherical geometry, ZRDAAM, and alpha-ejection\n");
break;
}
printf("\n Radius: %6.2f microns\nU-Th-Sm (ppm): %6.2f %6.2f %6.2f\n\n",radius, U_sample, TH_sample, SM_sample);
fclose(ifp);
// now get the input thermal history (from file)
ifp = fopen("euage_history.in", "r");
fscanf(ifp, "%d", &ttpairs_in); // oldest pair first
assert ((ttpairs_in > 1) && (ttpairs_in <= 1001));
vector<double> intime(ttpairs_in);
vector<double> intemp(ttpairs_in);
for (i = 0; i < ttpairs_in; i++)
{
fscanf(ifp, "%lf%lf",&intime[i], &intemp[i]);
}
fclose(ifp);
// ***** do the actual work
double age, corrAge, eU, eU_sample;
eU_sample = U_sample + 0.2376 * TH_sample + 0.0012 * SM_sample;
for (ieu=0;ieu<EUS;ieu++)
{
eU = ZMAG * (static_cast<double> (ieu) + 1.);
if (mineral == 0) // apatite
{
// turn local eU value into its component U, Th, and Sm values, assuming same proportion as sample
U = U_sample * eU / eU_sample;
TH = TH_sample * eU / eU_sample;
SM = SM_sample * eU / eU_sample;
RDAAM_Init(HE_PREC_BEST, radius, U, TH, SM); // precision, radius, U, Th, Sm
path.clear();
for (i = ttpairs_in-1; i >= 0; i--) // RDAAM wants most recent pair first
{
mypoint.time = intime[i];
mypoint.temperature = intemp[i];
path.push_back(mypoint); // Present day is first entry in path
}
int success = RDAAM_Calculate(&path, age, corrAge);
}
else // zircon
{
// turn local eU value into component U, Th, and Sm values having same proportion as sample
U = U_sample * eU / eU_sample;
TH = TH_sample * eU / eU_sample;
SM = SM_sample * eU / eU_sample;
ZRDAAM_Init(HE_PREC_BEST, radius, U, TH, SM); // precision, radius, U, Th, Sm
// RDAAM_Init(HE_PREC_BEST, 55., 15., 15., 15.); // precision, radius, U, Th, Sm
path.clear();
for (i = ttpairs_in-1; i >= 0; i--) // RDAAM wants most recent pair first
{
mypoint.time = intime[i];
mypoint.temperature = intemp[i];
path.push_back(mypoint); // Present day is first entry in path
}
int success = RDAAM_Calculate(&path, age, corrAge);
}
eu_save[ieu] = eU;
raw_age[ieu] = age;
alpha_age[ieu] = corrAge;
}
// ***** Wrap up
ofp = fopen("eugage_OUT.xls","w");
printf(" eU Raw(Ma) Corr(Ma)\n");
printf("-------------------------\n");
for (ieu=0;ieu<EUS;ieu++)
{
printf("%4.0f\t%7.2f\t%7.2f\n",eu_save[ieu],raw_age[ieu],alpha_age[ieu]);
fprintf(ofp,"%4.0f\t%7.2f\t%7.2f\n",eu_save[ieu],raw_age[ieu],alpha_age[ieu]);
}
fclose(ofp);
return 0;
} // end of main()