374   using namespace smash;  
 
  376   constexpr option longopts[] = {
 
  377       {
"config", required_argument, 0, 
'c'},
 
  378       {
"decaymodes", required_argument, 0, 
'd'},
 
  379       {
"endtime", required_argument, 0, 
'e'},
 
  380       {
"force", no_argument, 0, 
'f'},
 
  381       {
"help", no_argument, 0, 
'h'},
 
  382       {
"inputfile", required_argument, 0, 
'i'},
 
  383       {
"modus", required_argument, 0, 
'm'},
 
  384       {
"particles", required_argument, 0, 
'p'},
 
  385       {
"output", required_argument, 0, 
'o'},
 
  386       {
"list-2-to-n", no_argument, 0, 
'l'},
 
  387       {
"resonance", required_argument, 0, 
'r'},
 
  388       {
"cross-sections", required_argument, 0, 
's'},
 
  389       {
"cross-sections-fs", required_argument, 0, 
'S'},
 
  390       {
"dump-iSS", no_argument, 0, 
'x'},
 
  391       {
"version", no_argument, 0, 
'v'},
 
  392       {
"no-cache", no_argument, 0, 
'n'},
 
  393       {
"quiet", no_argument, 0, 
'q'},
 
  397   const std::string progname =
 
  398       std::filesystem::path(argv[0]).filename().native();
 
  401     bool force_overwrite = 
false;
 
  403     std::string input_path(
"./config.yaml"), particles, decaymodes;
 
  404     std::vector<std::string> extra_config;
 
  405     char *modus = 
nullptr, *end_time = 
nullptr, *pdg_string = 
nullptr,
 
  406          *cs_string = 
nullptr;
 
  407     bool list2n_activated = 
false;
 
  408     bool resonance_dump_activated = 
false;
 
  409     bool cross_section_dump_activated = 
false;
 
  410     bool final_state_cross_sections = 
false;
 
  411     bool particles_dump_iSS_format = 
false;
 
  412     bool cache_integrals = 
true;
 
  413     bool suppress_disclaimer = 
false;
 
  417     while ((opt = getopt_long(argc, argv, 
"c:d:e:fhi:m:p:o:lr:s:S:xvnq",
 
  418                               longopts, 
nullptr)) != -1) {
 
  421           extra_config.emplace_back(optarg);
 
  427           force_overwrite = 
true;
 
  433           usage(EXIT_SUCCESS, progname);
 
  445           output_path = optarg;
 
  448           list2n_activated = 
true;
 
  449           suppress_disclaimer = 
true;
 
  452           resonance_dump_activated = 
true;
 
  454           suppress_disclaimer = 
true;
 
  457           final_state_cross_sections = 
true;
 
  460           cross_section_dump_activated = 
true;
 
  462           suppress_disclaimer = 
true;
 
  465           particles_dump_iSS_format = 
true;
 
  466           suppress_disclaimer = 
true;
 
  474               "System   : %s\nCompiler : %s %s\n" 
  475               "Build    : %s\nDate     : %s\n",
 
  480               CMAKE_SYSTEM, CMAKE_CXX_COMPILER_ID, CMAKE_CXX_COMPILER_VERSION,
 
  481               CMAKE_BUILD_TYPE, BUILD_DATE);
 
  482           std::exit(EXIT_SUCCESS);
 
  484           cache_integrals = 
false;
 
  487           suppress_disclaimer = 
true;
 
  490           usage(EXIT_FAILURE, progname);
 
  496       std::cout << argv[0] << 
": invalid argument -- '" << argv[optind]
 
  498       usage(EXIT_FAILURE, progname);
 
  501     if (!suppress_disclaimer) {
 
  506                                                   decaymodes, extra_config);
 
  512     std::string tabulations_path;
 
  513     if (cache_integrals) {
 
  514       tabulations_path = output_path.has_parent_path()
 
  515                              ? output_path.parent_path().string()
 
  517       tabulations_path += 
"/tabulations";
 
  519       tabulations_path = 
"";
 
  521     const std::string version(SMASH_VERSION);
 
  523     if (list2n_activated) {
 
  526       configuration.merge_yaml(
"{Collision_Term: {Two_to_One: False}}");
 
  534       scat_finder.dump_reactions();
 
  535       std::exit(EXIT_SUCCESS);
 
  537     if (particles_dump_iSS_format) {
 
  540       ParticleTypePtrList list;
 
  543         list.push_back(&ptype);
 
  545       std::sort(list.begin(), list.end(),
 
  547                   return a->mass() < b->mass();
 
  550         if (ptype->pdgcode().is_lepton() || ptype->baryon_number() < 0) {
 
  553         const auto &decay_modes = ptype->decay_modes();
 
  554         const auto &modelist = decay_modes.decay_mode_list();
 
  555         int ndecays = ptype->is_stable() ? 1 : modelist.size();
 
  556         std::printf(
"%13i %s %10.5f %10.5f %5i %5i %5i %5i %5i %5i %5i %5i\n",
 
  557                     ptype->pdgcode().get_decimal(),
 
  559                     ptype->mass(), ptype->width_at_pole(),
 
  560                     ptype->pdgcode().spin_degeneracy(), ptype->baryon_number(),
 
  561                     ptype->strangeness(), ptype->pdgcode().charmness(),
 
  562                     ptype->pdgcode().bottomness(), ptype->isospin() + 1,
 
  563                     ptype->charge(), ndecays);
 
  564         if (!ptype->is_stable()) {
 
  565           for (
const auto &decay : modelist) {
 
  566             auto ptypes = decay->particle_types();
 
  567             std::printf(
"%13i %13i %20.5f %13i %13i %13i %13i %13i\n",
 
  568                         ptype->pdgcode().get_decimal(), 2, decay->weight(),
 
  569                         ptypes[0]->pdgcode().get_decimal(),
 
  570                         ptypes[1]->pdgcode().get_decimal(), 0, 0, 0);
 
  573           std::printf(
"%13i %13i %20.5f %13i %13i %13i %13i %13i\n",
 
  574                       ptype->pdgcode().get_decimal(), 1, 1.0,
 
  575                       ptype->pdgcode().get_decimal(), 0, 0, 0, 0);
 
  578       std::exit(EXIT_SUCCESS);
 
  580     if (resonance_dump_activated) {
 
  591       std::exit(EXIT_SUCCESS);
 
  593     if (cross_section_dump_activated) {
 
  596       std::string arg_string(cs_string);
 
  597       std::vector<std::string> args = 
split(arg_string, 
',');
 
  598       const unsigned int n_arg = args.size();
 
  599       if (n_arg != 2 && n_arg != 4 && n_arg < 5) {
 
  600         throw std::invalid_argument(
"-s usage: pdg1,pdg2[,m1,m2[,sqrts1,...]]");
 
  602       PdgCode pdg_a(args[0]), pdg_b(args[1]);
 
  606         for (
unsigned int i = 0; i < 4 - n_arg; i++) {
 
  610       double ma = (args[2] == 
"") ? a.
mass() : std::stod(args[2]);
 
  611       double mb = (args[3] == 
"") ? b.
mass() : std::stod(args[3]);
 
  612       if (a.
is_stable() && args[2] != 
"" && std::stod(args[2]) != a.
mass()) {
 
  614         std::cerr << 
"Warning: pole mass is used for stable particle " 
  615                   << a.
name() << 
" instead of " << args[2] << std::endl;
 
  617       if (b.
is_stable() && args[3] != 
"" && std::stod(args[3]) != b.
mass()) {
 
  619         std::cerr << 
"Warning: pole mass is used for stable particle " 
  620                   << b.
name() << 
" instead of " << args[3] << std::endl;
 
  622       const size_t plab_size = n_arg <= 4 ? 0 : n_arg - 4;
 
  623       std::vector<double> plab;
 
  624       plab.reserve(plab_size);
 
  625       for (
size_t i = 4; i < n_arg; i++) {
 
  626         plab.push_back(std::stod(args.at(i)));
 
  633       scat_finder.dump_cross_sections(a, b, ma, mb, final_state_cross_sections,
 
  635       std::exit(EXIT_SUCCESS);
 
  642                               std::abs(std::atof(end_time)));
 
  652     const std::filesystem::path lock_path = output_path / 
"smash.lock";
 
  654     if (!lock.acquire()) {
 
  655       throw std::runtime_error(
 
  656           "Another instance of SMASH is already writing to the specified " 
  657           "output directory. If you are sure this is not the case, remove \"" +
 
  658           lock_path.native() + 
"\".");
 
  660     logg[
LMain].debug(
"output path: ", output_path);
 
  661     if (!force_overwrite &&
 
  662         std::filesystem::exists(output_path / 
"config.yaml")) {
 
  663       throw std::runtime_error(
 
  664           "Output directory would get overwritten. Select a different output " 
  665           "directory, clean up, or tell SMASH to ignore existing files.");
 
  670     std::ofstream(output_path / 
"config.yaml")
 
  671         << 
"# " << SMASH_VERSION << 
'\n' 
  673         << 
"# Branch   : " << GIT_BRANCH << 
'\n' 
  675         << 
"# System   : " << CMAKE_SYSTEM << 
'\n' 
  676         << 
"# Compiler : " << CMAKE_CXX_COMPILER_ID << 
' ' 
  677         << CMAKE_CXX_COMPILER_VERSION << 
'\n' 
  678         << 
"# Build    : " << CMAKE_BUILD_TYPE << 
'\n' 
  679         << 
"# Date     : " << BUILD_DATE << 
'\n' 
  680         << configuration.to_string() << 
'\n';
 
  694   } 
catch (std::exception &e) {
 
  695     logg[
LMain].fatal() << 
"SMASH failed with the following error:\n" 
static std::unique_ptr< ExperimentBase > create(Configuration &config, const std::filesystem::path &output_path)
Factory method that creates and initializes a new Experiment<Modus>.
 
Guard to create a file lock.
 
A pointer-like interface to global references to ParticleType objects.
 
Particle type contains the static properties of a particle species.
 
void dump_width_and_spectral_function() const
Prints out width and spectral function versus mass to the standard output.
 
static const ParticleType & find(PdgCode pdgcode)
Returns the ParticleType object for the given pdgcode.
 
const std::string & name() const
 
static const ParticleTypeList & list_all()
 
PdgCode stores a Particle Data Group Particle Numbering Scheme particle type number.
 
#define SMASH_SOURCE_LOCATION
Hackery that is required to output the location in the source code where the log statement occurs.
 
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
 
std::unique_ptr< ExperimentBase > experiment(Configuration c)
Create an experiment given an input configuration.
 
void ignore_simulation_config_values(Configuration &configuration)
Remove all config values that are only needed for simulations.
 
ScatterActionsFinder actions_finder_for_dump(Configuration &configuration)
Prepares ActionsFinder for cross-section and reaction dumps.
 
void usage(const int rc, const std::string &progname)
Prints usage information and exits the program.
 
void ensure_path_is_valid(const std::filesystem::path &path)
Ensures the output path is valid.
 
void check_for_unused_config_values(const Configuration &configuration)
Checks if there are unused config values.
 
void print_disclaimer()
Print the disclaimer.
 
std::filesystem::path default_output_path()
 
int64_t generate_63bit_seed()
Generates a seed with a truly random 63-bit value, if possible.
 
std::string fill_left(const std::string &s, size_t width, char fill=' ')
Fill string with characters to the left until the given width is reached.
 
std::vector< std::string > split(const std::string &s, char delim)
Split string by delimiter.
 
void initialize_particles_decays_and_tabulations(Configuration &configuration, const std::string &version, const std::string &tabulations_dir={})
Wrapper over a function that initializes the particles and decays from the given configuration,...
 
void tabulate_resonance_integrals(const sha256::Hash &hash, const std::string &tabulations_dir)
Tabulate the resonance integrals.
 
Configuration setup_config_and_logging(const std::string &config_file, const std::string &particles_file={}, const std::string &decaymodes_file={}, const std::vector< std::string > &extra_config={})
Set up configuration and logging from input files and extra config.
 
sha256::Hash initialize_particles_decays_and_return_hash(Configuration &configuration, const std::string &version)
Initialize the particles and decays from the given configuration.
 
void setup_default_float_traps()
Setup the floating-point traps used throughout SMASH.
 
static constexpr int LMain