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));
80#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)
83 #define X(field) std::optional<double> field;
87 Eigen::ArrayXd
z = (Eigen::ArrayXd(1) << 1.0).finished();
90 #define X(field) if (!field){ throw teqp::InvalidArgument("A field [" + stdstringify(field) + "] has not been initialized"); }
95 template<
typename Model>
101 auto rhoL = rhoLrhoV[0];
103 auto Ar0n = model->get_Ar02n(
T.value(), rhoL,
z);
104 double Ar01 = Ar0n[1], Ar02 = Ar0n[2];
105 auto Ar11 = model->get_Ar11(
T.value(), rhoL,
z);
106 auto Ar20 = model->get_Ar20(
T.value(), rhoL,
z);
109 auto p = rhoL*
R.value()*
T.value()*(1+Ar01);
115 double Mw2RT = 1 + 2*Ar01 + Ar02 -
POW2(1.0 + Ar01 - Ar11)/(
Ao20.value() + Ar20);
116 double w = sqrt(Mw2RT*
R.value()*
T.value()/
M.value());
126#define SOSPoint_fields X(T) X(p_exp) X(rho_guess) X(w_exp) X(Ao20) X(M) X(R)
129 #define X(field) std::optional<double> field;
134 Eigen::ArrayXd
z = (Eigen::ArrayXd(1) << 1.0).finished();
137 #define X(field) if (!field){ throw teqp::InvalidArgument("A field [" + stdstringify(field) + "] has not been initialized"); }
142 template<
typename Model>
146 double R_ =
R.value();
147 double T_K_ =
T.value();
151 for (
auto step = 0; step < 10; ++step){
152 auto Ar0n = model->get_Ar02n(T_K_, rho,
z);
153 double Ar01 = Ar0n[1], Ar02 = Ar0n[2];
154 double pEOS = rho*R_*T_K_*(1+Ar01);
155 double dpdrho = R_*T_K_*(1 + 2*Ar0n[1] + Ar0n[2]);
156 double res = (pEOS-
p_exp.value())/
p_exp.value();
157 double dresdrho = dpdrho/
p_exp.value();
158 double change = -res/dresdrho;
159 if (std::abs(change/rho-1) < 1e-10 || abs(res) < 1e-12){
167 auto Ar0n = model->get_Ar02n(T_K_, rho,
z);
168 double Ar01 = Ar0n[1], Ar02 = Ar0n[2];
169 auto Ar11 = model->get_Ar11(T_K_, rho,
z);
170 auto Ar20 = model->get_Ar20(T_K_, rho,
z);
174 double Mw2RT = 1.0 + 2.0*Ar01 + Ar02 -
POW2(1.0 + Ar01 - Ar11)/(
Ao20.value() + Ar20);
175 double w = sqrt(Mw2RT*R_*T_K_/
M.value());
185 auto make_pointers(
const std::vector<std::variant<std::string, std::vector<std::string>>>& pointerstrs){
186 std::vector<std::vector<nlohmann::json::json_pointer>> pointers_;
187 for (
auto & pointer: pointerstrs){
188 if (std::holds_alternative<std::string>(pointer)){
189 const std::string& s= std::get<std::string>(pointer);
190 pointers_.emplace_back(1, nlohmann::json::json_pointer(s));
193 std::vector<nlohmann::json::json_pointer> buffer;
194 for (
const auto& s : std::get<std::vector<std::string>>(pointer)){
195 buffer.emplace_back(s);
197 pointers_.push_back(buffer);
204 std::vector<std::vector<nlohmann::json::json_pointer>>
pointers;
210 std::visit([](
const auto&c){c.check_fields();}, cont);
215 return std::vector<double>{1, 3};
224 nlohmann::json j =
jbase;
225 for (
auto i = 0; i < x.size(); ++i){
226 for (
const auto& ptr :
pointers[i]){
238 return std::make_tuple(std::move(model), helpers);
243 const auto [_model, _helpers] =
prepare(x);
244 const auto& model = _model;
245 const auto& helpers = _helpers;
248 cost += std::visit([&model](
const auto& c){
return c.calculate_contribution(model); }, contrib);
250 if (!std::isfinite(cost)){
258 boost::asio::thread_pool pool{Nthreads};
259 const auto [_model, _helpers] =
prepare(x);
260 const auto& model = _model;
261 const auto& helpers = _helpers;
265 auto& dest = buffer[i];
266 auto payload = [&model, &dest, contrib] (){
267 dest = std::visit([&model](
const auto& c){
return c.calculate_contribution(model); }, contrib);
268 if (!std::isfinite(dest)){ dest = 1e30; }
270 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