https://mooseframework.inl.gov
Classes | Typedefs | Functions
ReactionNetworkUtils Namespace Reference

Classes

struct  Reaction
 
struct  Term
 

Typedefs

using TermList = std::vector< Term >
 
using Metadata = std::map< std::string, std::string >
 

Functions

std::vector< ReactionparseReactionNetwork (const std::string &reaction_network_string, bool output_to_cout)
 Parses the reaction network from a string form to a vector a Reaction. More...
 

Typedef Documentation

◆ Metadata

using ReactionNetworkUtils::Metadata = typedef std::map<std::string, std::string>

Definition at line 42 of file ReactionNetworkUtils.h.

◆ TermList

using ReactionNetworkUtils::TermList = typedef std::vector<Term>

Definition at line 41 of file ReactionNetworkUtils.h.

Function Documentation

◆ parseReactionNetwork()

std::vector< Reaction > ReactionNetworkUtils::parseReactionNetwork ( const std::string &  reaction_network_string,
bool  output_to_cout 
)

Parses the reaction network from a string form to a vector a Reaction.

Parameters
reaction_network_string
Returns

Definition at line 23 of file ReactionNetworkUtils.C.

Referenced by TEST().

24 {
25  using namespace peg;
26  parser parser(R"(
27  Reactions <- (_ Reaction _ Newline?)* _
28  Reaction <- TermList _ '->' _ TermList _ Metadata?
29  TermList <- Term (_ Term)*
30  Term <- Coefficient? Species
31  Coefficient <- Float
32  Float <- [+-]? (_)? ([0-9]+)? ('.' [0-9]+)?
33  Species <- BaseSpecies State? Charge?
34  BaseSpecies <- [a-zA-Z][a-zA-Z0-9_]*
35  State <- '(' [a-z]{1,3} ')'
36  Charge <- ('^'? [0-9]* [+-])
37  Metadata <- '[' _ Pair (_ ',' _ Pair)* _ ']'
38  Pair <- Key _ '=' _ Value
39  Key <- [A-Za-z_][A-Za-z0-9_]*
40  Value <- [A-Za-z0-9_.-]+
41  Newline <- [\r\n]+
42  ~_ <- [ \t]*
43  )");
44  mooseAssert(parser, "Failed to build parser");
45 
46  // Rules for how to parse each type
47  parser["Reactions"] = [](const SemanticValues & vs)
48  {
49  std::vector<Reaction> reactions;
50  for (const auto & v : vs)
51  {
52  if (v.type() == typeid(Reaction))
53  {
54  reactions.push_back(std::any_cast<Reaction>(v));
55  }
56  }
57  return reactions;
58  };
59 
60  parser["Float"] = [](const SemanticValues & vs)
61  {
62  // We need to remove whitespace in case the reaction was A - B -> C
63  std::string vs_str = std::string(std::any_cast<std::string_view>(vs.token()));
64  vs_str.erase(std::remove(vs_str.begin(), vs_str.end(), ' '), vs_str.end());
65  if (vs_str == "-")
66  return -1.;
67  else if (vs_str == "+" || vs_str == "")
68  return 1.;
69  else
70  return std::stod(std::string(vs_str));
71  };
72 
73  parser["Coefficient"] = [](const SemanticValues & vs) { return std::any_cast<double>(vs[0]); };
74 
75  parser["BaseSpecies"] = [](const SemanticValues & vs) { return vs.token(); };
76 
77  parser["State"] = [](const SemanticValues & vs) { return vs.token(); };
78 
79  parser["Charge"] = [](const SemanticValues & vs) { return vs.token(); };
80 
81  parser["Species"] = [](const SemanticValues & vs)
82  {
83  std::string base = std::string(std::any_cast<std::string_view>(vs[0]));
84  std::optional<std::string> state;
85  std::optional<std::string> charge;
86 
87  // Parse the state and charge
88  if (vs.size() >= 2)
89  {
90  for (size_t i = 1; i < vs.size(); ++i)
91  if (vs[i].type() == typeid(std::string_view))
92  {
93  std::string val = std::string(std::any_cast<std::string_view>(vs[i]));
94  if (val.front() == '(' && val.back() == ')')
95  state = val;
96  else
97  charge = val;
98  }
99  }
100 
101  return Term{1.0, base, state, charge}; // default coefficient = 1.0
102  };
103 
104  parser["Term"] = [](const SemanticValues & vs)
105  {
106  mooseAssert(vs.size() <= 2, "Should only have a coefficient and a species");
107  if (vs.size() == 2)
108  {
109  double coeff = std::any_cast<double>(vs[0]);
110  Term term = std::any_cast<Term>(vs[1]);
111  term.coefficient = coeff;
112  return term;
113  }
114  else
115  return std::any_cast<Term>(vs[0]);
116  };
117 
118  parser["TermList"] = [](const SemanticValues & vs)
119  {
120  TermList terms;
121  for (const auto & v : vs)
122  {
123  // One term
124  if (v.type() == typeid(Term))
125  terms.push_back(std::any_cast<Term>(v));
126  // Multiple terms
127  else if (v.type() == typeid(std::vector<Term>))
128  {
129  const auto & more = std::any_cast<std::vector<Term>>(v);
130  terms.insert(terms.end(), more.begin(), more.end());
131  }
132  }
133  return terms;
134  };
135 
136  // Leaf types can just use 'vs.token()'
137  parser["Key"] = [](const SemanticValues & vs) { return vs.token(); };
138 
139  parser["Value"] = [](const SemanticValues & vs) { return vs.token(); };
140 
141  parser["Pair"] = [](const SemanticValues & vs)
142  {
143  mooseAssert(vs.size() == 2, "Metadata entry should have exactly one key and one value");
144  return std::make_pair(std::string(std::any_cast<std::string_view>(vs[0])),
145  std::string(std::any_cast<std::string_view>(vs[1])));
146  };
147 
148  parser["Metadata"] = [](const SemanticValues & vs)
149  {
150  Metadata meta;
151  for (const auto & v : vs)
152  {
153  if (v.type() == typeid(std::pair<std::string, std::string>))
154  {
155  const auto & [k, val] = std::any_cast<std::pair<std::string, std::string>>(v);
156  meta[k] = val;
157  }
158  else if (v.type() == typeid(std::vector<std::pair<std::string, std::string>>))
159  {
160  const auto & pairs = std::any_cast<std::vector<std::pair<std::string, std::string>>>(v);
161  for (const auto & [k, val] : pairs)
162  meta[k] = val;
163  }
164  }
165  return meta;
166  };
167 
168  parser["Reaction"] = [](const SemanticValues & vs)
169  {
170  Reaction r;
171  if (vs.size() != 2 && vs.size() != 3)
172  mooseError("Reaction failed to read as 'reactors -> products [metadata]");
173  r.reactants = std::any_cast<TermList>(vs[0]);
174  r.products = std::any_cast<TermList>(vs[1]);
175  if (vs.size() == 3)
176  r.metadata = std::any_cast<Metadata>(vs[2]);
177  return r;
178  };
179 
180  parser.enable_packrat_parsing();
181 
182  std::vector<Reaction> reactions;
183  if (!parser.parse(reaction_network_string, reactions))
184  mooseError("Failed to parse reaction.");
185 
186  // Output the reaction network
187  if (output_to_cout)
188  {
189  for (size_t i = 0; i < reactions.size(); ++i)
190  {
191  const auto & r = reactions[i];
192  Moose::out << "Reaction " << i + 1 << ":\n";
193  Moose::out << Moose::stringify(r) << std::endl;
194  }
195  }
196 
197  return reactions;
198 }
std::vector< Term > TermList
std::map< std::string, std::string > Metadata
void mooseError(Args &&... args)
const double v
std::string stringify(const T &t)
static const std::string k
Definition: NS.h:134