MARLEY (Model of Argon Reaction Low Energy Yields) v2.0.0
A Monte Carlo event generator for tens-of-MeV neutrino interactions
Loading...
Searching...
No Matches
ExitChannel.cc
1
4//
5// This file is part of MARLEY (Model of Argon Reaction Low Energy Yields)
6//
7// MARLEY is free software: you can redistribute it and/or modify it under the
8// terms of version 3 of the GNU General Public License as published by the
9// Free Software Foundation.
10//
11// For the full text of the license please see COPYING or
12// visit http://opensource.org/licenses/GPL-3.0
13//
14// Please respect the MCnet academic usage guidelines. See GUIDELINES
15// or visit https://www.montecarlonet.org/GUIDELINES for details.
16
17// MARLEY includes
18#include "marley/hepmc3_utils.hh"
19#include "marley/marley_utils.hh"
20#include "marley/ExitChannel.hh"
21#include "marley/GammaStrengthFunctionModel.hh"
22#include "marley/LevelDensityModel.hh"
23#include "marley/Logger.hh"
24#include "marley/OpticalModel.hh"
25#include "marley/marley_kinematics.hh"
26
27namespace {
28
29 // Helper function that issues a warning when the final nuclear excitation
30 // energy exceeds the energetically accessible maximum value
31 void issue_Exf_warning( double Exf, double Exf_max ) {
32 MARLEY_LOG( WARN, "physics.deexcitation" )
33 << "Final nuclear excitation energy Exf = "
34 << Exf << " MeV exceeds the maximum accessible value of " << Exf_max
35 << " MeV. The decay width for this exit channel will be set to zero.";
36 }
37
38 // Helper function that issues a warning when the final nuclear excitation
39 // energy lies outside the accessible continuum
40 void issue_Exf_continuum_warning( double Exf, double E_c_min,
41 double E_c_max )
42 {
43 MARLEY_LOG( WARN, "physics.deexcitation" )
44 << "Final nuclear excitation energy Exf = "
45 << Exf << " MeV lies outside the accessible continuum [ " << E_c_min
46 << " MeV, " << E_c_max << " MeV ]. The differential decay width"
47 << " will be set to zero.";
48 }
49
50 // Helper function that throws an error in response to invalid excitation
51 // energy continuum bounds
52 void throw_continuum_bounds_error( double E_c_min, double E_c_max ) {
53 throw marley::Error( "Invalid continuum excitation energy bounds "
54 " E_c_min = " + std::to_string(E_c_min) + " MeV and E_c_max = "
55 + std::to_string(E_c_max) + " MeV encountered" );
56 }
57
58 // Used to avoid round-off problems in comparisons of floating-point numbers
59 constexpr double TINY_OFFSET = 1e-6;
60}
61
63
65 int Zi = marley_utils::get_particle_Z( pdgi_ );
66 int Ai = marley_utils::get_particle_A( pdgi_ );
67
68 int Zfrag = marley_utils::get_particle_Z( fragment_pdg_ );
69 int Afrag = marley_utils::get_particle_A( fragment_pdg_ );
70
71 int Zf = Zi - Zfrag;
72 int Af = Ai - Afrag;
73
74 int pdgf = marley_utils::get_nucleus_pid( Zf, Af );
75 return pdgf;
76}
77
79 const auto& mt = marley::MassTable::Instance();
80 double Sa = mt.get_fragment_separation_energy( pdgi_, fragment_pdg_ );
81 double Exf_max = Exi_ - Sa;
82 return Exf_max;
83}
84
86
87 int remnant_pdg = this->final_nucleus_pdg();
88 marley::OpticalModel& om = sdb_->get_optical_model( remnant_pdg );
89
90 // Get information about the emitted fragment
91 const marley::Fragment& f = *sdb_->get_fragment( fragment_pdg_ );
92
93 int two_s = f.get_two_s(); // two times the fragment spin
94 marley::Parity Pa = f.get_parity(); // intrinsic parity
95
96 // Maximum possible excitation energy in the daughter nucleus after the
97 // fragment is emitted
98 double Exf_max = this->max_Exf();
99
100 // Excitation energy of the final nuclear level
101 double Exf = final_level_.energy();
102
103 // Initialize the total decay width to zero, just in case
104 width_ = 0.;
105
106 if ( Exf >= Exf_max ) {
107 issue_Exf_warning( Exf, Exf_max );
108 return;
109 }
110
111 // Total kinetic energy in the CM frame immediately after the binary decay
112 double total_KE_CM_frame = Exf_max - Exf;
113
114 int twoJf = final_level_.twoJ();
115 marley::Parity Pf = final_level_.parity();
116
117 for (int two_j = std::abs(twoJi_ - twoJf); two_j <= twoJi_ + twoJf;
118 two_j += 2)
119 {
120 int j_plus_s = (two_j + two_s) / 2;
121
122 // For each new iteration, increment l and flip the overall final
123 // state parity
124 int l = std::abs(two_j - two_s) / 2;
125 bool l_is_odd = l % 2;
126 marley::Parity P_final_state = Pf * Pa * marley::Parity( !l_is_odd );
127 for ( ; l <= j_plus_s; ++l, !P_final_state )
128 {
129 // The current term in the sum only contributes to the total decay
130 // width if parity is conserved
131 if ( Pi_ == P_final_state ) {
132
133 double Tlj = om.transmission_coefficient( total_KE_CM_frame,
134 fragment_pdg_, two_j, l, two_s );
135
136 double partial_width = one_over_two_pi_rho_i_ * Tlj;
137
138 width_ += partial_width;
139
140 // TODO: cache term indexed by l, two_j
141 }
142 }
143 }
144
145 // Guard against numerical issues by capping the total width at zero
146 width_ = std::max( 0., width_ );
147}
148
149double marley::GammaExitChannel::gamma_energy( double Exf ) const {
150 // Approximate the gamma energy by the excitation energy difference between
151 // the initial and final nuclear states
152 // TODO: consider adding a nuclear recoil correction here
153 double E_gamma = Exi_ - Exf;
154 return E_gamma;
155}
156
157
158TrType marley::GammaExitChannel::get_transition_type( int mpol,
159 marley::Parity Pf ) const
160{
161 // Electric transitions satisfy the parity relation Pi = (-1)^{\ell} * Pf,
162 // where Pi (Pf) are the initial (final) nuclear parities and \ell is the
163 // multipolarity of the transition. Magnetic transitions satisfy
164 // Pi = (-1)^{\ell + 1} * Pf. We choose the appropriate transition type
165 // here based on these rules.
166 bool mpol_is_odd = mpol % 2;
167 marley::Parity P_final_state = Pf * marley::Parity( !mpol_is_odd );
168 TrType type = ( Pi_ == P_final_state ) ? TrType::electric : TrType::magnetic;
169 return type;
170}
171
173
174 // Retrieve the gamma strength function model used to compute transmission
175 // coefficients
177 = sdb_->get_gamma_strength_function_model( pdgi_ );
178
179 // Get properties of the final nuclear level
180 double Exf = final_level_.energy();
181 int twoJf = final_level_.twoJ();
182 marley::Parity Pf = final_level_.parity();
183
184 // Initialize the total width to zero, just in case.
185 width_ = 0.;
186
187 if ( Exf >= Exi_ ) {
188 issue_Exf_warning( Exf, Exi_ );
189 return;
190 }
191
192 // Compute the energy of the emitted gamma-ray
193 double E_gamma = this->gamma_energy( Exf );
194
195 // Initialize the multipolarity for the start of the loop.
196 // There is no monopole radiation, so the minimum allowed value is one.
197 int start_mpol = std::max( 1, std::abs(twoJi_ - twoJf) / 2 );
198 int end_mpol = ( twoJi_ + twoJf ) / 2;
199
200 // Sum contributions to the decay width from different multipolarities
201 for ( int mpol = start_mpol; mpol <= end_mpol; ++mpol ) {
202
203 // Use the multipolarity and final-state nuclear parity to determine
204 // whether the current partial width represents an electric or magnetic
205 // transition
206 TrType type = this->get_transition_type( mpol, Pf );
207
208 double TXl = gsfm.transmission_coefficient( type, mpol, E_gamma );
209
210 double term = one_over_two_pi_rho_i_ * TXl;
211
212 // TODO: add caching of terms by Xl pair
213
214 width_ += term;
215 }
216
217 // Guard against numerical issues by capping the total width at zero
218 width_ = std::max( 0., width_ );
219}
220
221double marley::FragmentContinuumExitChannel::differential_width( double Exf,
222 bool store_jpi_widths ) const
223{
224 if ( store_jpi_widths ) this->clear_jpi_widths();
225
226 int remnant_pdg = this->final_nucleus_pdg();
227 marley::OpticalModel& om = sdb_->get_optical_model( remnant_pdg );
228 marley::LevelDensityModel& ldm = sdb_->get_level_density_model( remnant_pdg );
229
230 // Get the maximum accessible final excitation energy
231 double Exf_max = this->max_Exf();
232
233 // Initialize the return value to zero
234 double diff_width = 0.;
235
236 if ( Exf_max < E_c_min_ ) throw_continuum_bounds_error( E_c_min_, Exf_max );
237
238 // Check that Exf lies within the continuum
239 if ( Exf < (E_c_min_ - TINY_OFFSET) || Exf > (Exf_max + TINY_OFFSET) ) {
240 // If it doesn't, complain and return zero
241 issue_Exf_continuum_warning( Exf, E_c_min_, Exf_max );
242 return 0.;
243 }
244
245 double total_KE_CM_frame = Exf_max - Exf;
246
247 // Get information about the emitted fragment
248 const marley::Fragment& f = *sdb_->get_fragment( fragment_pdg_ );
249
250 int two_s = f.get_two_s(); // two times the fragment spin
251 marley::Parity Pa = f.get_parity(); // intrinsic parity
252
253
254
255 // Final nuclear parity
257 // The orbital parity starts as (-1)^0 = 1. Rather than applying parity
258 // conservation each time, just find the final state parity Pf for l = 0.
259 // Then we can safely flip Pf without further thought for each new l value in
260 // the loop.
261 if (Pi_ == Pa) Pf = 1;
262 else Pf = -1;
263 // For each new iteration, increment l and flip the final-state parity
264 for (int l = 0; l <= l_max_; ++l, !Pf) {
265 int two_l = 2*l;
266 for (int two_j = std::abs(two_l - two_s);
267 two_j <= two_l + two_s; two_j += 2)
268 {
269
270 for (int twoJf = std::abs(twoJi_ - two_j);
271 twoJf <= twoJi_ + two_j; twoJf += 2)
272 {
273
274 double Tlj = om.transmission_coefficient( total_KE_CM_frame,
275 fragment_pdg_, two_j, l, two_s );
276
277 double rho_f = ldm.level_density( Exf, twoJf, Pf );
278
279 double term = one_over_two_pi_rho_i_ * Tlj * rho_f;
280
281 diff_width += term;
282
283 if ( store_jpi_widths ) {
284
285 auto f_spw = std::make_unique< FragmentSpinParityWidth >(
286 twoJf, Pf, term, two_j, l );
287
288 jpi_widths_table_.push_back( std::move(f_spw) );
289 // TODO: include (l, two_j) in cached term
290 }
291 }
292 }
293 }
294 return diff_width;
295}
296
298
299 // Initialize the total width to zero
300 width_ = 0.;
301
302 double Ec_max = this->E_c_max();
303
304 if ( Ec_max < E_c_min_ ) {
305 throw_continuum_bounds_error( E_c_min_, Ec_max );
306 return;
307 }
308
309 // Create a function object to use for integration of the differential decay
310 // width
311 std::function<double(double)> dw = [this](double Exf) -> double {
312 return this->differential_width( Exf );
313 };
314
315 // Numerically integrate over the bounds of the continuum using the
316 // function object prepared above
317 width_ = marley_utils::num_integrate( dw, E_c_min_, Ec_max );
318
319 // Guard against numerical issues by capping the total width at zero
320 width_ = std::max( 0., width_ );
321
322 // TODO: consider switching to doing the integration with a
323 // ChebyshevInterpolatingFunction object. This avoids needing to create one
324 // later (and may be comparable in terms of computational cost)
325}
326
327double marley::GammaContinuumExitChannel::differential_width( double Exf,
328 bool store_jpi_widths ) const
329{
330 if ( store_jpi_widths ) this->clear_jpi_widths();
331
332 auto& ldm = sdb_->get_level_density_model( pdgi_ );
333 auto& gsfm = sdb_->get_gamma_strength_function_model( pdgi_ );
334
335 // Initialize the return value to zero
336 double diff_width = 0.;
337
338 // Check that the continuum bounds make sense
339 if ( Exi_ < E_c_min_ ) throw_continuum_bounds_error( E_c_min_, Exi_ );
340
341 // Check that Exf lies within the continuum
342 if ( Exf < (E_c_min_ - TINY_OFFSET) || Exf > (Exi_ + TINY_OFFSET) ) {
343 // If it doesn't, complain and return zero
344 issue_Exf_continuum_warning( Exf, E_c_min_, Exi_ );
345 return 0.;
346 }
347
348 // Compute the energy of the emitted gamma-ray
349 double E_gamma = this->gamma_energy( Exf );
350
351 // Array containing both possible parity values. It is used in
352 // the loop below.
353 constexpr std::array<marley::Parity, 2>
354 parities = { marley::Parity(true), marley::Parity(false) };
355
356 // Sum over multipolarities. There is no monopole radiation, so
357 // the sum begins at mpol = 1.
358 for ( int mpol = 1; mpol <= l_max_; ++mpol ) {
359
360 int two_mpol = 2 * mpol;
361
362 for ( int twoJf = std::abs(twoJi_ - two_mpol); twoJf <= twoJi_ + two_mpol;
363 twoJf += 2 )
364 {
365 for ( const auto& Pf : parities ) {
366
367 // Use the multipolarity and final-state nuclear parity to determine
368 // whether the current partial differential width represents an
369 // electric or magnetic transition
370 TrType type = this->get_transition_type( mpol, Pf );
371
372 double Txl = gsfm.transmission_coefficient( type, mpol, E_gamma );
373 double rho_f = ldm.level_density(Exf, twoJf, Pf);
374
375 double term = one_over_two_pi_rho_i_ * Txl * rho_f;
376
377 if ( store_jpi_widths ) {
378
379 auto g_spw = std::make_unique< GammaSpinParityWidth >(
380 twoJf, Pf, term, mpol );
381
382 jpi_widths_table_.push_back( std::move(g_spw) );
383 }
384
385 diff_width += term;
386 }
387 }
388 }
389 return diff_width;
390}
391
392void marley::DiscreteExitChannel::do_decay(double& Exf, int& two_Jf,
393 marley::Parity& Pf, const std::shared_ptr< HepMC3::GenParticle >&
394 compound_nucleus, std::shared_ptr< HepMC3::GenParticle >& emitted_particle,
395 std::shared_ptr< HepMC3::GenParticle >& residual_nucleus,
396 int& qIon, marley::Generator& gen ) const
397{
398 Exf = final_level_.energy();
399 two_Jf = final_level_.twoJ();
400 Pf = final_level_.parity();
401 this->prepare_products( compound_nucleus, emitted_particle,
402 residual_nucleus, Exf, qIon, gen );
403}
404
406 const std::shared_ptr< HepMC3::GenParticle >& compound_nucleus,
407 std::shared_ptr< HepMC3::GenParticle >& emitted_particle,
408 std::shared_ptr< HepMC3::GenParticle >& residual_nucleus,
409 double Exf, int& qf, marley::Generator& gen ) const
410{
411 const auto& mt = marley::MassTable::Instance();
412 int ep_pdg = this->emitted_particle_pdg();
413 double ep_mass = mt.get_particle_mass( ep_pdg );
414
415 emitted_particle = marley_hepmc3::make_particle( ep_pdg,
416 marley_hepmc3::NUHEPMC_FINAL_STATE_STATUS, ep_mass );
417
418 // Proton number of the emitted particle
419 int ep_Z = marley_utils::get_particle_Z( ep_pdg );
420
421 // Final ion charge after particle emission
422 qf = qi_ - ep_Z;
423
424 double me = mt.get_particle_mass( marley_utils::ELECTRON );
425 int remnant_pdg = this->final_nucleus_pdg();
426
427 // Approximate the ground state mass of the ion formed when the fragment is
428 // emitted by subtracting qf electron masses from the atomic mass for the
429 // final nuclide.
430 double Mfgs_ion = mt.get_atomic_mass( remnant_pdg ) - qf*me;
431
432 residual_nucleus = marley_hepmc3::make_particle( remnant_pdg,
433 marley_hepmc3::NUHEPMC_INTERMEDIATE_RESIDUE_STATUS, Mfgs_ion + Exf );
434
435 // Now that the PDG codes, masses, and net charges of the binary decay
436 // products have been set, choose a direction for the emitted particle.
437 // TODO: Consider changing this to a more realistic model instead of
438 // isotropic emissions.
439 double cos_theta_emitted_particle
440 = gen.uniform_random_double( -1., 1., true );
441 double phi_emitted_particle
442 = gen.uniform_random_double( 0., marley_utils::two_pi, false );
443
444 // Handle the kinematics calculations for this decay. Load the
445 // final-state particle objects with their full 4-momenta.
446 marley_kinematics::two_body_decay( compound_nucleus, emitted_particle,
447 residual_nucleus, cos_theta_emitted_particle, phi_emitted_particle );
448}
449
450double marley::ContinuumExitChannel::sample_Exf( marley::Generator& gen ) const
451{
452 // The maximum accessible excitation energy for this exit channel. It
453 // will be used when creating the ChebyshevInterpolatingFunction below
454 double Emax = this->E_c_max();
455
456 // If we haven't built a CDF for sampling the final nuclear excitation
457 // energy yet, then build it before continuing
458 if ( !Exf_cdf_ ) {
459 // Build a polynomial approximant (at Chebyshev points) to the PDF for the
460 // final nuclear excitation energy
461 marley::ChebyshevInterpolatingFunction pdf_cheb( [this](double Exf)
462 -> double { return this->differential_width(Exf); }, E_c_min_, Emax,
463 marley::DEFAULT_N_CHEBYSHEV );
464
465 // Store the cumulative density function for possible re-use
466 Exf_cdf_ = std::make_unique<marley::ChebyshevInterpolatingFunction>(
467 pdf_cheb.cdf() );
468 }
469
470 // Sample a final nuclear excitation energy using the Chebyshev polynomial
471 // approximant to the CDF
472 double Exf = gen.inverse_transform_sample( *Exf_cdf_, E_c_min_, Emax );
473 return Exf;
474}
475
476void marley::ContinuumExitChannel::do_decay( double& Exf, int& two_Jf,
477 marley::Parity& Pf, const std::shared_ptr< HepMC3::GenParticle >&
478 compound_nucleus, std::shared_ptr< HepMC3::GenParticle >& emitted_particle,
479 std::shared_ptr< HepMC3::GenParticle >& residual_nucleus,
480 int& qIon, marley::Generator& gen ) const
481{
482 Exf = this->sample_Exf( gen );
483
484 // Sample a final nuclear spin-parity, unless the user has
485 // explicitly turned this off (presumably in unit tests
486 // where we only care about the final excitation energy).
487 if ( !skip_jpi_sampling_ ) sample_spin_parity( Exf, two_Jf, Pf, gen );
488
489 // TODO: sample a sub-Jpi variable set (e.g., l + j)
490
491 this->prepare_products( compound_nucleus, emitted_particle,
492 residual_nucleus, Exf, qIon, gen );
493}
494
495void marley::ContinuumExitChannel::sample_spin_parity( double Exf, int& twoJ,
496 marley::Parity& Pi, marley::Generator& gen ) const
497{
498 // Clear any previous table entries of spin-parities and decay widths
499 this->clear_jpi_widths();
500
501 // Load table of partial differential widths via a call to
502 // differential_width()
503 double diff_width = this->differential_width( Exf, true );
504
505 // Throw an error if all decays are impossible
506 if ( diff_width <= 0. ) throw marley::Error( "Cannot "
507 "continue Hauser-Feshbach decay. All partial differential decay widths "
508 "are zero." );
509
510 // Sample a final spin and parity
511 const auto begin = marley::IteratorToPointerMember<
512 std::vector< std::unique_ptr<SpinParityWidth> >::const_iterator,
513 const double>( jpi_widths_table_.cbegin(),
514 &SpinParityWidth::diff_width );
515
516 const auto end = marley::IteratorToPointerMember<
517 std::vector< std::unique_ptr<SpinParityWidth> >::const_iterator,
518 const double>( jpi_widths_table_.cend(),
519 &SpinParityWidth::diff_width );
520
521 std::discrete_distribution<size_t> jpi_dist( begin, end );
522 size_t jpi_index = gen.sample_from_distribution( jpi_dist );
523
524 // Store the results
525 last_sampled_spw_ = jpi_widths_table_.at( jpi_index ).get();
526 twoJ = last_sampled_spw_->twoJf;
527 Pi = last_sampled_spw_->Pf;
528}
529
Approximates a 1D function using Chebyshev points.
std::vector< std::unique_ptr< SpinParityWidth > > jpi_widths_table_
Table of possible final-state spin-parities together with their partial differential decay widths.
virtual void compute_total_width() final override
bool skip_jpi_sampling_
Flag that allows skipping the sampling of a final nuclear spin-parity (useful only for testing purpos...
virtual void do_decay(double &Ex, int &two_J, marley::Parity &Pi, const std::shared_ptr< HepMC3::GenParticle > &compound_nucleus, std::shared_ptr< HepMC3::GenParticle > &emitted_particle, std::shared_ptr< HepMC3::GenParticle > &residual_nucleus, int &qIon, marley::Generator &gen) const final override
Simulates a nuclear decay into this channel.
SpinParityWidth * last_sampled_spw_
Points to the last SpinParityWidth object sampled in a previous call to sample_spin_parity()
void clear_jpi_widths() const
Helper function that resets the table of SpinParityWidth objects.
double E_c_min_
Minimum accessible nuclear excitation energy (MeV) in the continuum.
const marley::Level & final_level_
Reference to the final-state nuclear level.
virtual void do_decay(double &Ex, int &two_J, marley::Parity &Pi, const std::shared_ptr< HepMC3::GenParticle > &compound_nucleus, std::shared_ptr< HepMC3::GenParticle > &emitted_particle, std::shared_ptr< HepMC3::GenParticle > &residual_nucleus, int &qIon, marley::Generator &gen) const final override
Simulates a nuclear decay into this channel.
Base class for all exceptions thrown by MARLEY functions.
Definition Error.hh:26
int twoJi_
Two times the initial nuclear spin .
int pdgi_
PDG code for the initial nucleus.
double width_
Total decay width into this channel (MeV)
marley::StructureDatabase * sdb_
StructureDatabase to use in calculations.
marley::Parity Pi_
Initial nuclear parity .
virtual void prepare_products(const std::shared_ptr< HepMC3::GenParticle > &compound_nucleus, std::shared_ptr< HepMC3::GenParticle > &emitted_particle, std::shared_ptr< HepMC3::GenParticle > &residual_nucleus, double Exf, int &qf, marley::Generator &gen) const
Helper function that prepares Particle objects representing the products of the two-body decay.
virtual int emitted_particle_pdg() const =0
Returns the PDG code for the particle (gamma-ray or nuclear fragment) emitted by decays into this Exi...
double Exi_
Initial nuclear excitation energy (MeV)
virtual int final_nucleus_pdg() const =0
Returns the PDG code for the final nucleus.
virtual void compute_total_width() final override
int fragment_pdg_
PDG code identifying the emitted fragment.
virtual int final_nucleus_pdg() const final override
Returns the PDG code for the final nucleus.
double max_Exf() const
Helper function that returns that maximum possible excitation energy for the daughter nucleus after e...
Simple container for storing reference data about each of the nuclear fragments considered by MARLEY'...
Definition Fragment.hh:27
int get_two_s() const
Get two times the spin of this fragment.
Definition Fragment.hh:76
marley::Parity get_parity() const
Get the parity of this fragment.
Definition Fragment.hh:79
virtual void compute_total_width() final override
Abstract base class for models of gamma-ray strength functions.
virtual double transmission_coefficient(TransitionType type, int l, double e_gamma)=0
Returns the gamma-ray transmission coefficient (dimensionless) for the requested gamma energy and mul...
TransitionType
Electromagnetic transitions in nuclei may be classified by their multipolarity (electric vs....
The MARLEY Event generator.
Definition Generator.hh:54
double uniform_random_double(double min, double max, bool inclusive)
Sample a random number uniformly on either [min, max) or [min, max].
Definition Generator.cc:235
double inverse_transform_sample(const marley::InterpolatingFunction &cdf, double xmin, double xmax, double bisection_tolerance=1e-12)
Sample from a given 1D cumulative density function cdf(x) on the interval [xmin, xmax] using bisectio...
Definition Generator.cc:552
auto sample_from_distribution(RandomNumberDistribution &rnd) -> decltype(std::declval< RandomNumberDistribution & >().operator()(std::declval< std::mt19937_64 & >()))
Sample from an arbitrary probability distribution (defined here as any object that implements an oper...
Definition Generator.hh:193
Template class that creates an iterator to a class member based on an iterator to a pointer (either b...
Abstract base class for models of nuclear level densities.
virtual double level_density(double Ex)=0
static const MassTable & Instance()
Get a const reference to the singleton instance of the MassTable.
Definition MassTable.cc:69
Abstract base class for nuclear optical model implementations.
virtual double transmission_coefficient(double total_KE_CM, int fragment_pdg, int two_j, int l, int two_s, int target_charge=0)=0
Calculate the transmission coefficient for a nuclear fragment.
Type-safe representation of a parity value (either +1 or -1)
Definition Parity.hh:25