Version: SMASH-1.6
configuration.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright (c) 2014-2019
4  * SMASH Team
5  *
6  * GNU General Public License (GPLv3 or later)
7  *
8  */
9 
10 #ifndef SRC_INCLUDE_CONFIGURATION_H_
11 #define SRC_INCLUDE_CONFIGURATION_H_
12 
13 #include <array>
14 #include <set>
15 #include <stdexcept>
16 #include <string>
17 #include <utility>
18 #include <vector>
19 
20 #include <yaml-cpp/yaml.h> // NOLINT(build/include_order)
21 
22 #include "density.h"
23 #include "forwarddeclarations.h"
24 
25 namespace YAML {
26 
33 template <typename T>
34 struct convert {
42  static Node encode(const T &x) { return Node{static_cast<std::string>(x)}; }
43 
52  static bool decode(const Node &node, T &x) {
53  if (!node.IsScalar()) {
54  return false;
55  } else {
56  x = static_cast<T>(node.Scalar());
57  return true;
58  }
59  }
60 };
61 } // namespace YAML
62 
63 namespace smash {
314  public:
319  struct IncorrectTypeInAssignment : public std::runtime_error {
320  using std::runtime_error::runtime_error;
321  };
326  struct ParseError : public std::runtime_error {
327  using std::runtime_error::runtime_error;
328  };
329 
334  struct FileDoesNotExist : public std::runtime_error {
335  using std::runtime_error::runtime_error;
336  };
337 
345  class Value {
346  friend class Configuration;
347 
349  const YAML::Node node_;
351  const char *const key_;
352 
359  Value(const YAML::Node &n, const char *key) : node_(n), key_(key) {
360  if (!(n.IsScalar() || n.IsSequence() || n.IsMap())) {
361  std::stringstream err;
362  err << "Configuration value for \"" << key
363  << "\" is missing or invalid";
364  throw std::runtime_error(err.str());
365  }
366  }
367 
368  public:
370  Value(const Value &) = delete;
372  Value &operator=(const Value &) = delete;
373 
400  template <typename T>
401  T convert_for(const T &) const {
402  return *this;
403  }
404 
413  template <typename T>
414  operator T() const {
415  try {
416  return node_.as<T>();
417  } catch (YAML::TypedBadConversion<T> &e) {
419  "The value for key \"" + std::string(key_) +
420  "\" cannot be converted to the requested type.");
421  }
422  }
423 
429  template <typename T>
430  operator std::vector<T>() const {
431  try {
432  return node_.as<std::vector<T>>();
433  } catch (YAML::TypedBadConversion<T> &e) {
435  "One of the values in the sequence for key \"" + std::string(key_) +
436  "\" failed to convert to the requested type. E.g. [1 2] is a "
437  "sequence of one string \"1 2\" and [1, 2] is a sequence of two "
438  "integers. Often there is just a comma missing in the config "
439  "file.");
440  } catch (YAML::TypedBadConversion<std::vector<T>> &e) {
442  "The value for key \"" + std::string(key_) +
443  "\" cannot be converted to the requested type. A sequence was "
444  "expected but apparently not found.");
445  }
446  }
447 
455  template <typename T, size_t N>
456  operator std::array<T, N>() const {
457  const std::vector<T> vec = operator std::vector<T>();
458  const size_t n_read = vec.size();
459  // Alert if size does not match
460  if (n_read != N) {
461  throw IncorrectTypeInAssignment("Wrong number of values in array \"" +
462  std::string(key_) + "\". Expected " +
463  std::to_string(N) +
464  " values,"
465  " found " +
466  std::to_string(n_read) + ".");
467  }
468  std::array<T, N> arr;
469  std::copy_n(vec.begin(), N, arr.begin());
470  return arr;
471  }
472 
480  operator ReactionsBitSet() const {
481  const std::vector<std::string> v = operator std::vector<std::string>();
482  ReactionsBitSet s;
483  for (const auto &x : v) {
484  if (x == "All") {
485  s.set();
486  break;
487  } else if (x == "Elastic") {
489  } else if (x == "NN_to_NR") {
491  } else if (x == "NN_to_DR") {
493  } else if (x == "KN_to_KN") {
495  } else if (x == "KN_to_KDelta") {
497  } else if (x == "Strangeness_exchange") {
499  } else {
501  "The value for key \"" + std::string(key_) +
502  "\" should be \"All\", \"Elastic\", \"NN_to_NR\", \"NN_to_DR\","
503  "\"KN_to_KN\", \"KN_to_KDelta\" or \"strangeness_exchange\","
504  " or any combination of these.");
505  }
506  }
507  return s;
508  }
509 
517  operator std::set<ThermodynamicQuantity>() const {
518  const std::vector<std::string> v = operator std::vector<std::string>();
519  std::set<ThermodynamicQuantity> s;
520  for (const auto &x : v) {
521  if (x == "rho_eckart") {
523  } else if (x == "tmn") {
524  s.insert(ThermodynamicQuantity::Tmn);
525  } else if (x == "tmn_landau") {
527  } else if (x == "landau_velocity") {
529  } else if (x == "j_QBS") {
531  } else {
533  "The value for key \"" + std::string(key_) +
534  "\" should be \"rho_eckart\", \"tmn\""
535  ", \"tmn_landau\", \"landau_velocity\" or \"j_QBS\".");
536  }
537  }
538  return s;
539  }
540 
548  operator CalculationFrame() const {
549  const std::string s = operator std::string();
550  if (s == "center of velocity") {
552  }
553  if (s == "center of mass") {
555  }
556  if (s == "fixed target") {
558  }
560  "The value for key \"" + std::string(key_) +
561  "\" should be \"center of velocity\" or \"center of mass\" "
562  "or \"fixed target\".");
563  }
564 
572  operator FermiMotion() const {
573  const std::string s = operator std::string();
574  if (s == "off") {
575  return FermiMotion::Off;
576  }
577  if (s == "on") {
578  return FermiMotion::On;
579  }
580  if (s == "frozen") {
581  return FermiMotion::Frozen;
582  }
584  "The value for key \"" + std::string(key_) +
585  "\" should be \"off\" or \"on\" or \"frozen\".");
586  }
587 
595  operator DensityType() const {
596  const std::string s = operator std::string();
597  if (s == "hadron") {
598  return DensityType::Hadron;
599  }
600  if (s == "baryon") {
601  return DensityType::Baryon;
602  }
603  if (s == "baryonic isospin") {
604  return DensityType::BaryonicIsospin;
605  }
606  if (s == "pion") {
607  return DensityType::Pion;
608  }
609  if (s == "total isospin") {
610  return DensityType::Isospin3_tot;
611  }
612  if (s == "none") {
613  return DensityType::None;
614  }
615  throw IncorrectTypeInAssignment("The value for key \"" +
616  std::string(key_) +
617  "\" should be \"hadron\" or \"baryon\" "
618  "or \"baryonic isospin\" or \"pion\" "
619  "or \"none\".");
620  }
621 
629  operator ExpansionMode() const {
630  const std::string s = operator std::string();
631  if (s == "NoExpansion") {
633  }
634  if (s == "MasslessFRW") {
636  }
637  if (s == "MassiveFRW") {
639  }
640  if (s == "Exponential") {
642  }
644  "The value for key \"" + std::string(key_) +
645  "\" should be \"NoExpansion\", \"MasslessFRW\"," +
646  "\"MassiveFRW\" or \"Exponential\".");
647  }
648 
656  operator TimeStepMode() const {
657  const std::string s = operator std::string();
658  if (s == "None") {
659  return TimeStepMode::None;
660  }
661  if (s == "Fixed") {
662  return TimeStepMode::Fixed;
663  }
664  throw IncorrectTypeInAssignment("The value for key \"" +
665  std::string(key_) +
666  "\" should be \"None\" or \"Fixed\".");
667  }
668 
676  operator BoxInitialCondition() const {
677  const std::string s = operator std::string();
678  if (s == "thermal momenta") {
680  }
681  if (s == "peaked momenta") {
683  }
685  "The value for key \"" + std::string(key_) +
686  "\" should be \"thermal momenta\" or \"peaked momenta\".");
687  }
688 
696  operator SphereInitialCondition() const {
697  const std::string s = operator std::string();
698  if (s == "thermal momenta") {
700  }
701  if (s == "IC_ES") {
703  }
704  if (s == "IC_1M") {
706  }
707  if (s == "IC_2M") {
709  }
710  if (s == "IC_Massive") {
712  }
714  "The value for key \"" + std::string(key_) +
715  "\" should be \"thermal momenta\", \"IC_ES\", " +
716  "\"IC_1M\", \"IC_2M\" or" + "\"IC_Massive\".");
717  }
718 
726  operator NNbarTreatment() const {
727  const std::string s = operator std::string();
728  if (s == "no annihilation") {
730  }
731  if (s == "resonances") {
733  }
734  if (s == "strings") {
736  }
738  "The value for key \"" + std::string(key_) + "\" should be " +
739  "\"no annihilation\", \"detailed balance\", or \"strings\".");
740  }
741 
749  operator Sampling() const {
750  const std::string s = operator std::string();
751  if (s == "quadratic") {
752  return Sampling::Quadratic;
753  }
754  if (s == "custom") {
755  return Sampling::Custom;
756  }
757  if (s == "uniform") {
758  return Sampling::Uniform;
759  }
761  "The value for key \"" + std::string(key_) +
762  "\" should be \"quadratic\", \"uniform\" or \"custom\".");
763  }
764 
772  operator ThermalizationAlgorithm() const {
773  const std::string s = operator std::string();
774  if (s == "mode sampling") {
776  }
777  if (s == "biased BF") {
779  }
780  if (s == "unbiased BF") {
782  }
784  "The value for key \"" + std::string(key_) +
785  "\" should be \"mode sampling\", \"biased BF\" or \"unbiased BF\".");
786  }
787  };
788 
794  explicit Configuration(const bf::path &path);
795 
803  explicit Configuration(const bf::path &path, const bf::path &filename);
804 
805 #ifdef BUILD_TESTS
806 
814  explicit Configuration(const char *yaml) : root_node_(YAML::Load(yaml)) {}
815 #endif
816 
818  Configuration(const Configuration &) = default;
820  Configuration &operator=(const Configuration &) = default;
821 
823  Configuration(Configuration &&) = default;
825  Configuration &operator=(Configuration &&) = default;
826 
837  void merge_yaml(const std::string &yaml);
838 
840  std::vector<std::string> list_upmost_nodes();
841 
863  Value take(std::initializer_list<const char *> keys);
864 
866  template <typename T>
867  T take(std::initializer_list<const char *> keys, T default_value) {
868  if (has_value(keys)) {
869  return take(keys);
870  }
871  return default_value;
872  }
873 
888  Value read(std::initializer_list<const char *> keys) const;
889 
891  template <typename T>
892  T read(std::initializer_list<const char *> keys, T default_value) {
893  if (has_value(keys)) {
894  return read(keys);
895  }
896  return default_value;
897  }
898 
904  void remove_all_but(const std::string &key);
905 
920  template <typename T>
922  return root_node_[std::forward<T>(key)];
923  }
924 
932  template <typename T>
933  Configuration &operator=(T &&value) {
934  root_node_ = std::forward<T>(value);
935  return *this;
936  }
937 
942  bool has_value_including_empty(
943  std::initializer_list<const char *> keys) const;
948  bool has_value(std::initializer_list<const char *> keys) const;
949 
953  std::string unused_values_report() const;
954 
960  std::string to_string() const;
961 
962  private:
969  Configuration(const YAML::Node &node) // NOLINT(runtime/explicit) : see above
970  : root_node_(node) {}
971 
973  YAML::Node root_node_;
974 };
975 
976 } // namespace smash
977 
978 #endif // SRC_INCLUDE_CONFIGURATION_H_
Configuration(const YAML::Node &node)
Creates a subobject that has its root node at the given node.
Thrown if the file does not exist.
ThermalizationAlgorithm
Defines the algorithm used for the forced thermalization.
FermiMotion
Option to use Fermi Motion.
Return type of Configuration::take that automatically determines the target type. ...
T convert_for(const T &) const
Convert the value to the type of the supplied argument.
const char *const key_
The key to be interpreted.
BoxInitialCondition
Initial condition for a particle in a box.
Value(const YAML::Node &n, const char *key)
Constructs the Value wrapper from a YAML::Node.
const YAML::Node node_
a YAML leaf node
Configuration(const char *yaml)
T take(std::initializer_list< const char * > keys, T default_value)
Interface to the SMASH configuration files.
Thrown for YAML parse errors.
NNbarTreatment
Treatment of N Nbar Annihilation.
Convert from YAML::Node to SMASH-readable (C++) format and vice versa.
Definition: configuration.h:34
static bool decode(const Node &node, T &x)
Deserialization: Converts a YAML::Node to any SMASH-readable data type and returns whether or not thi...
Definition: configuration.h:52
Sample from uniform distribution.
SphereInitialCondition
Initial condition for a particle in a sphere.
CalculationFrame
The calculation frame.
TimeStepMode
The time step mode.
Sample from custom, user-defined distribution.
Don&#39;t use time steps; propagate from action to action.
Configuration operator[](T &&key)
Access to the YAML::Node behind the requested keys.
Sample from areal / quadratic distribution.
Configuration & operator=(T &&value)
Assignment overwrites the value of the current YAML node.
Don&#39;t use fermi motion.
std::bitset< 6 > ReactionsBitSet
Container for the 2 to 2 reactions in the code.
Use fermi motion without potentials.
Use string fragmentation.
Use fixed time step.
Use intermediate Resonances.
ExpansionMode
Defines properties of expansion for the metric (e.g.
Sampling
Possible methods of impact parameter sampling.
Thrown when the types in the config file and C++ don&#39;t match.
YAML::Node root_node_
the general_config.yaml contents - fully parsed
constexpr int n
Neutron.
DensityType
Allows to choose which kind of density to calculate.
Definition: density.h:34
static Node encode(const T &x)
Serialization: Converts x (of any type) to a YAML::Node.
Definition: configuration.h:42
T read(std::initializer_list< const char * > keys, T default_value)
Use fermi motion in combination with potentials.
Definition: action.h:24