6#include "nlohmann/json.hpp"
11#include <boost/asio/thread_pool.hpp>
12#include <boost/asio/post.hpp>
19 template<
typename Model>
26#define stdstringify(s) std::string(#s)
28#define PVTNoniterativePoint_optionalfields X(T) X(rho_exp) X(p_exp)
30 #define X(field) std::optional<double> field;
34 Eigen::ArrayXd
z = (Eigen::ArrayXd(1) << 1.0).finished();
37 #define X(field) if (!field){ throw teqp::InvalidArgument("A field [" + stdstringify(field) + "] has not been initialized"); }
42 template<
typename Model>
45 double T_ =
T.value(), rho_ =
rho_exp.value();
46 auto Ar0n = model->get_Ar02n(T_, rho_,
z);
47 auto p = rho_*
R*T_*(1+Ar0n[1]);
48 auto dpdrho =
R*T_*(1 + 2*Ar0n[1] + Ar0n[2]);
53#define SatRhoLPPoint_optionalfields X(T) X(p_exp) X(rhoL_exp) X(rhoL_guess) X(rhoV_guess)
55 #define X(field) std::optional<double> field;
59 Eigen::ArrayXd
z = (Eigen::ArrayXd(1) << 1.0).finished();
62 #define X(field) if (!field){ throw teqp::InvalidArgument("A field [" + stdstringify(field) + "] has not been initialized"); }
67 template<
typename Model>
70 auto rhoL = rhoLrhoV[0];
71 auto p = rhoL*
R*
T.value()*(1+model->get_Ar01(
T.value(), rhoL,
z));
77#define SatRhoLPWPoint_optionalfields X(T) X(p_exp) X(rhoL_exp) X(w_exp) X(rhoL_guess) X(rhoV_guess) X(Ao20) X(M) X(R)
80 #define X(field) std::optional<double> field;
84 Eigen::ArrayXd
z = (Eigen::ArrayXd(1) << 1.0).finished();
87 #define X(field) if (!field){ throw teqp::InvalidArgument("A field [" + stdstringify(field) + "] has not been initialized"); }
92 template<
typename Model>
98 auto rhoL = rhoLrhoV[0];
100 auto Ar0n = model->get_Ar02n(
T.value(), rhoL,
z);
101 double Ar01 = Ar0n[1], Ar02 = Ar0n[2];
102 auto Ar11 = model->get_Ar11(
T.value(), rhoL,
z);
103 auto Ar20 = model->get_Ar20(
T.value(), rhoL,
z);
106 auto p = rhoL*
R.value()*
T.value()*(1+Ar01);
112 double Mw2RT = 1 + 2*Ar01 + Ar02 -
POW2(1.0 + Ar01 - Ar11)/(
Ao20.value() + Ar20);
113 double w = sqrt(Mw2RT*
R.value()*
T.value()/
M.value());
123#define SOSPoint_fields X(T) X(p_exp) X(rho_guess) X(w_exp) X(Ao20) X(M) X(R)
126 #define X(field) std::optional<double> field;
131 Eigen::ArrayXd
z = (Eigen::ArrayXd(1) << 1.0).finished();
134 #define X(field) if (!field){ throw teqp::InvalidArgument("A field [" + stdstringify(field) + "] has not been initialized"); }
139 template<
typename Model>
143 double R_ =
R.value();
144 double T_K_ =
T.value();
148 for (
auto step = 0; step < 10; ++step){
149 auto Ar0n = model->get_Ar02n(T_K_, rho,
z);
150 double Ar01 = Ar0n[1], Ar02 = Ar0n[2];
151 double pEOS = rho*R_*T_K_*(1+Ar01);
152 double dpdrho = R_*T_K_*(1 + 2*Ar0n[1] + Ar0n[2]);
153 double res = (pEOS-
p_exp.value())/
p_exp.value();
154 double dresdrho = dpdrho/
p_exp.value();
155 double change = -res/dresdrho;
156 if (std::abs(change/rho-1) < 1e-10 || abs(res) < 1e-12){
164 auto Ar0n = model->get_Ar02n(T_K_, rho,
z);
165 double Ar01 = Ar0n[1], Ar02 = Ar0n[2];
166 auto Ar11 = model->get_Ar11(T_K_, rho,
z);
167 auto Ar20 = model->get_Ar20(T_K_, rho,
z);
171 double Mw2RT = 1.0 + 2.0*Ar01 + Ar02 -
POW2(1.0 + Ar01 - Ar11)/(
Ao20.value() + Ar20);
172 double w = sqrt(Mw2RT*R_*T_K_/
M.value());
182 auto make_pointers(
const std::vector<std::variant<std::string, std::vector<std::string>>>& pointerstrs){
183 std::vector<std::vector<nlohmann::json::json_pointer>> pointers_;
184 for (
auto & pointer: pointerstrs){
185 if (std::holds_alternative<std::string>(pointer)){
186 const std::string& s= std::get<std::string>(pointer);
187 pointers_.emplace_back(1, nlohmann::json::json_pointer(s));
190 std::vector<nlohmann::json::json_pointer> buffer;
191 for (
const auto& s : std::get<std::vector<std::string>>(pointer)){
192 buffer.emplace_back(s);
194 pointers_.push_back(buffer);
201 std::vector<std::vector<nlohmann::json::json_pointer>>
pointers;
207 std::visit([](
const auto&c){c.check_fields();}, cont);
212 return std::vector<double>{1, 3};
221 nlohmann::json j =
jbase;
222 for (
auto i = 0; i < x.size(); ++i){
223 for (
const auto& ptr :
pointers[i]){
235 return std::make_tuple(std::move(model), helpers);
240 const auto [_model, _helpers] =
prepare(x);
241 const auto& model = _model;
242 const auto& helpers = _helpers;
245 cost += std::visit([&model](
const auto& c){
return c.calculate_contribution(model); }, contrib);
247 if (!std::isfinite(cost)){
255 boost::asio::thread_pool pool{Nthreads};
256 const auto [_model, _helpers] =
prepare(x);
257 const auto& model = _model;
258 const auto& helpers = _helpers;
262 auto& dest = buffer[i];
263 auto payload = [&model, &dest, contrib] (){
264 dest = std::visit([&model](
const auto& c){
return c.calculate_contribution(model); }, contrib);
265 if (!std::isfinite(dest)){ dest = 1e30; }
267 boost::asio::post(pool, payload);
std::vector< PureOptimizationContribution > contributions
const nlohmann::json jbase
auto prepare(const T &x) const
auto cost_function(const T &x) const
auto cost_function_threaded(const T &x, std::size_t Nthreads)
void add_one_contribution(const PureOptimizationContribution &cont)
nlohmann::json build_JSON(const T &x) const
auto prepare_helper_models(const auto &model) const
PureParameterOptimizer(const nlohmann::json jbase, const std::vector< std::variant< std::string, std::vector< std::string > > > &pointerstrs)
std::vector< std::vector< nlohmann::json::json_pointer > > pointers
std::variant< SatRhoLPoint, SatRhoLPPoint, SatRhoLPWPoint, SOSPoint, PVTNoniterativePoint > PureOptimizationContribution
std::unique_ptr< AbstractModel > make_model(const nlohmann::json &, bool validate=true)
#define PVTNoniterativePoint_optionalfields
#define SatRhoLPWPoint_optionalfields
#define SatRhoLPPoint_optionalfields
std::optional< double > T
std::optional< double > p_exp
std::optional< double > rho_exp
auto calculate_contribution(const Model &model) const
auto check_fields() const
std::optional< double > T
std::optional< double > M
auto calculate_contribution(const Model &model) const
std::optional< double > w_exp
std::optional< double > R
std::optional< double > rho_guess
auto check_fields() const
std::optional< double > Ao20
std::optional< double > p_exp
std::optional< double > T
std::optional< double > rhoL_exp
std::optional< double > rhoL_guess
auto check_fields() const
std::optional< double > rhoV_guess
auto calculate_contribution(const Model &model) const
std::optional< double > p_exp
std::optional< double > M
std::optional< double > rhoL_exp
std::optional< double > rhoL_guess
std::optional< double > T
auto check_fields() const
std::optional< double > rhoV_guess
std::optional< double > p_exp
std::optional< double > R
std::optional< double > w_exp
std::optional< double > Ao20
auto calculate_contribution(const Model &model) const
auto check_fields() const
auto calculate_contribution(const Model &model) const