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
Target.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
18
19#include "marley/Error.hh"
20#include "marley/Logger.hh"
21#include "marley/Target.hh"
22#include "marley/marley_utils.hh"
23
25 this->initialize_single_nuclide( pdg );
26}
27
28marley::Target::Target( int Z, int A ) {
29 // Get the nuclear PDG code corresponding to these Z and A values
30 int pdg = marley_utils::get_nucleus_pid( Z, A );
31
32 // Delegate the rest of the work
33 this->initialize_single_nuclide( pdg );
34}
35
37 // Create trivial vectors of a single nuclide
38 // whose atom fraction is one
39 std::vector<double> atom_fracs = { 1. };
40 std::vector<marley::TargetAtom> atoms;
41 atoms.emplace_back( pdg );
42
43 // Delegate the rest to the initialization method for the general case
44 this->initialize( atoms, atom_fracs );
45}
46
47marley::Target::Target( const std::vector<marley::TargetAtom>& nuclides,
48 const std::vector<double>& atom_fracs )
49{
50 this->initialize( nuclides, atom_fracs );
51}
52
53void marley::Target::initialize( const std::vector<marley::TargetAtom>& nuclides,
54 const std::vector<double>& atom_fracs )
55{
56 // Check that we have the same number of target atoms and atom fractions
57 if ( nuclides.size() != atom_fracs.size() ) {
58 throw marley::Error("Different numbers of target atoms and atom fractions"
59 " encountered in the constructor of marley::Target");
60 }
61
62 // Check that we have at least one target nuclide. Note that the vector's
63 // size is unsigned and therefore can't go negative.
64 if ( nuclides.size() == 0u ) throw marley::Error( "No target atoms"
65 " specified when constructing a marley::Target object" );
66
67 // Make sure the atom fractions sum to unity by explicitly renormalizing them
68 double sum = 0.;
69 for ( size_t j = 0u; j < atom_fracs.size(); ++j ) {
70 double af = atom_fracs.at( j );
71 const auto& nuc = nuclides.at( j );
72 if ( af < 0. ) throw marley::Error("Invalid atom fraction "
73 + std::to_string(af) + " encountered for a "
74 + nuc.to_string() + " target atom");
75 else if ( af == 0. ) MARLEY_LOG( WARN, "init.config.target" )
76 << "Atom fraction of zero encountered for a " << nuc << " target atom";
77 sum += af;
78 }
79
80 // If the sum of the fractions is non-positive, we'll have trouble.
81 if ( sum <= 0. ) throw marley::Error( "Sum of atom fractions = "
82 + std::to_string(sum) + " in the constructor of marley::Target" );
83
84 std::vector<double> renorm_fracs;
85 for ( const auto& af : atom_fracs ) renorm_fracs.push_back( af / sum );
86
87 // We're ready. Initialize the target atom map.
88 for ( size_t j = 0u; j < nuclides.size(); ++j ) {
89 const auto& nuc = nuclides.at( j );
90 const auto& frac = renorm_fracs.at( j );
91 // If we have duplicate nuclides, throw an error (likely to be a mistake)
92 if ( atom_fractions_.count(nuc) ) throw marley::Error("Duplicate atom"
93 " fractions specified for the target atom " + nuc.to_string() + " in"
94 " the constructor of marley::Target");
95 atom_fractions_[ nuc ] = frac;
96 }
97}
98
100 // If we have an atom fraction stored in the map for this nuclide,
101 // then just return it
102 auto it = atom_fractions_.find( atom );
103 if ( it != atom_fractions_.end() ) return it->second;
104 // If we couldn't find it, then just return zero
105 return 0.;
106}
107
109 return ( this->atom_fraction(atom) != 0. );
110}
111
112void marley::Target::print( std::ostream& out ) const {
113 size_t num_atom_types = atom_fractions_.size();
114 size_t count = 1;
115 for ( const auto& pair : atom_fractions_ ) {
116 const auto& nuc = pair.first;
117 const auto& frac = pair.second;
118 std::string A_str = std::to_string( nuc.A() );
119 marley_utils::pad_left_inplace( A_str, 3 );
120
121 auto it = marley_utils::element_symbols.find( nuc.Z() );
122 std::string symb = "??";
123 if ( it != marley_utils::element_symbols.end() ) symb = it->second;
124 marley_utils::pad_right_inplace( symb, 2 );
125
126 out << A_str << symb << " = " << frac;
127 // Add a newline to all but the last entry
128 if ( count < num_atom_types ) out << '\n';
129 ++count;
130 }
131}
Base class for all exceptions thrown by MARLEY functions.
Definition Error.hh:26
An atomic target for a lepton scattering reaction.
Definition TargetAtom.hh:26
std::map< marley::TargetAtom, double > atom_fractions_
Map storing the atom fraction for each nuclide in the target material.
Definition Target.hh:91
Target(int pdg)
Create a Target composed of a single nuclide.
Definition Target.cc:24
void initialize_single_nuclide(int pdg)
Helper function for the constructors that use a single nuclide.
Definition Target.cc:36
bool contains(const marley::TargetAtom &atom) const
Return true if the target contains the requested atom, or false otherwise.
Definition Target.cc:108
void initialize(const std::vector< TargetAtom > &nuclides, const std::vector< double > &atom_fracs)
General helper function for the constructors.
Definition Target.cc:53
void print(std::ostream &out) const
Print a textual representation of the Target to a std::ostream.
Definition Target.cc:112
double atom_fraction(const marley::TargetAtom &atom) const
Returns the atom fraction for the requested nuclide.
Definition Target.cc:99