Cholla 3.0.1-dev
Cholla - Massively parallel hydro on GPUs
Loading...
Searching...
No Matches
ratecalc.h
1#ifndef FEEDBACK_RATECALC_H
2#define FEEDBACK_RATECALC_H
3
4#ifdef O_HIP
5 #include <hiprand.h>
6 #include <hiprand_kernel.h>
7#else
8 #include <curand.h>
9 #include <curand_kernel.h>
10#endif // O_HIP
11
12#include <string>
13
14#include "../global/global.h"
15#include "../io/ParameterMap.h"
16#include "../utils/gpu.hpp"
17
18typedef curandStateMRG32k3a_t feedback_prng_t;
19
20// This header declares classes that encapsulate calculations of SN rates and the rate of SW
21// deposition
22//
23// Currently, they don't have destructors that deallocate the data. This is fine in the short term,
24// since we only construct up to a single instance of each class on the host during the entire
25// simulation. With that said, I do have a strategy in mind for resolving this.
26
27// seed for poisson random number generator
28#define FEEDBACK_SEED 42
29
30// the starburst 99 total stellar mass input
31// stellar wind momentum fluxes and SN rates
32// must be divided by this to get per solar
33// mass values.
34#define S_99_TOTAL_MASS 1e6
35
36namespace feedback
37{
38/* The following should really be macros */
39// supernova rate: 1SN / 100 solar masses per 36 Myr
40static const Real DEFAULT_SNR = 2.8e-7;
41// default value for when SNe stop (40 Myr)
42static const Real DEFAULT_SN_END = 40000;
43// default value for when SNe start (4 Myr)
44static const Real DEFAULT_SN_START = 4000;
45
46/* Encapsulate Supernova Rate Calculation that is primarily intended to interpolate the data from
47 * starburst99 tables.
48 *
49 * @note
50 * The destructor doesn't currently deallocate the device heap-data. That's okay for the moment
51 * because the only way to allocate that data at the moment is to call the table-reader constructor,
52 * and that table-reader particular constructor is only called once during the entire duration of
53 * the simulation. With that said, I do have plans to address this issue in the future.
54 */
55struct SNRateCalc {
56 public:
57 /* Default constructor. Ensures this object is always in a usable state
58 *
59 * This assumes a constant supernova rate given by feedback::DEFAULT_SNR
60 */
61 __host__ __device__ SNRateCalc()
62 : dev_snr_(nullptr),
63 snr_dt_(feedback::DEFAULT_SN_END - feedback::DEFAULT_SN_START),
64 time_sn_start_(feedback::DEFAULT_SN_START),
65 time_sn_end_(feedback::DEFAULT_SN_END)
66 {
67 }
68
69 /* The "table-reader" constructor.
70 *
71 * Reads data from the specified file and allocates heapdata. If no file was specified, fall back
72 * to configuration assumed in default constructor.
73 *
74 * @param P reference to parameters struct. Passes in starburst 99 filename.
75 */
76 __host__ SNRateCalc(ParameterMap &pmap);
77
78 /* returns supernova rate from starburst 99 (or default analytical rate).
79 *
80 * Does a basic interpolation of S'99 table values.
81 *
82 * @param t The cluster age.
83 * @return number of SNe per kyr per solar mass
84 *
85 * @note
86 * It's important to retain the inline annotation to maximize the chance of inlining.
87 */
88 inline __device__ Real Get_SN_Rate(Real t) const
89 {
90 if ((t < time_sn_start_) or (t >= time_sn_end_)) return 0;
91 if (dev_snr_ == nullptr) return feedback::DEFAULT_SNR;
92
93 int index = (int)((t - time_sn_start_) / snr_dt_);
94 return dev_snr_[index] + (t - index * snr_dt_) * (dev_snr_[index + 1] - dev_snr_[index]) / snr_dt_;
95 }
96
97 /* Get an actual number of SNe given the expected number. Both the simulation step number
98 * and cluster ID is used to set the state of the random number generator in a unique and
99 * deterministic way.
100 *
101 * @param ave_num_sn expected number of SN, based on cluster age, mass and time step.
102 * @param n_step sim step number
103 * @param cluster_id
104 * @return number of supernovae
105 *
106 * @note
107 * It's important to retain the inline annotation to maximize the chance of inlining
108 */
109 static inline __device__ int Get_Number_Of_SNe_In_Cluster(Real ave_num_sn, int n_step, part_int_t cluster_id)
110 {
111 feedback_prng_t state;
112 // Note: in the C++ spec, wrap-around behavior is well-defined for unsigned types during integer
113 // overflow (overflow for signed types invokes undefined behavior)
114 unsigned long long seed = (cluster_id < 0)
115 ? (unsigned long long)(FEEDBACK_SEED) - (unsigned long long)(-1 * cluster_id)
116 : (unsigned long long)(FEEDBACK_SEED) + (unsigned long long)(cluster_id);
117 curand_init(seed, 0, 0, &state);
118 skipahead((unsigned long long)(n_step), &state); // provided by curand
119 return (int)curand_poisson(&state, ave_num_sn);
120 }
121
122 inline __device__ bool nonzero_sn_probability(Real age) const
123 {
124 return (time_sn_start_ <= age) and (age <= time_sn_end_);
125 }
126
127 private: // attributes
128 /* device array with rate info */
129 Real *dev_snr_;
130 /* time interval between table data. Assumed to be constant. */
131 Real snr_dt_;
132 /* cluster age when SNR is first greater than zero. */
133 Real time_sn_start_;
134 /* cluster age when SNR drops to zero. */
135 Real time_sn_end_;
136};
137
138/* Class responsible for computing stellar-wind rates
139 *
140 * @note
141 * These were pretty much extracted directly from feedback.cu. There's a chance that there are some
142 * logical errors in these functions. In particular, the way we have been using the Wind_Flux and
143 * Wind_Power to update gas-momentum and gas-energy is inconsistent.
144 *
145 * @note
146 * The destructor doesn't currently deallocate the device heap-data. That's okay for the moment
147 * because the only way to allocate that data at the moment is to call the table-reader constructor,
148 * and that table-reader particular constructor is only called once during the entire duration of
149 * the simulation. With that said, I do have plans to address this issue in the future.
150 */
152 __host__ SWRateCalc(ParameterMap &P);
153
154 __host__ __device__ SWRateCalc(Real *dev_sw_p, Real *dev_sw_e, Real dt, Real t_start, Real t_end)
155 : dev_sw_p_(dev_sw_p), dev_sw_e_(dev_sw_e), sw_dt_(dt), time_sw_start_(t_start), time_sw_end_(t_end)
156 {
157 }
158
159 /* Get the Starburst 99 stellar wind momentum flux per solar mass.
160 *
161 * @param t cluster age in kyr
162 * @return flux (in Cholla force units) per solar mass.
163 */
164 inline __device__ Real Get_Wind_Flux(Real t) const
165 {
166 if ((t < time_sw_start_) or (t >= time_sw_end_)) return 0;
167
168 int index = (int)((t - time_sw_start_) / sw_dt_);
169 Real log_p_dynes = (dev_sw_p_[index] + (t - index * sw_dt_) * (dev_sw_p_[index + 1] - dev_sw_p_[index]) / sw_dt_);
170 return pow(10, log_p_dynes) / FORCE_UNIT / S_99_TOTAL_MASS;
171 }
172
173 /* Get the Starburst 99 stellar wind emitted power per solar mass.
174 *
175 * @param t cluster age in kyr
176 * @return power (in Cholla units) per solar mass.
177 */
178 inline __device__ Real Get_Wind_Power(Real t) const
179 {
180 if ((t < time_sw_start_) or (t >= time_sw_end_)) return 0;
181
182 int index = (int)((t - time_sw_start_) / sw_dt_);
183 Real log_e = (dev_sw_e_[index] + (t - index * sw_dt_) * (dev_sw_e_[index + 1] - dev_sw_e_[index]) / sw_dt_);
184 Real e = pow(10, log_e) / (MASS_UNIT * VELOCITY_UNIT * VELOCITY_UNIT) * TIME_UNIT / S_99_TOTAL_MASS;
185 return e;
186 }
187
188 /* Get the mass flux associated with stellar wind momentum flux and stellar wind power scaled per
189 * cluster mass.
190 *
191 * @param flux
192 * @return mass flux in g/s per solar mass
193 */
194 static __device__ Real Get_Wind_Mass(Real flux, Real power)
195 {
196 if ((flux <= 0) or (power <= 0)) return 0;
197 return flux * flux / power / 2;
198 }
199
200 inline __device__ bool is_active(Real age) const { return (time_sw_start_ <= age) and (age <= time_sw_end_); }
201
202 private: // attributes
203 /* device array of log base 10 momentum flux values in dynes. */
204 Real *dev_sw_p_ = nullptr;
205 /* device array of log base 10 power (erg/s) */
206 Real *dev_sw_e_ = nullptr;
207 /* time interval between table data points in kyr. */
208 Real sw_dt_ = 0.0;
209 /* cluster age when flux becomes non-negligible (kyr). */
210 Real time_sw_start_ = 0.0;
211 /* cluster age when stellar winds turn off (kyr). */
212 Real time_sw_end_ = 0.0;
213};
214
215} // namespace feedback
216
217#endif /* FEEDBACK_RATECALC_H */
A class that provides map-like access to parameter files.
Definition ParameterMap.h:74
Definition ratecalc.h:55
Definition ratecalc.h:151