forked from AMReX-Astro/Microphysics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathburn_cell.H
222 lines (163 loc) · 6.38 KB
/
burn_cell.H
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#ifndef BURN_CELL_H
#define BURN_CELL_H
#include <extern_parameters.H>
#include <eos.H>
#include <network.H>
#include <burner.H>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <react_util.H>
using namespace unit_test_rp;
AMREX_INLINE
void burn_cell_c()
{
amrex::Real massfractions[NumSpec] = {-1.0};
// Make sure user set all the mass fractions to values in the interval [0, 1]
for (int n = 1; n <= NumSpec; ++n) {
massfractions[n-1] = get_xn(n, unit_test_rp::uniform_xn);
if (massfractions[n-1] < 0 || massfractions[n-1] > 1) {
amrex::Error("mass fraction for " + short_spec_names_cxx[n-1] + " not initialized in the interval [0,1]!");
}
}
// Echo initial conditions at burn and fill burn state input
std::cout << "Maximum Time (s): " << tmax << std::endl;
std::cout << "State Density (g/cm^3): " << density << std::endl;
std::cout << "State Temperature (K): " << temperature << std::endl;
for (int n = 0; n < NumSpec; ++n) {
std::cout << "Mass Fraction (" << short_spec_names_cxx[n] << "): " << massfractions[n] << std::endl;
}
burn_t burn_state;
eos_t eos_state;
eos_state.rho = density;
eos_state.T = temperature;
for (int n = 0; n < NumSpec; n++) {
eos_state.xn[n] = massfractions[n];
}
#ifdef AUX_THERMO
set_aux_comp_from_X(eos_state);
#endif
eos(eos_input_rt, eos_state);
burn_state.rho = eos_state.rho;
burn_state.T = eos_state.T;
for (int n = 0; n < NumSpec; ++n) {
burn_state.xn[n] = massfractions[n];
}
#if NAUX_NET > 0
for (int n = 0; n < NumAux; ++n) {
burn_state.aux[n] = eos_state.aux[n];
}
#endif
burn_state.i = 0;
burn_state.j = 0;
burn_state.k = 0;
burn_state.T_fixed = -1.0_rt;
burn_state.time = 0.0;
// normalize -- just in case
if (! skip_initial_normalization) {
normalize_abundances_burn(burn_state);
}
// call the EOS to set initial e -- it actually doesn't matter to
// the burn but we need to keep track of e to get a valid
// temperature for the burn if we substep
eos(eos_input_rt, burn_state);
// output just the instantaneous RHS
amrex::Array1D<amrex::Real, 1, neqs> ydot;
actual_rhs(burn_state, ydot);
std::cout << "RHS at t = 0" << std::endl;
for(int n = 0; n < NumSpec; ++n){
const std::string& element = short_spec_names_cxx[n];
std::cout << std::setw(6) << element << " " << ydot(n+1) << std::endl;
}
// output initial burn type data
std::ofstream state_over_time("state_over_time.txt");
// we will divide the total integration time into nsteps that are
// logarithmically spaced
if (tfirst == 0.0_rt) {
if (nsteps == 1) {
tfirst = tmax;
} else {
tfirst = tmax / nsteps;
}
}
amrex::Real dlogt = 0.0_rt;
if (nsteps == 1) {
dlogt = (std::log10(tmax) - std::log10(tfirst));
} else {
dlogt = (std::log10(tmax) - std::log10(tfirst)) / (nsteps - 1);
}
// save the initial state -- we'll use this to determine
// how much things changed over the entire burn
burn_t burn_state_in = burn_state;
// output the data in columns, one line per timestep
state_over_time << std::setw(25) << "# Time";
state_over_time << std::setw(25) << "Temperature";
for(int x = 0; x < NumSpec; ++x){
const std::string& element = short_spec_names_cxx[x];
state_over_time << std::setw(25) << element;
}
state_over_time << std::endl;
state_over_time << std::setprecision(15);
amrex::Real t = 0.0;
state_over_time << std::setw(25) << t;
state_over_time << std::setw(25) << burn_state.T;
for (double X : burn_state.xn) {
state_over_time << std::setw(25) << X;
}
state_over_time << std::endl;
// store the initial internal energy -- we'll update this after
// each substep
amrex::Real energy_initial = burn_state.e;
// loop over steps, burn, and output the current state
int nstep_int = 0;
for (int n = 0; n < nsteps; n++){
// compute the time we wish to integrate to
amrex::Real tend = std::pow(10.0_rt, std::log10(tfirst) + dlogt * n);
amrex::Real dt = tend - t;
burner(burn_state, dt);
if (! burn_state.success) {
amrex::Error("integration failed");
}
nstep_int += burn_state.n_step;
// state.e represents the change in energy over the burn (for
// just this sybcycle), so turn it back into a physical energy
burn_state.e += energy_initial;
// reset the initial energy for the next subcycle
energy_initial = burn_state.e;
// get the updated T
if (integrator_rp::call_eos_in_rhs) {
eos(eos_input_re, burn_state);
}
t += dt;
state_over_time << std::setw(25) << t;
state_over_time << std::setw(25) << burn_state.T;
for (double X : burn_state.xn) {
state_over_time << std::setw(25) << X;
}
state_over_time << std::endl;
}
state_over_time.close();
// output diagnostics to the terminal
std::cout << "------------------------------------" << std::endl;
std::cout << "successful? " << burn_state.success << std::endl;
std::cout << " - Hnuc = " << (burn_state.e - burn_state_in.e) / tmax << std::endl;
std::cout << " - added e = " << burn_state.e - burn_state_in.e << std::endl;
std::cout << " - final T = " << burn_state.T << std::endl;
std::cout << "------------------------------------" << std::endl;
std::cout << "e initial = " << burn_state_in.e << std::endl;
std::cout << "e final = " << burn_state.e << std::endl;
std::cout << "------------------------------------" << std::endl;
std::cout << "new mass fractions: " << std::endl;
for (int n = 0; n < NumSpec; ++n) {
const std::string& element = short_spec_names_cxx[n];
std::cout << element << " " << burn_state.xn[n] << std::endl;
}
std::cout << "------------------------------------" << std::endl;
std::cout << "species creation rates: " << std::endl;
for (int n = 0; n < NumSpec; ++n) {
std::cout << "omegadot(" << short_spec_names_cxx[n] << "): "
<< (burn_state.xn[n] - burn_state_in.xn[n]) / tmax << std::endl;
}
std::cout << "number of steps taken: " << nstep_int << std::endl;
}
#endif