Reaktoro  v2.11.0
A unified framework for modeling chemically reactive systems
Model.hpp
1 // Reaktoro is a unified framework for modeling chemically reactive systems.
2 //
3 // Copyright © 2014-2024 Allan Leal
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with this library. If not, see <http://www.gnu.org/licenses/>.
17 
18 #pragma once
19 
20 // Reaktoro includes
21 #include <Reaktoro/Common/Algorithms.hpp>
22 #include <Reaktoro/Common/Memoization.hpp>
23 #include <Reaktoro/Common/TraitsUtils.hpp>
24 #include <Reaktoro/Common/Types.hpp>
25 #include <Reaktoro/Core/Data.hpp>
26 
27 namespace Reaktoro {
28 
29 template<typename Signature>
30 class Model;
31 
33 template<typename ResultRef, typename... Args>
34 using ModelEvaluator = Fn<void(ResultRef res, Args... args)>;
35 
37 template<typename Result, typename... Args>
38 using ModelCalculator = Fn<Result(Args... args)>;
39 
42 template<typename Result, typename... Args>
43 class Model<Result(Args...)>
44 {
45 public:
49  using ResultRef = Ref<Result>;
50 
53  {}
54 
58  Model(const ModelEvaluator<ResultRef, Args...>& evalfn, const Data& params = {})
59  : m_params(params)
60  {
61  assert(evalfn);
62 
63  m_evalfn = [evalfn](ResultRef res, const Args&... args)
64  {
65  evalfn(res, args...);
66  };
67 
68  m_calcfn = [evalfn](const Args&... args) -> Result
69  {
70  Result res;
71  evalfn(res, args...);
72  return res;
73  };
74  }
75 
79  Model(const ModelCalculator<Result, Args...>& calcfn, const Data& params = {})
80  : m_params(params)
81  {
82  assert(calcfn);
83 
84  m_evalfn = [calcfn](ResultRef res, const Args&... args)
85  {
86  res = calcfn(args...);
87  };
88 
89  m_calcfn = [calcfn](const Args&... args) -> Result
90  {
91  return calcfn(args...);
92  };
93  }
94 
101  template<typename Fun, Requires<!isFunction<Fun>> = true>
102  Model(const Fun& f)
103  : Model(std::function(f))
104  {}
105 
107  auto withMemoization() const -> Model
108  {
109  Model copy = *this;
110  copy.m_evalfn = memoizeLastUsingRef<Result>(copy.m_evalfn); // Here, `m_evalfn` is memoized in case it is called multiple times with the same arguments and parameters.
111  copy.m_calcfn = memoizeLast(copy.m_calcfn); // Here, `m_calcfn` is memoized in case it is called multiple times with the same arguments and parameters.
112  return copy;
113  }
114 
116  auto apply(ResultRef res, const Args&... args) const -> void
117  {
118  errorifnot(m_evalfn, "Model evaluator function object has not been initialized.");
119  m_evalfn(res, args...);
120  }
121 
123  auto operator()(const Args&... args) const -> Result
124  {
125  errorifnot(m_calcfn, "Model calculator function object has not been initialized.");
126  return m_calcfn(args...);
127  }
128 
130  auto operator()(ResultRef res, const Args&... args) const -> void
131  {
132  apply(res, args...);
133  }
134 
136  auto initialized() const -> bool
137  {
138  return m_evalfn != nullptr;
139  }
140 
142  operator bool() const
143  {
144  return initialized();
145  }
146 
148  auto evaluatorFn() const -> const ModelEvaluator<ResultRef, Args...>&
149  {
150  return m_evalfn;
151  }
152 
154  auto calculatorFn() const -> const ModelCalculator<Result, Args...>&
155  {
156  return m_calcfn;
157  }
158 
160  auto params() const -> const Data&
161  {
162  return m_params;
163  }
164 
167  static auto Constant(String const& name, real const& value) -> Model
168  {
169  auto calcfn = [value](const Args&... args) -> real { return value; }; // the constant model is a simple function that always return the given constant value
170  Data params;
171  params[name]["Value"] = value; //
172  return Model(calcfn, params);
173  }
174 
175 private:
177  ModelEvaluator<ResultRef, Args...> m_evalfn;
178 
180  ModelCalculator<Result, Args...> m_calcfn;
181 
183  Data m_params;
184 };
185 
187 template<typename Result, typename... Args>
188 auto chain(const Vec<Model<Result(Args...)>>& models) -> Model<Result(Args...)>
189 {
190  using ResultRef = Ref<Result>;
191 
192  const auto evalfns = vectorize(models, RKT_LAMBDA(model, model.evaluatorFn()));
193 
194  auto evalfn = [=](ResultRef res, const Args&... args)
195  {
196  for(auto i = 0; i < evalfns.size(); ++i)
197  evalfns[i](res, args...);
198  };
199 
200  Data params;
201  for(auto const& model : models)
202  params.add(model.params());
203 
204  return Model<Result(Args...)>(evalfn, params);
205 }
206 
208 template<typename Signature>
210 {
211  return model;
212 }
213 
215 template<typename Result, typename... Args, typename... Models>
216 auto chain(const Model<Result(Args...)>& model, const Models&... models) -> Model<Result(Args...)>
217 {
218  Vec<Model<Result(Args...)>> vec = {model, models...};
219  return chain(vec);
220 }
221 
222 } // namespace Reaktoro
The class used to store and retrieve data for assemblying chemical systems.
Definition: Data.hpp:30
auto add(Data data) -> void
Add a Data object to this Data object, which becomes a list if not already.
Model(const Fun &f)
Construct a Model function object with either a model evaluator or a model calculator function.
Definition: Model.hpp:102
Ref< Result > ResultRef
The reference type of result type.
Definition: Model.hpp:49
auto initialized() const -> bool
Return true if this Model function object has been initialized.
Definition: Model.hpp:136
auto operator()(const Args &... args) const -> Result
Evaluate the model with given arguments and return the result of the evaluation.
Definition: Model.hpp:123
Model()
Construct a default Model function object.
Definition: Model.hpp:52
auto evaluatorFn() const -> const ModelEvaluator< ResultRef, Args... > &
Return the model evaluator function of this Model function object.
Definition: Model.hpp:148
Model(const ModelEvaluator< ResultRef, Args... > &evalfn, const Data &params={})
Construct a Model function object with given model evaluator function and its parameters.
Definition: Model.hpp:58
auto withMemoization() const -> Model
Return a new Model function object with memoization for the model calculator.
Definition: Model.hpp:107
auto params() const -> const Data &
Return the model parameters of this Model function object.
Definition: Model.hpp:160
auto calculatorFn() const -> const ModelCalculator< Result, Args... > &
Return the model calculator function of this Model function object.
Definition: Model.hpp:154
static auto Constant(String const &name, real const &value) -> Model
Return a constant Model function object.
Definition: Model.hpp:167
auto operator()(ResultRef res, const Args &... args) const -> void
Evaluate the model with given arguments and return the result of the evaluation.
Definition: Model.hpp:130
auto apply(ResultRef res, const Args &... args) const -> void
Evaluate the model with given arguments.
Definition: Model.hpp:116
Model(const ModelCalculator< Result, Args... > &calcfn, const Data &params={})
Construct a Model function object with given direct model calculator and its parameters.
Definition: Model.hpp:79
Definition: Model.hpp:30
#define errorifnot(condition,...)
Define a macro to raise a runtime exception if an expected condition is not true.
Definition: Exception.hpp:149
The namespace containing all components of the Reaktoro library.
Definition: Algorithms.hpp:29
std::vector< T > Vec
Convenient alias for std::vector<T>.
Definition: Types.hpp:66
Fn< Result(Args... args)> ModelCalculator
The functional signature of functions that calculates properties.
Definition: Model.hpp:38
auto memoizeLast(Fn< Ret(Args...)> f) -> Fn< Ret(Args...)>
Return a memoized version of given function f that caches only the arguments used in the last call.
Definition: Memoization.hpp:167
auto chain(const Vec< ActivityModelGenerator > &models) -> ActivityModelGenerator
Return an activity model resulting from chaining other activity models.
std::string String
Convenient alias for std::string.
Definition: Types.hpp:52
autodiff::real real
The number type used throughout the library.
Definition: Real.hpp:26
auto vectorize(const Container &c, const Function &f)
Return a vector by applying function f on every item in container c.
Definition: Algorithms.hpp:135
std::function< F > Fn
Convenient alias for std::function<R(Args...)>.
Definition: Types.hpp:110
Fn< void(ResultRef res, Args... args)> ModelEvaluator
The functional signature of functions that evaluates properties.
Definition: Model.hpp:34