|
1 | 1 | #ifndef actual_network_H |
2 | 2 | #define actual_network_H |
3 | 3 |
|
| 4 | +#define NEW_NETWORK_IMPLEMENTATION |
| 5 | + |
4 | 6 | #include <AMReX_REAL.H> |
5 | 7 | #include <AMReX_Vector.H> |
6 | 8 | #include <AMReX_Array.H> |
7 | 9 |
|
8 | 10 | #include <fundamental_constants.H> |
9 | 11 | #include <network_properties.H> |
| 12 | +#include <rhs_type.H> |
10 | 13 |
|
11 | 14 | using namespace amrex; |
12 | 15 |
|
13 | | -void actual_network_init(); |
| 16 | +AMREX_INLINE |
| 17 | +void actual_network_init() {} |
14 | 18 |
|
15 | 19 | const std::string network_name = "ignition_chamulak"; |
16 | 20 |
|
17 | | -namespace network |
18 | | -{ |
19 | | - // M12_chamulak is the effective number of C12 nuclei destroyed per |
20 | | - // reaction |
21 | | - const Real M12_chamulak = 2.93e0_rt; |
22 | | -} |
23 | | - |
24 | 21 | namespace Rates |
25 | 22 | { |
26 | 23 | enum NetworkRates { |
27 | | - NumRates = 1 |
| 24 | + chamulak_rate = 1, |
| 25 | + NumRates = chamulak_rate |
28 | 26 | }; |
29 | 27 | }; |
30 | 28 |
|
| 29 | +namespace RHS { |
| 30 | + |
| 31 | + AMREX_GPU_HOST_DEVICE AMREX_INLINE |
| 32 | + constexpr rhs_t rhs_data (int rate) |
| 33 | + { |
| 34 | + using namespace Species; |
| 35 | + using namespace Rates; |
| 36 | + |
| 37 | + rhs_t data; |
| 38 | + |
| 39 | + switch (rate) { |
| 40 | + |
| 41 | + case chamulak_rate: |
| 42 | + data.species_A = C12; |
| 43 | + data.species_D = Ash; |
| 44 | + |
| 45 | + // The composite "ash" particle we are creating has a A = 18, |
| 46 | + // while we are consuming 2 C12 nucleons to create it. In order |
| 47 | + // to conserve mass, we need to scale the number of ash particles |
| 48 | + // created by 24 / 18 = 4 / 3. |
| 49 | + |
| 50 | + data.number_A = 2.0_rt; |
| 51 | + data.number_D = 4.0_rt / 3.0_rt; |
| 52 | + |
| 53 | + data.exponent_A = 2; |
| 54 | + data.exponent_D = 1; |
| 55 | + |
| 56 | + // For each reaction, we lose 2.93 C12 nuclei (for a single rate, |
| 57 | + // C12+C12, we would lose 2. In Chamulak et al. (2008), they say a |
| 58 | + // value of 2.93 captures the energetics from a larger network. |
| 59 | + |
| 60 | + data.forward_branching_ratio = 2.93e0_rt / 2.0_rt; |
| 61 | + break; |
| 62 | + |
| 63 | + } |
| 64 | + |
| 65 | + return data; |
| 66 | + } |
| 67 | + |
| 68 | + template<int rate> |
| 69 | + AMREX_GPU_HOST_DEVICE AMREX_INLINE |
| 70 | + void evaluate_analytical_rate (const rhs_state_t& state, rate_t& rates) |
| 71 | + { |
| 72 | + using namespace Species; |
| 73 | + using namespace Rates; |
| 74 | + |
| 75 | + if constexpr (rate == chamulak_rate) { |
| 76 | + // compute some often used temperature constants |
| 77 | + Real T9 = state.tf.t9; |
| 78 | + Real dT9dt = 1.0_rt / 1.0e9_rt; |
| 79 | + Real T9a = T9 / (1.0_rt + 0.0396e0_rt * T9); |
| 80 | + Real dT9adt = (T9a / T9 - (T9a / (1.0_rt + 0.0396e0_rt * T9)) * 0.0396e0_rt) * dT9dt; |
| 81 | + |
| 82 | + // compute the CF88 rate |
| 83 | + Real scratch = std::pow(T9a, 1.0_rt / 3.0_rt); |
| 84 | + Real dscratchdt = (1.0_rt / 3.0_rt) * std::pow(T9a, -2.0_rt / 3.0_rt) * dT9adt; |
| 85 | + |
| 86 | + Real a = 4.27e26_rt * std::pow(T9a, 5.0_rt / 6.0_rt) * std::pow(T9, -1.5e0_rt); |
| 87 | + Real dadt = (5.0_rt / 6.0_rt) * (a / T9a) * dT9adt - 1.5e0_rt * (a / T9) * dT9dt; |
| 88 | + |
| 89 | + Real b = std::exp(-84.165e0_rt / scratch - 2.12e-3_rt * T9 * T9 * T9); |
| 90 | + Real dbdt = (84.165e0_rt * dscratchdt / (scratch * scratch) - 3.0_rt * 2.12e-3_rt * T9 * T9 * dT9dt) * b; |
| 91 | + |
| 92 | + rates.fr = a * b; |
| 93 | + rates.frdt = dadt * b + a * dbdt; |
| 94 | + |
| 95 | + rates.rr = 0.0_rt; |
| 96 | + rates.rrdt = 0.0_rt; |
| 97 | + } |
| 98 | + } |
| 99 | + |
| 100 | + template<int rate> |
| 101 | + AMREX_GPU_HOST_DEVICE AMREX_INLINE |
| 102 | + void postprocess_rate (const rhs_state_t& state, rate_t& rates, |
| 103 | + rate_t& rates1, rate_t& rates2, rate_t& rates3) |
| 104 | + { |
| 105 | + // Nothing to do for this network. |
| 106 | + } |
| 107 | + |
| 108 | + template<int spec> |
| 109 | + AMREX_GPU_HOST_DEVICE AMREX_INLINE |
| 110 | + Real ener_gener_rate (const rhs_state_t& rhs_state, Real const& dydt) |
| 111 | + { |
| 112 | + // Chamulak et al. provide the q-value resulting from C12 burning, |
| 113 | + // given as 3 different values (corresponding to 3 different densities). |
| 114 | + // Here we do a simple quadratic fit to the 3 values provided (see |
| 115 | + // Chamulak et al., p. 164, column 2). |
| 116 | + |
| 117 | + // our convention is that the binding energies are negative. We convert |
| 118 | + // from the MeV values that are traditionally written in astrophysics |
| 119 | + // papers by multiplying by 1.e6 eV/MeV * 1.60217646e-12 erg/eV. The |
| 120 | + // MeV values are per nucleus, so we divide by aion to make it per |
| 121 | + // nucleon and we multiple by Avogardo's # (6.0221415e23) to get the |
| 122 | + // value in erg/g |
| 123 | + Real rho9 = rhs_state.rho / 1.0e9_rt; |
| 124 | + |
| 125 | + // q_eff is effective heat evolved per reaction (given in MeV) |
| 126 | + Real q_eff = 0.06e0_rt * rho9 * rho9 + 0.02e0_rt * rho9 + 8.83e0_rt; |
| 127 | + |
| 128 | + // convert from MeV to ergs / gram. Here 2.93 is the |
| 129 | + // number of C12 nuclei destroyed in a single reaction and 12.0 is |
| 130 | + // the mass of a single C12 nuclei. Also note that our convention |
| 131 | + // is that binding energies are negative. |
| 132 | + Real ebin_C12 = -q_eff * C::MeV2eV * C::ev2erg * C::n_A / (2.93e0_rt * 12.0e0_rt); |
| 133 | + |
| 134 | + if constexpr (spec == Species::C12) { |
| 135 | + return dydt * NetworkProperties::aion(spec) * ebin_C12; |
| 136 | + } |
| 137 | + else { |
| 138 | + return 0.0_rt; |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | +} // namespace RHS |
| 143 | + |
31 | 144 | #endif |
0 commit comments