diff --git a/CMakeLists.txt b/CMakeLists.txt index 9278fff2f93968e5a66bc3d4099b37c64c4b9fd2..463f282dd18680402fd211b7365fbc339d7d5c26 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,7 +84,9 @@ target_link_libraries(teqpcpp PUBLIC teqpinterface PUBLIC autodiff) if (TEQP_TESTTEQPCPP) add_executable(test_teqpcpp "${CMAKE_CURRENT_SOURCE_DIR}/interface/CPP/test_teqpcpp.cpp") - target_link_libraries(test_teqpcpp PUBLIC teqpcpp PRIVATE Catch2WithMain) + target_link_libraries(test_teqpcpp PUBLIC teqpcpp) + add_executable(bench_teqpcpp "${CMAKE_CURRENT_SOURCE_DIR}/interface/CPP/bench_teqpcpp.cpp") + target_link_libraries(bench_teqpcpp PUBLIC teqpcpp PRIVATE Catch2WithMain) endif() if (TEQP_JAVASCRIPT_MODULE) diff --git a/interface/CPP/bench_teqpcpp.cpp b/interface/CPP/bench_teqpcpp.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3acb69efb1398556a4fd6c1814599124f437b566 --- /dev/null +++ b/interface/CPP/bench_teqpcpp.cpp @@ -0,0 +1,46 @@ +#include <catch2/catch_test_macros.hpp> +#include <catch2/benchmark/catch_benchmark_all.hpp> + +#include "teqpcpp.hpp" + +using namespace teqp::cppinterface; + +#include "teqp/derivs.hpp" + +using namespace teqp; + +TEST_CASE("Test C++ interface", "[C++]") +{ + auto modelnovar = teqp::build_multifluid_model({ "Methane","Ethane" }, "../mycp"); + teqp::AllowedModels model = modelnovar; + auto z = (Eigen::ArrayXd(2) << 0.5, 0.5).finished(); + SECTION("Ar01") { + double Ar01 = get_Arxy(model, 0, 1, 300, 3, z); + } + SECTION("critical trace") { + double Tc1 = modelnovar.redfunc.Tc(0); + auto rhovec0 = (Eigen::ArrayXd(2) << 1/modelnovar.redfunc.vc(0), 0).finished(); + auto cr = trace_critical_arclength_binary(model, Tc1, rhovec0); + std::cout << cr.dump(1) << std::endl; + } +} + +TEST_CASE("Benchmark C++ interface", "[C++]") +{ + teqp::AllowedModels model = teqp::build_multifluid_model({ "Methane", "Ethane"}, "../mycp"); + auto z = (Eigen::ArrayXd(2) << 0.5, 0.5).finished(); + + auto model1novar = teqp::build_multifluid_model({ "Methane" }, "../mycp"); + teqp::AllowedModels model1 = model1novar; + auto z1 = (Eigen::ArrayXd(1) << 1).finished(); + + BENCHMARK("Ar01 two components") { + return get_Arxy(model, 0, 1, 300, 3, z); + }; + BENCHMARK("Ar01 one component w/ Arxy (runtime lookup)") { + return get_Arxy(model1, 0, 1, 300, 3, z1); + }; + BENCHMARK("Ar01 one component w/ Ar01 directly") { + return TDXDerivatives<decltype(model1novar)>::get_Arxy<0,1,ADBackends::autodiff>(model1novar, 300, 3, z1); + }; +} diff --git a/interface/CPP/teqpcpp.cpp b/interface/CPP/teqpcpp.cpp index 331bcd6872fa28e7da489e4a72084a2d3d1804f0..4706160cf9d9eb31aba3d5e05bacb1baa4a31241 100644 --- a/interface/CPP/teqpcpp.cpp +++ b/interface/CPP/teqpcpp.cpp @@ -1,20 +1,17 @@ -// Pulls in the AllowedModels variant #include "teqp/models/fwd.hpp" #include "teqpcpp.hpp" #include "teqp/derivs.hpp" #include "teqp/algorithms/critical_tracing.hpp" -double teqp::cppinterface::get_Arxy(const void* modelptr, const int NT, const int ND, const double T, const double rho, const Eigen::ArrayXd &molefracs){ - const teqp::AllowedModels& model = *static_cast<const teqp::AllowedModels*>(modelptr); +double teqp::cppinterface::get_Arxy(const teqp::AllowedModels& model, const int NT, const int ND, const double T, const double rho, const Eigen::ArrayXd &molefracs){ return std::visit([&](const auto& model) { using tdx = teqp::TDXDerivatives<decltype(model), double, std::decay_t<decltype(molefracs)>>; return tdx::template get_Ar(NT, ND, model, T, rho, molefracs); }, model); } -nlohmann::json teqp::cppinterface::trace_critical_arclength_binary(const void* modelptr, const double T0, const Eigen::ArrayXd &rhovec0) { - const teqp::AllowedModels& model = *static_cast<const teqp::AllowedModels*>(modelptr); +nlohmann::json teqp::cppinterface::trace_critical_arclength_binary(const teqp::AllowedModels& model, const double T0, const Eigen::ArrayXd &rhovec0) { return std::visit([&](const auto& model) { using crit = teqp::CriticalTracing<decltype(model), double, std::decay_t<decltype(rhovec0)>>; return crit::trace_critical_arclength_binary(model, T0, rhovec0, ""); diff --git a/interface/CPP/teqpcpp.hpp b/interface/CPP/teqpcpp.hpp index 628c847181e61eca874034cd3f59ba77fd540886..2b0de35b1087d6fb717e43db0478f7a297deff69 100644 --- a/interface/CPP/teqpcpp.hpp +++ b/interface/CPP/teqpcpp.hpp @@ -3,11 +3,14 @@ #include <Eigen/Dense> #include "nlohmann/json.hpp" +// Pulls in the AllowedModels variant +#include "teqp/models/fwd.hpp" + namespace teqp { namespace cppinterface { // Wrapper functions - double get_Arxy(const void* model, const int NT, const int ND, const double T, const double rho, const Eigen::ArrayXd& molefracs); - nlohmann::json trace_critical_arclength_binary(const void* model, const double T0, const Eigen::ArrayXd& rhovec0); + double get_Arxy(const teqp::AllowedModels& model, const int NT, const int ND, const double T, const double rho, const Eigen::ArrayXd& molefracs); + nlohmann::json trace_critical_arclength_binary(const teqp::AllowedModels& model, const double T0, const Eigen::ArrayXd& rhovec0); } } \ No newline at end of file diff --git a/interface/CPP/test_teqpcpp.cpp b/interface/CPP/test_teqpcpp.cpp index 2644aca16ab4f8641c78a505db0a869adfecddd4..326ed775774069ba7f41a7d57e303298de96f9c0 100644 --- a/interface/CPP/test_teqpcpp.cpp +++ b/interface/CPP/test_teqpcpp.cpp @@ -1,49 +1,18 @@ -#include <catch2/catch_test_macros.hpp> -#include <catch2/benchmark/catch_benchmark_all.hpp> +/** +* This is a minimal example of the use of the C++ interface around teqp +* +* The point of the interface is to reduce compilation time, as compilation +* of this file should be MUCH faster than compilation with the full set of +* algorithms and models because the template instantiations are all included in the +* library that this file is linked against and the compiler does not need to resolve +* all the templates every time this file is compiled +*/ -#include "teqpcpp.hpp" - -using namespace teqp::cppinterface; - -// Pulls in the AllowedModels variant -#include "teqp/models/fwd.hpp" - -#include "teqp/derivs.hpp" -using namespace teqp; - -TEST_CASE("Test C++ interface", "[C++]") -{ - auto modelnovar = teqp::build_multifluid_model({ "Methane","Ethane" }, "../mycp"); - teqp::AllowedModels model = modelnovar; - auto z = (Eigen::ArrayXd(2) << 0.5, 0.5).finished(); - SECTION("Ar01") { - double Ar01 = get_Arxy(&model, 0, 1, 300, 3, z); - } - SECTION("critical trace") { - double Tc1 = modelnovar.redfunc.Tc(0); - auto rhovec0 = (Eigen::ArrayXd(2) << 1/modelnovar.redfunc.vc(0), 0).finished(); - auto cr = trace_critical_arclength_binary(&model, Tc1, z); - std::cout << cr.dump(1) << std::endl; - } -} +#include "teqpcpp.hpp" -TEST_CASE("Benchmark C++ interface", "[C++]") -{ - teqp::AllowedModels model = teqp::build_multifluid_model({ "Methane", "Ethane"}, "../mycp"); +int main() { + teqp::AllowedModels model = teqp::build_multifluid_model({ "Methane", "Ethane" }, "../mycp"); auto z = (Eigen::ArrayXd(2) << 0.5, 0.5).finished(); - - auto model1novar = teqp::build_multifluid_model({ "Methane" }, "../mycp"); - teqp::AllowedModels model1 = model1novar; - auto z1 = (Eigen::ArrayXd(1) << 1).finished(); - - BENCHMARK("Ar01 two components") { - return get_Arxy(&model, 0, 1, 300, 3, z); - }; - BENCHMARK("Ar01 one component w/ Arxy (runtime lookup)") { - return get_Arxy(&model1, 0, 1, 300, 3, z1); - }; - BENCHMARK("Ar01 one component w/ Ar01 directly") { - return TDXDerivatives<decltype(model1novar)>::get_Arxy<0,1,ADBackends::autodiff>(model1novar, 300, 3, z1); - }; -} + double Ar01 = teqp::cppinterface::get_Arxy(model, 0, 1, 300, 3, z); +} \ No newline at end of file