Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add residual parts of GERG-2004 and GERG-2008 #79

Merged
merged 9 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
960 changes: 960 additions & 0 deletions include/teqp/models/GERG/GERG.hpp

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions include/teqp/models/fwd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "teqp/models/model_potentials/2center_ljf.hpp"
#include "teqp/models/mie/lennardjones.hpp"
#include "teqp/models/mie/mie.hpp"
#include "teqp/models/GERG/GERG.hpp"

namespace teqp {

Expand Down
3 changes: 3 additions & 0 deletions interface/CPP/teqp_impl_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ namespace teqp {
{"2CLJF-Quadrupole", [](const nlohmann::json& spec){ return make_owned(twocenterljf::build_two_center_model_quadrupole(spec.at("author"), spec.at("L^*"), spec.at("(Q^*)^2")));}},
{"IdealHelmholtz", [](const nlohmann::json& spec){ return make_owned(IdealHelmholtz(spec));}},

{"GERG2004resid", [](const nlohmann::json& spec){ return make_owned(GERG2004::GERG2004ResidualModel(spec.at("names")));}},
{"GERG2008resid", [](const nlohmann::json& spec){ return make_owned(GERG2008::GERG2008ResidualModel(spec.at("names")));}},

// Implemented in its own compilation unit to help with compilation time
{"SAFT-VR-Mie", [](const nlohmann::json& spec){ return make_SAFTVRMie(spec); }}
};
Expand Down
22 changes: 22 additions & 0 deletions interface/pybind11_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ void attach_multifluid_methods(py::object&obj){
setattr("set_meta", MethodType(py::cpp_function([](py::object& o, const std::string& s){ return get_mutable_typed<TYPE>(o).set_meta(s); }, "self"_a, "s"_a), obj));
setattr("get_alpharij", MethodType(py::cpp_function([](py::object& o, const int i, const int j, const double tau, const double delta){ return get_typed<TYPE>(o).dep.get_alpharij(i,j,tau,delta); }, "self"_a, "i"_a, "j"_a, "tau"_a, "delta"_a), obj));
}
template<typename TYPE>
void attach_GERG_methods(py::object&obj){
auto setattr = py::getattr(obj, "__setattr__");
auto MethodType = py::module_::import("types").attr("MethodType");
setattr("get_Tcvec", MethodType(py::cpp_function([](py::object& o){ return get_typed<TYPE>(o).red.get_Tcvec(); }), obj));
setattr("get_vcvec", MethodType(py::cpp_function([](py::object& o){ return get_typed<TYPE>(o).red.get_vcvec(); }), obj));
setattr("get_Tr", MethodType(py::cpp_function([](py::object& o, REArrayd& molefrac){ return get_typed<TYPE>(o).red.get_Tr(molefrac); }, "self"_a, "molefrac"_a.noconvert()), obj));
setattr("get_rhor", MethodType(py::cpp_function([](py::object& o, REArrayd& molefrac){ return get_typed<TYPE>(o).red.get_rhor(molefrac); }, "self"_a, "molefrac"_a.noconvert()), obj));
// setattr("get_meta", MethodType(py::cpp_function([](py::object& o){ return get_typed<TYPE>(o).get_meta(); }), obj));
// setattr("set_meta", MethodType(py::cpp_function([](py::object& o, const std::string& s){ return get_mutable_typed<TYPE>(o).set_meta(s); }, "self"_a, "s"_a), obj));
// setattr("get_alpharij", MethodType(py::cpp_function([](py::object& o, const int i, const int j, const double tau, const double delta){ return get_typed<TYPE>(o).dep.get_alpharij(i,j,tau,delta); }, "self"_a, "i"_a, "j"_a, "tau"_a, "delta"_a), obj));
}

// Type index variables matching the model types, used for runtime attachment of model-specific methods
const std::type_index vdWEOS1_i{std::type_index(typeid(vdWEOS1))};
Expand All @@ -111,6 +123,8 @@ const std::type_index twocenterLJF_i{std::type_index(typeid(twocenterLJF_t))};
const std::type_index QuantumPR_i{std::type_index(typeid(QuantumPR_t))};
const std::type_index advancedPRaEres_i{std::type_index(typeid(advancedPRaEres_t))};
const std::type_index RKPRCismondi2005_i{std::type_index(typeid(RKPRCismondi2005_t))};
const std::type_index GERG2004ResidualModel_i{std::type_index(typeid(GERG2004::GERG2004ResidualModel))};
const std::type_index GERG2008ResidualModel_i{std::type_index(typeid(GERG2008::GERG2008ResidualModel))};

/**
At runtime we can add additional model-specific methods that only apply for a particular model. We take in a Python-wrapped
Expand Down Expand Up @@ -155,10 +169,12 @@ void attach_model_specific_methods(py::object& obj){
setattr("get_epsilon_over_k_K", MethodType(py::cpp_function([](py::object& o){ return get_typed<SAFTVRMie_t>(o).get_epsilon_over_k_K(); }), obj));
setattr("get_lambda_r", MethodType(py::cpp_function([](py::object& o){ return get_typed<SAFTVRMie_t>(o).get_lambda_r(); }), obj));
setattr("get_lambda_a", MethodType(py::cpp_function([](py::object& o){ return get_typed<SAFTVRMie_t>(o).get_lambda_a(); }), obj));

// setattr("max_rhoN", MethodType(py::cpp_function([](py::object& o, double T, REArrayd& molefrac){ return get_typed<SAFTVRMie_t>(o).max_rhoN(T, molefrac); }, "self"_a, "T"_a, "molefrac"_a), obj));
setattr("get_kmat", MethodType(py::cpp_function([](py::object& o){ return get_typed<SAFTVRMie_t>(o).get_kmat(); }), obj));
setattr("has_polar", MethodType(py::cpp_function([](py::object& o){ return get_typed<SAFTVRMie_t>(o).has_polar(); }), obj));
setattr("get_core_calcs", MethodType(py::cpp_function([](py::object& o, double T, double rhomolar, REArrayd& molefrac){ return get_typed<SAFTVRMie_t>(o).get_core_calcs(T, rhomolar, molefrac); }, "self"_a, "T"_a, "rhomolar"_a, "molefrac"_a), obj));

}
else if (index == canonical_cubic_i){
setattr("get_a", MethodType(py::cpp_function([](py::object& o, double T, REArrayd& molefrac){ return get_typed<canonical_cubic_t>(o).get_a(T, molefrac); }, "self"_a, "T"_a, "molefrac"_a), obj));
Expand Down Expand Up @@ -230,6 +246,12 @@ void attach_model_specific_methods(py::object& obj){
return teqp::MultiFluidVLEAncillaries(jancillaries);
}, "self"_a, py::arg_v("i", std::nullopt, "None")), obj));
}
else if (index == GERG2004ResidualModel_i){
attach_GERG_methods<GERG2004::GERG2004ResidualModel>(obj);
}
else if (index == GERG2008ResidualModel_i){
attach_GERG_methods<GERG2008::GERG2008ResidualModel>(obj);
}
else if (index == idealgas_i){
// Here X-Macros are used to create functions like get_Aig00, get_Aig01, ....
#define X(i,j) setattr(stringify(get_Aig ## i ## j), MethodType(py::cpp_function([](py::object& o, double T, double rho, REArrayd& molefrac){ \
Expand Down
65 changes: 65 additions & 0 deletions src/bench_AbstractModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,23 @@
#include "teqp/derivs.hpp"
#include "teqp/cpp/deriv_adapter.hpp"
#include "teqp/models/multifluid.hpp"
#include "teqp/models/GERG/GERG.hpp"

using namespace teqp;

TEST_CASE("GERG2008 parts", "[GERG2008]")
{
BENCHMARK("bg"){
return GERG2008::get_betasgammas("methane","n-decane");
};
BENCHMARK("bg backwards"){
return GERG2008::get_betasgammas("n-decane", "methane");
};
BENCHMARK("bg fallback to 2004"){
return GERG2008::get_betasgammas("ethane", "methane");
};
}

TEST_CASE("multifluid derivatives", "[mf]")
{
nlohmann::json j = {
Expand All @@ -25,6 +39,9 @@ TEST_CASE("multifluid derivatives", "[mf]")
auto z = (Eigen::ArrayXd(1) << 1.0).finished();
auto rhovec = 300.0* z;

BENCHMARK("construction"){
return teqp::cppinterface::make_model(j);
};
BENCHMARK("alphar") {
return am->get_Arxy(0, 0, 300, 3.0, z);
};
Expand Down Expand Up @@ -84,3 +101,51 @@ TEST_CASE("multifluid derivatives via DerivativeAdapter", "[mf]")
return view(model)->get_Bnvir(4, 300, z);
};
}


TEST_CASE("GERG2008 derivatives", "[GERG2008]")
{
nlohmann::json j = {
{"kind", "GERG2008resid"},
{"model", {
{"names", {"methane","ethane","propane","n-butane"}},
}
}};
//std::cout << j.dump(2);


auto z = (Eigen::ArrayXd(1) << 1.0).finished();
auto rhovec = 300.0* z;
auto am = teqp::cppinterface::make_model(j);

BENCHMARK("construction"){
return teqp::cppinterface::make_model(j);
};
BENCHMARK("alphar") {
return am->get_Arxy(0, 0, 300, 3.0, z);
};
BENCHMARK("Ar20") {
return am->get_Ar20(300, 3.0, z);
};
BENCHMARK("get_Ar02n") {
return am->get_Ar02n(300, 3.0, z);
};
BENCHMARK("fugacity coefficients") {
return am->get_fugacity_coefficients(300.0, rhovec);
};
BENCHMARK("cvr/R") {
return -1*am->get_Arxy(2, 0, 300, 3.0, z);
};
BENCHMARK("partial_molar_volumes") {
return am->get_partial_molar_volumes(300.0, rhovec);
};
BENCHMARK("get_deriv_mat2") {
return am->get_deriv_mat2(300.0, 3.0, z);
};
BENCHMARK("build_iteration_Jv") {
auto mat = am->get_deriv_mat2(300.0, 3.0, z);
auto mat2 = am->get_deriv_mat2(300.0, 3.0, z);
const std::vector<char> vars = {'T','D','P','S'};
return teqp::cppinterface::build_iteration_Jv(vars, mat, mat2, 8.3144, 300.0, 300.0, z);
};
}
Loading
Loading