Version: SMASH-3.1
customnucleus.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019-2022
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 #include "smash/customnucleus.h"
8 
9 #include <cmath>
10 #include <fstream>
11 #include <map>
12 #include <string>
13 #include <vector>
14 
15 #include "smash/constants.h"
16 #include "smash/particletype.h"
17 #include "smash/pdgcode.h"
18 
19 namespace smash {
20 static constexpr int LCollider = LogArea::Collider::id;
21 
22 std::unique_ptr<std::ifstream> CustomNucleus::filestream_shared_ = nullptr;
23 
24 CustomNucleus::CustomNucleus(Configuration& config, int testparticles,
25  bool same_file) {
26  // Read in file directory from config
27  const std::string particle_list_file_directory =
28  config.take({"Custom", "File_Directory"});
29  // Read in file name from config
30  const std::string particle_list_file_name =
31  config.take({"Custom", "File_Name"});
32 
33  if (particles_.size() != 0) {
34  throw std::runtime_error(
35  "Your Particle List is already filled before reading in from the "
36  "external file."
37  "Something went wrong. Please check your config.");
38  }
39  /*
40  * Counts number of nucleons in one nucleus as it is specialized
41  * by the user in the config file.
42  * It is needed to read in the proper number of nucleons for one
43  * nucleus and to restart at the listreading for the following
44  * nucleus as one does not want to read configurations twice.
45  */
46  std::map<PdgCode, int> particle_list = config.take({"Particles"});
47  for (const auto& particle : particle_list) {
48  if (particle.first == pdg::p) {
49  number_of_protons_ = particle.second * testparticles;
50  } else if (particle.first == pdg::n) {
51  number_of_neutrons_ = particle.second * testparticles;
52  } else {
53  throw std::runtime_error(
54  "Your nucleus can only contain protons and/or neutrons."
55  "Please check what particles you have specified in the config");
56  }
58  }
59  /*
60  * "if" statement makes sure the streams to the file are initialized
61  * properly.
62  */
63  const std::string path =
64  file_path(particle_list_file_directory, particle_list_file_name);
65  if (same_file && !filestream_shared_) {
66  filestream_shared_ = std::make_unique<std::ifstream>(path);
68  } else if (!same_file) {
69  filestream_ = std::make_unique<std::ifstream>(path);
71  } else {
73  }
74 
77  // Inherited from nucleus class (see nucleus.h)
79 }
80 
81 void CustomNucleus::fill_from_list(const std::vector<Nucleoncustom>& vec) {
82  particles_.clear();
83  index_ = 0;
84  // checking if particle is proton or neutron
85  for (const auto& it : vec) {
86  PdgCode pdgcode;
87  if (it.isospin == 1) {
88  pdgcode = pdg::p;
89  } else if (it.isospin == 0) {
90  pdgcode = pdg::n;
91  } else {
92  throw std::runtime_error(
93  "Your particles charges are not 1 = proton or 0 = neutron.\n"
94  "Check whether your list is correct or there is an error.");
95  }
96  // setting parameters for the particles in the particlelist in smash
97  const ParticleType& current_type = ParticleType::find(pdgcode);
98  double current_mass = current_type.mass();
99  particles_.emplace_back(current_type);
100  particles_.back().set_4momentum(current_mass, 0.0, 0.0, 0.0);
101  }
102 }
103 
105  /*
106  * As only arrange_nucleons is called at the beginning of every
107  * event it is important to have readfile and fill from list
108  * called again when a new event starts. The constructor is only
109  * called twice to initialize the first target and projectile.
110  * Therefore this if statement is implemented.
111  */
112  if (index_ >= custom_nucleus_.size()) {
115  }
116  const auto& pos = custom_nucleus_.at(index_);
117  index_++;
118  ThreeVector nucleon_position(pos.x, pos.y, pos.z);
119  // rotate nucleon about euler angle
120  nucleon_position.rotate(euler_phi_, euler_theta_, euler_psi_);
121 
122  return nucleon_position;
123 }
124 
126  /* Randomly generate Euler angles for rotation everytime a new
127  * custom nucleus is initialized. Therefore this is done 2 times per
128  * event.
129  */
131 
132  for (auto i = begin(); i != end(); i++) {
133  // Initialize momentum
134  i->set_4momentum(i->pole_mass(), 0.0, 0.0, 0.0);
135  /* Sampling the Woods-Saxon, get the radial
136  * position and solid angle for the nucleon. */
138  // Set the position of the nucleon.
139  i->set_4position(FourVector(0.0, pos));
140  }
141  // Recenter
142  align_center();
143 }
144 
147  logg[LCollider].warn() << "Fermi motion activated with a custom nucleus.\n";
148  logg[LCollider].warn() << "Be aware that generating the Fermi momenta\n"
149  << "assumes nucleons distributed according to a\n"
150  << "Woods-Saxon distribution.";
151 }
152 
153 std::string CustomNucleus::file_path(const std::string& file_directory,
154  const std::string& file_name) {
155  if (file_directory.back() == '/') {
156  return file_directory + file_name;
157  } else {
158  return file_directory + '/' + file_name;
159  }
160 }
161 
162 std::vector<Nucleoncustom> CustomNucleus::readfile(
163  std::ifstream& infile) const {
164  int proton_counter = 0;
165  int neutron_counter = 0;
166  std::string line;
167  std::vector<Nucleoncustom> custom_nucleus;
168  // read in only A particles for one nucleus
169  for (int i = 0; i < number_of_nucleons_; ++i) {
170  std::getline(infile, line);
171  // make sure the stream goes back to the beginning when it hits end of file
172  if (infile.eof()) {
173  infile.clear();
174  infile.seekg(0, infile.beg);
175  std::getline(infile, line);
176  }
177  Nucleoncustom nucleon;
178  std::istringstream iss(line);
179  if (!(iss >> nucleon.x >> nucleon.y >> nucleon.z >>
180  nucleon.spinprojection >> nucleon.isospin)) {
181  throw std::runtime_error(
182  "SMASH could not read in a line from your initial nuclei input file."
183  "\nCheck if your file has the following format: x y z "
184  "spinprojection isospin");
185  }
186  if (nucleon.isospin == 1) {
187  proton_counter++;
188  } else if (nucleon.isospin == 0) {
189  neutron_counter++;
190  }
191  custom_nucleus.push_back(nucleon);
192  }
193  if (proton_counter != number_of_protons_ ||
194  neutron_counter != number_of_neutrons_) {
195  throw std::runtime_error(
196  "Number of protons and/or neutrons in the nuclei input file does not "
197  "correspond to the number specified in the config.\nCheck the config "
198  "and your input file.");
199  } else {
200  return custom_nucleus;
201  }
202 }
203 
204 } // namespace smash
Interface to the SMASH configuration files.
Value take(std::initializer_list< const char * > keys)
The default interface for SMASH to read configuration values.
size_t index_
Index needed to read out vector in distribute nucleon.
std::string file_path(const std::string &file_directory, const std::string &file_name)
Generates the name of the stream file.
static std::unique_ptr< std::ifstream > filestream_shared_
Filestream variable used if projectile and target are read in from the same file and they use the sam...
Definition: customnucleus.h:98
int number_of_protons_
Number of protons per nucleus.
ThreeVector distribute_nucleon() override
Returns position of a nucleon as given in the external file.
void arrange_nucleons() override
Sets the positions of the nucleons inside a nucleus.
CustomNucleus(Configuration &config, int testparticles, bool same_file)
Constructor that needs configuration parameters from input file and the number of testparticles.
std::vector< Nucleoncustom > custom_nucleus_
Vector contianing Data for one nucleus given in the particlelist.
int number_of_neutrons_
Number of neutrons per nucleus.
int number_of_nucleons_
Number of nucleons per nucleus Set initally to zero to be modified in the constructor.
std::unique_ptr< std::ifstream > filestream_
Filestream variable used if projectile and target are read in from different files and they therefore...
std::vector< Nucleoncustom > readfile(std::ifstream &infile) const
The returned vector contains Data for one nucleus given in the particlelist.
void generate_fermi_momenta() override
Generates Fermi momenta as it is done in the mother class but in addition prints a warning that the F...
void fill_from_list(const std::vector< Nucleoncustom > &vec)
Fills Particlelist from vector containing data for one nucleus.
std::unique_ptr< std::ifstream > * used_filestream_
Pointer to the used filestream pointer.
The FourVector class holds relevant values in Minkowski spacetime with (+, −, −, −) metric signature.
Definition: fourvector.h:33
double euler_theta_
Euler angel theta.
Definition: nucleus.h:303
void random_euler_angles()
Randomly generate Euler angles.
Definition: nucleus.cc:480
virtual void generate_fermi_momenta()
Generates momenta according to Fermi motion for the nucleons.
Definition: nucleus.cc:348
virtual void set_parameters_automatic()
Sets the deformation parameters of the Woods-Saxon distribution according to the current mass number.
Definition: nucleus.cc:282
double euler_phi_
Euler angel phi.
Definition: nucleus.h:301
std::vector< ParticleData > particles_
Particles associated with this nucleus.
Definition: nucleus.h:288
double euler_psi_
Euler angel psi.
Definition: nucleus.h:305
void align_center()
Shifts the nucleus so that its center is at (0,0,0)
Definition: nucleus.h:223
std::vector< ParticleData >::iterator begin()
For iterators over the particle list:
Definition: nucleus.h:309
std::vector< ParticleData >::iterator end()
For iterators over the particle list:
Definition: nucleus.h:313
Particle type contains the static properties of a particle species.
Definition: particletype.h:98
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
double mass() const
Definition: particletype.h:145
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:111
The ThreeVector class represents a physical three-vector with the components .
Definition: threevector.h:31
void rotate(double phi, double theta, double psi)
Rotate vector by the given Euler angles phi, theta, psi.
Definition: threevector.h:283
Collection of useful constants that are known at compile time.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
constexpr int p
Proton.
constexpr int n
Neutron.
Definition: action.h:24
static constexpr int LCollider
Contains data for one nucleon that is read in from the list.
Definition: customnucleus.h:24
double z
z-coordinate
Definition: customnucleus.h:30
double x
x-coordinate
Definition: customnucleus.h:26
bool isospin
to differentiate between protons isospin=1 and neutrons isospin=0
Definition: customnucleus.h:34
bool spinprojection
spinprojection of the nucleon
Definition: customnucleus.h:32
double y
y-coordinate
Definition: customnucleus.h:28