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.hh
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#pragma once
18
19// Standard library includes
20#include <cmath>
21#include <limits>
22
23// MARLEY includes
24#include "marley/Logger.hh"
25#include "marley/marley_utils.hh"
26
27namespace marley {
28
29 // Forward-declare the JSON class
30 class JSON;
31
34 public:
35
38 NuclearFormFactor( int Z, int A ) : Z_( Z ), A_( A ) {}
39
40 virtual ~NuclearFormFactor() = default;
41
44 virtual double F( double kappa ) const = 0;
45
46 inline int Z() const { return Z_; }
47 inline int A() const { return A_; }
48
54 static std::shared_ptr< marley::NuclearFormFactor > create( int Z, int A,
55 const JSON& ff_config );
56
57 protected:
58
60 int Z_;
61
63 int A_;
64 };
65
66 // Implements a nuclear form factor that is trivially unity
67 class TrivialNuclearFormFactor : public NuclearFormFactor {
68 public:
69
70 inline TrivialNuclearFormFactor( int Z, int A )
71 : NuclearFormFactor( Z, A ) {}
72
73 virtual ~TrivialNuclearFormFactor() = default;
74
75 inline virtual double F( double /*kappa*/ ) const override final
76 { return 1.; }
77 };
78
82 class HelmNuclearFormFactor : public NuclearFormFactor {
83 public:
84
85 inline HelmNuclearFormFactor( int Z, int A ) : NuclearFormFactor( Z, A )
86 {
87 c_ = 1.23*std::pow( A, marley_utils::ONE_THIRD ) - 0.6; // fm
88 this->update_effective_radius();
89 }
90
91 virtual ~HelmNuclearFormFactor() = default;
92
93 virtual double F( double kappa ) const override final;
94
95 inline double s() const { return s_; }
96 inline void set_s( double s ) {
97 s_ = s;
98 this->update_effective_radius();
99 }
100
101 inline double a() const { return a_; }
102
103 inline void set_a( double a ) {
104 a_ = a;
105 this->update_effective_radius();
106 }
107
108 inline double c() const { return c_; }
109 inline void set_c( double c ) {
110 c_ = c;
111 this->update_effective_radius();
112 }
113
114 inline void update_effective_radius() {
115 R_ = marley_utils::real_sqrt( c_*c_ + 7.*marley_utils::pi
116 *marley_utils::pi*a_*a_/3. - 5.*s_*s_ );
117 }
118
119 protected:
120
121 // Parameters in the fit to muon spectroscopy data
123 double s_ = 0.9; // fm
124 double a_ = 0.52; // fm
125 double c_; // fm
126
128 double R_;
129 };
130
134 class KleinNystrandNuclearFormFactor : public NuclearFormFactor {
135 public:
136
137 inline KleinNystrandNuclearFormFactor( int Z, int A,
138 bool adapted = false, double r0 = DUMMY_r0_VALUE )
139 : NuclearFormFactor( Z, A ), adapted_( adapted ), r0_( r0 )
140 {
141 // COHERENT-style "adapted" treatment uses the rms charge radius r0 to
142 // calculate the effective nuclear radius. If the user did not supply
143 // one, then look it up from the table of measurements.
144 if ( adapted_ ) {
145 if ( r0_ == DUMMY_r0_VALUE ) {
146 // Ensure that the table has been loaded
147 if ( !r0_table_ ) this->initialize_r0_table();
148
149 int pdg = marley_utils::get_nucleus_pid( Z, A );
150 auto iter = r0_table_->find( pdg );
151 if ( iter != r0_table_->end() ) {
152 r0_ = iter->second;
153 }
154 else {
155 throw marley::Error( "Unable to find tabulated rms charge"
156 " radius for nucleus with PDG code " + std::to_string( pdg )
157 + ". Please specify a value in fm using the \"r0\" JSON key." );
158 }
159 }
160
161 R_ = marley_utils::real_sqrt( 5.*r0_*r0_/3. - 10.*a_*a_ );
162 return;
163 }
164
165 // Default treatment assigns the effective nuclear radius based solely
166 // on the nucleon number
167 R_ = 1.23 * std::pow( A_, marley_utils::ONE_THIRD ); // fm
168 }
169
170 virtual ~KleinNystrandNuclearFormFactor() = default;
171
172 virtual double F( double kappa ) const override final;
173
176 inline double r0() const {
177 if ( !adapted_ ) MARLEY_LOG( WARN, "physics.formfactor" )
178 << "Requested rms charge radius"
179 << " when using default Klein-Nystrand nuclear form factor";
180 return r0_;
181 }
182
185 static constexpr double DUMMY_r0_VALUE
186 = std::numeric_limits< double >::lowest();
187
188 protected:
189
190 static void initialize_r0_table();
191
194 inline static std::unique_ptr< std::map< int, double > > r0_table_;
195
198 inline static const std::string r0_data_file_name_
199 = "nuclear_charge_radii.js";
200
202 double a_ = 0.7;
203
205 double R_;
206
209 bool adapted_ = false;
210
213 };
214
215}
Base class for all exceptions thrown by MARLEY functions.
Definition Error.hh:26
double s_
Nuclear skin thickness parameter (fm)
virtual double F(double kappa) const override final
double R_
Effective nuclear radius (fm)
double a_
Range (fm) of the assumed Yukawa potential.
virtual double F(double kappa) const override final
double r0_
Value of the rms charge radius, used only for the adapted version.
double R_
Effective nuclear radius (fm)
static std::unique_ptr< std::map< int, double > > r0_table_
Stores measured rms charge radii for many nucleii.
static const std::string r0_data_file_name_
Name of the data file containing the measured rms charge radii.
Base class for nuclear form factor models.
virtual double F(double kappa) const =0
static std::shared_ptr< marley::NuclearFormFactor > create(int Z, int A, const JSON &ff_config)
virtual double F(double) const override final