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
NuclearFormFactor.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/Error.hh"
19#include "marley/FileManager.hh"
20#include "marley/JSON.hh"
21#include "marley/JSONConfig.hh"
22#include "marley/NuclearFormFactor.hh"
23
24std::shared_ptr< marley::NuclearFormFactor > marley::NuclearFormFactor::create(
25 int Z, int A, const marley::JSON& ff_config )
26{
27 static bool need_to_log_nuc_ff_info = true;
28
29 // If the user has requested use of the allowed approximation, then configure
30 // the trivial nuclear form factor model and return without logging this
31 // choice (it will be handled elsewhere)
33 auto tnff = std::make_shared< marley::TrivialNuclearFormFactor >( Z, A );
34 need_to_log_nuc_ff_info = false;
35 return tnff;
36 }
37
38 if ( !ff_config.has_key("nuclear_model") ) {
39 throw marley::Error( "Missing nuclear form factor model configuration" );
40 }
41 const auto& nucl_json = ff_config.at( "nuclear_model" );
42 if ( !nucl_json.is_string() ) {
43 throw marley::Error( "Invalid nuclear form factor model "
44 + nucl_json.dump_string() );
45 }
46 std::string nucl_ff_model = nucl_json.to_string();
47
48 std::shared_ptr< marley::NuclearFormFactor > nuclear_ff;
49
50 // Choose the model to use for the nuclear form factor
51 if ( nucl_ff_model == "trivial" ) {
52 nuclear_ff = std::make_shared< marley::TrivialNuclearFormFactor >( Z, A );
53 if ( need_to_log_nuc_ff_info ) {
54 MARLEY_LOG( INFO, "physics.formfactor" ) << "Using trivial nuclear form factor";
55 }
56 }
57 else if ( nucl_ff_model == "helm" ) {
58 nuclear_ff = std::make_shared< marley::HelmNuclearFormFactor >( Z, A );
59 if ( need_to_log_nuc_ff_info ) {
60 MARLEY_LOG( INFO, "physics.formfactor" ) << "Using Helm nuclear form factor";
61 }
62 }
63 else if ( nucl_ff_model == "klein" ) {
64
65 // Retrieve the optional "nucl_options" JSON object if it is present
66 bool ok; // dummy flag used when parsing the JSON configuration
67 marley::JSON nucl_opt = assign_from_json< marley::JSON >(
68 "nucl_options", ff_config, ok, marley::JSON::object() );
69
70 // Set the "adapted" option from the parameters if it is present
71 bool adapted = assign_from_json< bool >( "adapted", nucl_opt, ok, true );
72
73 nuclear_ff = std::make_shared< marley
74 ::KleinNystrandNuclearFormFactor >( Z, A, adapted );
75
76 if ( need_to_log_nuc_ff_info ) {
77 std::string kn_name;
78 if ( adapted ) kn_name += "adapted ";
79 kn_name += "Klein-Nystrand";
80 MARLEY_LOG( INFO, "physics.formfactor" ) << "Using " << kn_name << " nuclear form factor";
81 }
82 }
83 else throw marley::Error( "Unrecognized nuclear form factor model name \""
84 + nucl_ff_model + "\" in marley::NuclearFormFactor::create()" );
85
86 need_to_log_nuc_ff_info = false;
87 return nuclear_ff;
88}
89
90double marley::HelmNuclearFormFactor::F( double kappa ) const {
91 if ( kappa == 0. ) return 1.;
92 double kappa_in_inverse_fm = kappa / marley_utils::hbar_c;
93 double x = kappa_in_inverse_fm * R_;
94 double j1 = ( std::sin( x ) / x - std::cos( x ) ) / x;
95 double F = 3. * j1 / x * std::exp( -kappa_in_inverse_fm
96 * kappa_in_inverse_fm * s_ * s_ / 2. );
97 return F;
98}
99
100double marley::KleinNystrandNuclearFormFactor::F( double kappa ) const {
101 if ( kappa == 0. ) return 1.;
102 double kappa_in_inverse_fm = kappa / marley_utils::hbar_c;
103 double x = kappa_in_inverse_fm * R_;
104 double j1 = ( std::sin( x ) / x - std::cos( x ) ) / x;
105 double F = 3. * j1 / x * ( 1. / ( 1.
106 + kappa_in_inverse_fm*kappa_in_inverse_fm*a_*a_ ) );
107 return F;
108}
109
110void marley::KleinNystrandNuclearFormFactor::initialize_r0_table() {
111
112 // Instantiate the file manager and use it to find the data file containing
113 // the rms charge radii for many nuclei
114 const auto& fm = marley::FileManager::Instance();
115 std::string full_r0_file_name = fm.find_file( r0_data_file_name_ );
116
117 if ( full_r0_file_name.empty() ) {
118 throw marley::Error( "Could not find the MARLEY nuclear rms charge radii"
119 " data file " + r0_data_file_name_ + ". Please ensure that"
120 " the folder containing it is on the MARLEY search path."
121 " If needed, the folder can be appended to the MARLEY_SEARCH_PATH"
122 " environment variable." );
123 }
124
125 MARLEY_LOG( INFO, "init.structure" ) << "Loading ground-state nuclear rms charge radii from "
126 << full_r0_file_name;
127
128 marley::JSON r0_json_obj = marley::JSON::load_file( full_r0_file_name );
129 if ( !r0_json_obj.has_key("nuclear_charge_radii") ) {
130 throw marley::Error( "Missing \"nuclear_charge_radii\" key in "
131 + full_r0_file_name );
132 }
133 const marley::JSON& r0_json_array = r0_json_obj.at( "nuclear_charge_radii" );
134 if ( !r0_json_array.is_array() ) {
135 throw marley::Error( "Invalid \"nuclear_charge_radii\" array in "
136 + full_r0_file_name );
137 }
138
139 r0_table_ = std::make_unique< std::map< int, double > >();
140
141 bool ok; // Helper flag to use when reading the JSON array elements
142 for ( const auto& r0_js : r0_json_array.array_range() ) {
143 int Z = assign_from_json< int >( "Z", r0_js, ok );
144 int A = assign_from_json< int >( "A", r0_js, ok );
145 double R = assign_from_json< double >( "R", r0_js, ok );
146
147 // TODO: load and use the uncertainty on the rms charge radius
148 //double R_unc = assign_from_json< double >( "R_unc", r0_js, ok );
149
150 // Add the completed entry to the table of nuclear radii
151 int pdg = marley_utils::get_nucleus_pid( Z, A );
152 r0_table_->operator[]( pdg ) = R;
153
154 MARLEY_LOG( TRACE, "init.structure.masstable" ) << "Nucleus with PDG code "
155 << pdg << " has rms charge radius " << R << " fm";
156 }
157
158}
Base class for all exceptions thrown by MARLEY functions.
Definition Error.hh:26
static const FileManager & Instance()
Get a const reference to the singleton instance of the FileManager.
double s_
Nuclear skin thickness parameter (fm)
virtual double F(double kappa) const override final
double R_
Effective nuclear radius (fm)
static bool check_for_allowed_approximation(const marley::JSON &ff_config)
double a_
Range (fm) of the assumed Yukawa potential.
virtual double F(double kappa) const override final
double R_
Effective nuclear radius (fm)
static std::shared_ptr< marley::NuclearFormFactor > create(int Z, int A, const JSON &ff_config)