Version: SMASH-2.0
customnucleus.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2020
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 
87 std::unique_ptr<std::ifstream> CustomNucleus::filestream_shared_ = nullptr;
88 
89 CustomNucleus::CustomNucleus(Configuration& config, int testparticles,
90  bool same_file) {
91  // Read in file directory from config
92  const std::string particle_list_file_directory =
93  config.take({"Custom", "File_Directory"});
94  // Read in file name from config
95  const std::string particle_list_file_name =
96  config.take({"Custom", "File_Name"});
97 
98  if (particles_.size() != 0) {
99  throw std::runtime_error(
100  "Your Particle List is already filled before reading in from the "
101  "external file."
102  "Something went wrong. Please check your config.");
103  }
104  /*
105  * Counts number of nucleons in one nucleus as it is specialized
106  * by the user in the config file.
107  * It is needed to read in the proper number of nucleons for one
108  * nucleus and to restart at the listreading for the following
109  * nucleus as one does not want to read configurations twice.
110  */
111  std::map<PdgCode, int> particle_list = config.take({"Particles"});
112  for (const auto& particle : particle_list) {
113  if (particle.first == pdg::p) {
114  number_of_protons_ = particle.second * testparticles;
115  } else if (particle.first == pdg::n) {
116  number_of_neutrons_ = particle.second * testparticles;
117  } else {
118  throw std::runtime_error(
119  "Your nucleus can only contain protons and/or neutrons."
120  "Please check what particles you have specified in the config");
121  }
123  }
124  /*
125  * "if" statement makes sure the streams to the file are initialized
126  * properly.
127  */
128  const std::string path =
129  file_path(particle_list_file_directory, particle_list_file_name);
130  if (same_file && !filestream_shared_) {
131  filestream_shared_ = make_unique<std::ifstream>(path);
133  } else if (!same_file) {
134  filestream_ = make_unique<std::ifstream>(path);
136  } else {
138  }
139 
142  // Inherited from nucleus class (see nucleus.h)
144 }
145 
146 void CustomNucleus::fill_from_list(const std::vector<Nucleoncustom>& vec) {
147  particles_.clear();
148  index_ = 0;
149  // checking if particle is proton or neutron
150  for (const auto& it : vec) {
151  PdgCode pdgcode;
152  if (it.isospin == 1) {
153  pdgcode = pdg::p;
154  } else if (it.isospin == 0) {
155  pdgcode = pdg::n;
156  } else {
157  throw std::runtime_error(
158  "Your particles charges are not 1 = proton or 0 = neutron.\n"
159  "Check whether your list is correct or there is an error.");
160  }
161  // setting parameters for the particles in the particlelist in smash
162  const ParticleType& current_type = ParticleType::find(pdgcode);
163  double current_mass = current_type.mass();
164  particles_.emplace_back(current_type);
165  particles_.back().set_4momentum(current_mass, 0.0, 0.0, 0.0);
166  }
167 }
168 
170  /*
171  * As only arrange_nucleons is called at the beginning of every
172  * event it is important to have readfile and fill from list
173  * called again when a new event starts. The constructor is only
174  * called twice to initialize the first target and projectile.
175  * Therefore this if statement is implemented.
176  */
177  if (index_ >= custom_nucleus_.size()) {
180  }
181  const auto& pos = custom_nucleus_.at(index_);
182  index_++;
183  ThreeVector nucleon_position(pos.x, pos.y, pos.z);
184  // rotate nucleon about euler angle
185  nucleon_position.rotate(euler_phi_, euler_theta_, euler_psi_);
186 
187  return nucleon_position;
188 }
189 
191  /* Randomly generate Euler angles for rotation everytime a new
192  * custom nucleus is initialized. Therefore this is done 2 times per
193  * event.
194  */
196 
197  for (auto i = begin(); i != end(); i++) {
198  // Initialize momentum
199  i->set_4momentum(i->pole_mass(), 0.0, 0.0, 0.0);
200  /* Sampling the Woods-Saxon, get the radial
201  * position and solid angle for the nucleon. */
203  // Set the position of the nucleon.
204  i->set_4position(FourVector(0.0, pos));
205  }
206  // Recenter
207  align_center();
208 }
209 
212  logg[LCollider].warn() << "Fermi motion activated with a custom nucleus.\n";
213  logg[LCollider].warn() << "Be aware that generating the Fermi momenta\n"
214  << "assumes nucleons distributed according to a\n"
215  << "Woods-Saxon distribution.";
216 }
217 
218 std::string CustomNucleus::file_path(const std::string& file_directory,
219  const std::string& file_name) {
220  if (file_directory.back() == '/') {
221  return file_directory + file_name;
222  } else {
223  return file_directory + '/' + file_name;
224  }
225 }
226 
227 std::vector<Nucleoncustom> CustomNucleus::readfile(
228  std::ifstream& infile) const {
229  int proton_counter = 0;
230  int neutron_counter = 0;
231  std::string line;
232  std::vector<Nucleoncustom> custom_nucleus;
233  // read in only A particles for one nucleus
234  for (int i = 0; i < number_of_nucleons_; ++i) {
235  std::getline(infile, line);
236  // make sure the stream goes back to the beginning when it hits end of file
237  if (infile.eof()) {
238  infile.clear();
239  infile.seekg(0, infile.beg);
240  std::getline(infile, line);
241  }
242  Nucleoncustom nucleon;
243  std::istringstream iss(line);
244  if (!(iss >> nucleon.x >> nucleon.y >> nucleon.z >>
245  nucleon.spinprojection >> nucleon.isospin)) {
246  throw std::runtime_error(
247  "SMASH could not read in a line from your initial nuclei input file."
248  "\nCheck if your file has the following format: x y z "
249  "spinprojection isospin");
250  }
251  if (nucleon.isospin == 1) {
252  proton_counter++;
253  } else if (nucleon.isospin == 0) {
254  neutron_counter++;
255  }
256  custom_nucleus.push_back(nucleon);
257  }
258  if (proton_counter != number_of_protons_ ||
259  neutron_counter != number_of_neutrons_) {
260  throw std::runtime_error(
261  "Number of protons and/or neutrons in the nuclei input file does not "
262  "correspond to the number specified in the config.\nCheck the config "
263  "and your input file.");
264  } else {
265  return custom_nucleus;
266  }
267 }
268 
269 } // namespace smash
smash::CustomNucleus::distribute_nucleon
ThreeVector distribute_nucleon() override
Returns position of a nucleon as given in the external file.
Definition: customnucleus.cc:169
smash::Nucleus::random_euler_angles
void random_euler_angles()
Randomly generate Euler angles.
Definition: nucleus.cc:497
smash
Definition: action.h:24
customnucleus.h
smash::CustomNucleus::arrange_nucleons
void arrange_nucleons() override
Sets the positions of the nucleons inside a nucleus.
Definition: customnucleus.cc:190
smash::Nucleus::generate_fermi_momenta
virtual void generate_fermi_momenta()
Generates momenta according to Fermi motion for the nucleons.
Definition: nucleus.cc:365
smash::Nucleoncustom::z
double z
z-coordinate
Definition: customnucleus.h:30
smash::Nucleoncustom::x
double x
x-coordinate
Definition: customnucleus.h:26
smash::CustomNucleus::CustomNucleus
CustomNucleus(Configuration &config, int testparticles, bool same_file)
Constructor that needs configuration parameters from input file and the number of testparticles.
Definition: customnucleus.cc:89
smash::ThreeVector::rotate
void rotate(double phi, double theta, double psi)
Rotate vector by the given Euler angles phi, theta, psi.
Definition: threevector.h:276
smash::Nucleus::begin
std::vector< ParticleData >::iterator begin()
For iterators over the particle list:
Definition: nucleus.h:273
smash::Nucleoncustom::y
double y
y-coordinate
Definition: customnucleus.h:28
smash::ParticleType::mass
double mass() const
Definition: particletype.h:144
smash::Nucleus::euler_theta_
double euler_theta_
Euler angel theta.
Definition: nucleus.h:267
smash::Nucleus::align_center
void align_center()
Shifts the nucleus so that its center is at (0,0,0)
Definition: nucleus.h:215
smash::Nucleoncustom::isospin
bool isospin
to differentiate between protons isospin=1 and neutrons isospin=0
Definition: customnucleus.h:34
smash::CustomNucleus::generate_fermi_momenta
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...
Definition: customnucleus.cc:210
smash::logg
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
Definition: logging.cc:39
smash::Nucleus::set_parameters_automatic
virtual void set_parameters_automatic()
Sets the deformation parameters of the Woods-Saxon distribution according to the current mass number.
Definition: nucleus.cc:280
smash::Nucleus::particles_
std::vector< ParticleData > particles_
Particles associated with this nucleus.
Definition: nucleus.h:256
smash::ParticleType::find
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
Definition: particletype.cc:99
smash::Configuration
Interface to the SMASH configuration files.
Definition: configuration.h:464
smash::CustomNucleus::filestream_
std::unique_ptr< std::ifstream > filestream_
Filestream variable used if projectile and target are read in from different files and they therefore...
Definition: customnucleus.h:103
smash::ThreeVector
Definition: threevector.h:31
smash::Nucleus::euler_psi_
double euler_psi_
Euler angel psi.
Definition: nucleus.h:269
smash::CustomNucleus::custom_nucleus_
std::vector< Nucleoncustom > custom_nucleus_
Vector contianing Data for one nucleus given in the particlelist.
Definition: customnucleus.h:118
smash::CustomNucleus::number_of_nucleons_
int number_of_nucleons_
Number of nucleons per nucleus Set initally to zero to be modified in the constructor.
Definition: customnucleus.h:112
smash::Nucleus::end
std::vector< ParticleData >::iterator end()
For iterators over the particle list:
Definition: nucleus.h:277
smash::CustomNucleus::number_of_neutrons_
int number_of_neutrons_
Number of neutrons per nucleus.
Definition: customnucleus.h:116
smash::ParticleType
Definition: particletype.h:97
smash::LCollider
static constexpr int LCollider
Definition: collidermodus.cc:30
particletype.h
smash::CustomNucleus::used_filestream_
std::unique_ptr< std::ifstream > * used_filestream_
Pointer to the used filestream pointer.
Definition: customnucleus.h:105
smash::PdgCode
Definition: pdgcode.h:108
smash::CustomNucleus::file_path
std::string file_path(const std::string &file_directory, const std::string &file_name)
Generates the name of the stream file.
Definition: customnucleus.cc:218
smash::CustomNucleus::number_of_protons_
int number_of_protons_
Number of protons per nucleus.
Definition: customnucleus.h:114
constants.h
smash::Nucleus::euler_phi_
double euler_phi_
Euler angel phi.
Definition: nucleus.h:265
pdgcode.h
smash::Nucleoncustom
Contains data for one nucleon that is read in from the list.
Definition: customnucleus.h:24
smash::CustomNucleus::filestream_shared_
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
smash::Nucleoncustom::spinprojection
bool spinprojection
spinprojection of the nucleon
Definition: customnucleus.h:32
smash::Configuration::take
Value take(std::initializer_list< const char * > keys)
The default interface for SMASH to read configuration values.
Definition: configuration.cc:140
smash::FourVector
Definition: fourvector.h:33
smash::CustomNucleus::index_
size_t index_
Index needed to read out vector in distribute nucleon.
Definition: customnucleus.h:120
smash::CustomNucleus::fill_from_list
void fill_from_list(const std::vector< Nucleoncustom > &vec)
Fills Particlelist from vector containing data for one nucleus.
Definition: customnucleus.cc:146
smash::pdg::p
constexpr int p
Proton.
Definition: pdgcode_constants.h:28
smash::pdg::n
constexpr int n
Neutron.
Definition: pdgcode_constants.h:30
smash::CustomNucleus::readfile
std::vector< Nucleoncustom > readfile(std::ifstream &infile) const
The returned vector contains Data for one nucleus given in the particlelist.
Definition: customnucleus.cc:227