Version: SMASH-2.2
customnucleus.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2021
3  * SMASH Team
4  *
5  * GNU General Public License (GPLv3 or later)
6  */
7 #include <cmath>
8 #include <fstream>
9 #include <map>
10 #include <string>
11 #include <vector>
12 
13 #include "smash/constants.h"
14 #include "smash/customnucleus.h"
15 #include "smash/particletype.h"
16 #include "smash/pdgcode.h"
17 
18 namespace smash {
19 static constexpr int LCollider = LogArea::Collider::id;
20 
96 std::unique_ptr<std::ifstream> CustomNucleus::filestream_shared_ = nullptr;
97 
98 CustomNucleus::CustomNucleus(Configuration& config, int testparticles,
99  bool same_file) {
100  // Read in file directory from config
101  const std::string particle_list_file_directory =
102  config.take({"Custom", "File_Directory"});
103  // Read in file name from config
104  const std::string particle_list_file_name =
105  config.take({"Custom", "File_Name"});
106 
107  if (particles_.size() != 0) {
108  throw std::runtime_error(
109  "Your Particle List is already filled before reading in from the "
110  "external file."
111  "Something went wrong. Please check your config.");
112  }
113  /*
114  * Counts number of nucleons in one nucleus as it is specialized
115  * by the user in the config file.
116  * It is needed to read in the proper number of nucleons for one
117  * nucleus and to restart at the listreading for the following
118  * nucleus as one does not want to read configurations twice.
119  */
120  std::map<PdgCode, int> particle_list = config.take({"Particles"});
121  for (const auto& particle : particle_list) {
122  if (particle.first == pdg::p) {
123  number_of_protons_ = particle.second * testparticles;
124  } else if (particle.first == pdg::n) {
125  number_of_neutrons_ = particle.second * testparticles;
126  } else {
127  throw std::runtime_error(
128  "Your nucleus can only contain protons and/or neutrons."
129  "Please check what particles you have specified in the config");
130  }
132  }
133  /*
134  * "if" statement makes sure the streams to the file are initialized
135  * properly.
136  */
137  const std::string path =
138  file_path(particle_list_file_directory, particle_list_file_name);
139  if (same_file && !filestream_shared_) {
140  filestream_shared_ = make_unique<std::ifstream>(path);
142  } else if (!same_file) {
143  filestream_ = make_unique<std::ifstream>(path);
145  } else {
147  }
148 
151  // Inherited from nucleus class (see nucleus.h)
153 }
154 
155 void CustomNucleus::fill_from_list(const std::vector<Nucleoncustom>& vec) {
156  particles_.clear();
157  index_ = 0;
158  // checking if particle is proton or neutron
159  for (const auto& it : vec) {
160  PdgCode pdgcode;
161  if (it.isospin == 1) {
162  pdgcode = pdg::p;
163  } else if (it.isospin == 0) {
164  pdgcode = pdg::n;
165  } else {
166  throw std::runtime_error(
167  "Your particles charges are not 1 = proton or 0 = neutron.\n"
168  "Check whether your list is correct or there is an error.");
169  }
170  // setting parameters for the particles in the particlelist in smash
171  const ParticleType& current_type = ParticleType::find(pdgcode);
172  double current_mass = current_type.mass();
173  particles_.emplace_back(current_type);
174  particles_.back().set_4momentum(current_mass, 0.0, 0.0, 0.0);
175  }
176 }
177 
179  /*
180  * As only arrange_nucleons is called at the beginning of every
181  * event it is important to have readfile and fill from list
182  * called again when a new event starts. The constructor is only
183  * called twice to initialize the first target and projectile.
184  * Therefore this if statement is implemented.
185  */
186  if (index_ >= custom_nucleus_.size()) {
189  }
190  const auto& pos = custom_nucleus_.at(index_);
191  index_++;
192  ThreeVector nucleon_position(pos.x, pos.y, pos.z);
193  // rotate nucleon about euler angle
194  nucleon_position.rotate(euler_phi_, euler_theta_, euler_psi_);
195 
196  return nucleon_position;
197 }
198 
200  /* Randomly generate Euler angles for rotation everytime a new
201  * custom nucleus is initialized. Therefore this is done 2 times per
202  * event.
203  */
205 
206  for (auto i = begin(); i != end(); i++) {
207  // Initialize momentum
208  i->set_4momentum(i->pole_mass(), 0.0, 0.0, 0.0);
209  /* Sampling the Woods-Saxon, get the radial
210  * position and solid angle for the nucleon. */
212  // Set the position of the nucleon.
213  i->set_4position(FourVector(0.0, pos));
214  }
215  // Recenter
216  align_center();
217 }
218 
221  logg[LCollider].warn() << "Fermi motion activated with a custom nucleus.\n";
222  logg[LCollider].warn() << "Be aware that generating the Fermi momenta\n"
223  << "assumes nucleons distributed according to a\n"
224  << "Woods-Saxon distribution.";
225 }
226 
227 std::string CustomNucleus::file_path(const std::string& file_directory,
228  const std::string& file_name) {
229  if (file_directory.back() == '/') {
230  return file_directory + file_name;
231  } else {
232  return file_directory + '/' + file_name;
233  }
234 }
235 
236 std::vector<Nucleoncustom> CustomNucleus::readfile(
237  std::ifstream& infile) const {
238  int proton_counter = 0;
239  int neutron_counter = 0;
240  std::string line;
241  std::vector<Nucleoncustom> custom_nucleus;
242  // read in only A particles for one nucleus
243  for (int i = 0; i < number_of_nucleons_; ++i) {
244  std::getline(infile, line);
245  // make sure the stream goes back to the beginning when it hits end of file
246  if (infile.eof()) {
247  infile.clear();
248  infile.seekg(0, infile.beg);
249  std::getline(infile, line);
250  }
251  Nucleoncustom nucleon;
252  std::istringstream iss(line);
253  if (!(iss >> nucleon.x >> nucleon.y >> nucleon.z >>
254  nucleon.spinprojection >> nucleon.isospin)) {
255  throw std::runtime_error(
256  "SMASH could not read in a line from your initial nuclei input file."
257  "\nCheck if your file has the following format: x y z "
258  "spinprojection isospin");
259  }
260  if (nucleon.isospin == 1) {
261  proton_counter++;
262  } else if (nucleon.isospin == 0) {
263  neutron_counter++;
264  }
265  custom_nucleus.push_back(nucleon);
266  }
267  if (proton_counter != number_of_protons_ ||
268  neutron_counter != number_of_neutrons_) {
269  throw std::runtime_error(
270  "Number of protons and/or neutrons in the nuclei input file does not "
271  "correspond to the number specified in the config.\nCheck the config "
272  "and your input file.");
273  } else {
274  return custom_nucleus;
275  }
276 }
277 
278 } // 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:479
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:97
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
double mass() const
Definition: particletype.h:144
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
Definition: pdgcode.h:108
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:276
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