|
1 | 1 | #ifndef actual_integrator_H
|
2 | 2 | #define actual_integrator_H
|
3 | 3 |
|
4 |
| -#include <AMReX_Print.H> |
5 |
| - |
6 |
| -#include <iomanip> |
7 |
| - |
8 | 4 | #include <network.H>
|
9 | 5 | #include <burn_type.H>
|
10 | 6 |
|
| 7 | +#include <integrator_data.H> |
| 8 | +#include <integrator_setup_strang.H> |
| 9 | + |
11 | 10 | #include <be_type.H>
|
12 | 11 | #include <be_integrator.H>
|
13 | 12 |
|
14 | 13 | template <typename BurnT>
|
15 | 14 | AMREX_GPU_HOST_DEVICE AMREX_INLINE
|
16 | 15 | void actual_integrator (BurnT& state, const amrex::Real dt, bool is_retry=false)
|
17 | 16 | {
|
18 |
| - constexpr int int_neqs = integrator_neqs<BurnT>(); |
19 |
| - |
20 |
| - be_t<int_neqs> be; |
21 |
| - |
22 |
| - // Set the tolerances. |
23 |
| - |
24 |
| - if (!is_retry) { |
25 |
| - be.atol_spec = atol_spec; // mass fractions |
26 |
| - be.atol_enuc = atol_enuc; // energy generated |
27 |
| - |
28 |
| - be.rtol_spec = rtol_spec; // mass fractions |
29 |
| - be.rtol_enuc = rtol_enuc; // energy generated |
30 |
| - } else { |
31 |
| - be.atol_spec = retry_atol_spec; // mass fractions |
32 |
| - be.atol_enuc = retry_atol_enuc; // energy generated |
33 |
| - |
34 |
| - be.rtol_spec = retry_rtol_spec; // mass fractions |
35 |
| - be.rtol_enuc = retry_rtol_enuc; // energy generated |
36 |
| - } |
37 |
| - |
38 |
| - // set the Jacobian type |
39 |
| - if (is_retry && integrator_rp::retry_swap_jacobian) { |
40 |
| - be.jacobian_type = (jacobian == 1) ? 2 : 1; |
41 |
| - } else { |
42 |
| - be.jacobian_type = jacobian; |
43 |
| - } |
44 |
| - |
45 |
| - // Start off by assuming a successful burn. |
46 |
| - |
47 |
| - state.success = true; |
48 |
| - |
49 |
| - // Initialize the integration time. |
50 |
| - |
51 |
| - be.t = 0.0_rt; |
52 |
| - be.tout = dt; |
53 |
| - |
54 |
| - // Initialize ydot to zero for Strang burn. |
55 |
| - |
56 |
| - for (int n = 0; n < SVAR; ++n) { |
57 |
| - state.ydot_a[n] = 0; |
58 |
| - } |
59 |
| - |
60 |
| - // We assume that (rho, T) coming in are valid, do an EOS call |
61 |
| - // to fill the rest of the thermodynamic variables. |
62 |
| - |
63 |
| - eos(eos_input_rt, state); |
64 |
| - |
65 |
| - // set the scaling for energy if we integrate it dimensionlessly |
66 |
| - state.e_scale = state.e; |
67 |
| - |
68 |
| - if (scale_system) { |
69 |
| - // the absolute tol for energy needs to reflect the scaled |
70 |
| - // energy the integrator sees |
71 |
| - be.atol_enuc /= state.e_scale; |
72 |
| - } |
73 |
| - |
74 |
| - // Fill in the initial integration state. |
75 |
| - |
76 |
| - burn_to_integrator(state, be); |
77 | 17 |
|
78 |
| - // Save the initial composition, temperature, and energy for our later diagnostics. |
79 |
| - |
80 |
| -#ifndef AMREX_USE_GPU |
81 |
| - amrex::Real xn_in[NumSpec]; |
82 |
| - for (int n = 0; n < NumSpec; ++n) { |
83 |
| - xn_in[n] = state.xn[n]; |
84 |
| - } |
85 |
| - const amrex::Real T_in = state.T; |
86 |
| -#endif |
87 |
| - const amrex::Real e_in = state.e; |
88 |
| - |
89 |
| - // Call the integration routine. |
90 |
| - |
91 |
| - int istate = be_integrator(state, be); |
92 |
| - state.error_code = istate; |
93 |
| - |
94 |
| - // Copy the integration data back to the burn state. |
95 |
| - |
96 |
| - integrator_to_burn(be, state); |
97 |
| - |
98 |
| -#ifdef NSE |
99 |
| - // compute the temperature based on the energy release -- we need |
100 |
| - // this in case we failed in our burn here because we entered NSE |
101 |
| - |
102 |
| -#ifdef AUX_THERMO |
103 |
| - // need to sync the auxiliary data up with the new mass fractions |
104 |
| - set_aux_comp_from_X(state); |
105 |
| -#endif |
106 |
| - if (call_eos_in_rhs) { |
107 |
| - eos(eos_input_re, state); |
108 |
| - } |
109 |
| -#endif |
110 |
| - |
111 |
| - // Subtract off the initial energy if the application codes expect |
112 |
| - // to get back only the generated energy during the burn. |
113 |
| - if (integrator_rp::subtract_internal_energy) { |
114 |
| - state.e -= e_in; |
115 |
| - } |
116 |
| - |
117 |
| - // Normalize the final abundances. |
118 |
| - |
119 |
| - if (! integrator_rp::use_number_densities) { |
120 |
| - normalize_abundances_burn(state); |
121 |
| - } |
122 |
| - |
123 |
| - // Get the number of RHS and Jacobian evaluations. |
124 |
| - |
125 |
| - state.n_rhs = be.n_rhs; |
126 |
| - state.n_jac = be.n_jac; |
127 |
| - state.n_step = be.n_step; |
128 |
| - |
129 |
| - // BE does not always fail even though it can lead to unphysical states. |
130 |
| - // Add some checks that indicate a burn fail even if VODE thinks the |
131 |
| - // integration was successful. |
132 |
| - |
133 |
| - if (istate != IERR_SUCCESS) { |
134 |
| - state.success = false; |
135 |
| - } |
136 |
| - |
137 |
| - for (int n = 1; n <= NumSpec; ++n) { |
138 |
| - if (be.y(n) < -species_failure_tolerance) { |
139 |
| - state.success = false; |
140 |
| - } |
| 18 | + constexpr int int_neqs = integrator_neqs<BurnT>(); |
141 | 19 |
|
142 |
| - // Don't enforce a max if we are evolving number densities |
| 20 | + auto be_state = integrator_setup<BurnT, be_t<int_neqs>>(state, dt, is_retry); |
143 | 21 |
|
144 |
| - if (! integrator_rp::use_number_densities) { |
145 |
| - if (be.y(n) > 1.0_rt + species_failure_tolerance) { |
146 |
| - state.success = false; |
147 |
| - } |
148 |
| - } |
149 |
| - } |
| 22 | + auto state_save = integrator_backup(state); |
150 | 23 |
|
151 |
| -#ifndef AMREX_USE_GPU |
152 |
| - if (burner_verbose) { |
153 |
| - // Print out some integration statistics, if desired. |
154 |
| - std::cout << "integration summary: " << std::endl; |
155 |
| - std::cout << "dens: " << state.rho << " temp: " << state.T << std::endl; |
156 |
| - std::cout << "energy released: " << state.e << std::endl; |
157 |
| - std::cout << "number of steps taken: " << state.n_step << std::endl; |
158 |
| - std::cout << "number of f evaluations: " << state.n_rhs << std::endl; |
159 |
| - } |
160 |
| -#endif |
| 24 | + auto istate = be_integrator(state, be_state); |
161 | 25 |
|
162 |
| - // If we failed, print out the current state of the integration. |
| 26 | + integrator_cleanup(be_state, state, istate, state_save, dt); |
163 | 27 |
|
164 |
| - if (!state.success) { |
165 |
| - if (istate != IERR_ENTERED_NSE) { |
166 |
| -#ifndef AMREX_USE_GPU |
167 |
| - std::cout << amrex::Font::Bold << amrex::FGColor::Red << "[ERROR] integration failed in net" << amrex::ResetDisplay << std::endl; |
168 |
| - std::cout << "istate = " << istate << std::endl; |
169 |
| - if (istate == IERR_SUCCESS) { |
170 |
| - std::cout << " BE exited successfully, but a check on the data values failed" << std::endl; |
171 |
| - } |
172 |
| - std::cout << "zone = (" << state.i << ", " << state.j << ", " << state.k << ")" << std::endl; |
173 |
| - std::cout << "time = " << be.t << std::endl; |
174 |
| - std::cout << "dt = " << std::setprecision(16) << dt << std::endl; |
175 |
| - std::cout << "temp start = " << std::setprecision(16) << T_in << std::endl; |
176 |
| - std::cout << "xn start = "; |
177 |
| - for (const auto X: xn_in) { |
178 |
| - std::cout << std::setprecision(16) << X << " "; |
179 |
| - } |
180 |
| - std::cout << std::endl; |
181 |
| - std::cout << "dens current = " << std::setprecision(16) << state.rho << std::endl; |
182 |
| - std::cout << "temp current = " << std::setprecision(16) << state.T << std::endl; |
183 |
| - std::cout << "xn current = "; |
184 |
| - for (const auto X: state.xn) { |
185 |
| - std::cout << std::setprecision(16) << X << " "; |
186 |
| - } |
187 |
| - std::cout << std::endl; |
188 |
| - std::cout << "energy generated = " << state.e << std::endl; |
189 |
| -#endif |
190 |
| - } else { |
191 |
| -#ifndef AMREX_USE_GPU |
192 |
| - std::cout << "burn entered NSE during integration (after " << state.n_step << " steps), zone = (" << state.i << ", " << state.j << ", " << state.k << ")" << std::endl; |
193 |
| -#endif |
194 |
| - } |
195 |
| - } |
196 | 28 | }
|
197 | 29 |
|
198 | 30 | #endif
|
0 commit comments