#include <catch2/catch_test_macros.hpp> #include <catch2/benchmark/catch_benchmark_all.hpp> #include <catch2/generators/catch_generators.hpp> // Only this file gets the implementation #define REFPROP_IMPLEMENTATION #define REFPROP_FUNCTION_MODIFIER #include "REFPROP_lib.h" #undef REFPROP_FUNCTION_MODIFIER #undef REFPROP_IMPLEMENTATION #include <stdlib.h> #include <stdio.h> #include <chrono> #include <iostream> #include <valarray> #include <random> #include <numeric> #include <stringstream> #include "teqp/models/multifluid.hpp" #include "teqp/derivs.hpp" using namespace teqp; static bool loaded_refprop = false; void init_REFPROP() { if (loaded_refprop) { return; } // you may need to change this path to suit your installation // note: forward-slashes are recommended. std::string path = std::getenv("rpprefix"); std::string dll_name = ""; // load the shared library and set up the fluid std::string err; loaded_refprop = load_REFPROP(err, path, dll_name); printf("loaded refprop: %s @ address %zu\n", loaded_refprop ? "true" : "false", REFPROP_address()); { char hpath[256] = " "; strcpy(hpath, const_cast<char*>(path.c_str())); SETPATHdll(hpath, 255); } // Try to disable caching in REFPROP { int ierr = 0; char herr[256]; char hflag[256] = "Cache "; int jFlag = 3, kFlag = -1; FLAGSdll(hflag, jFlag, kFlag, ierr, herr, 255, 255); //std::cout << kFlag << std::endl; } } TEST_CASE("Time fugacity coefficient"){ init_REFPROP(); // Implicit sections are built for each number of Ncomp auto Ncomp = GENERATE(1,2,3,4,5,6); double T = 300, D_moldm3 = 3, D_molm3 = D_moldm3*1e3; // Setup teqp model std::vector<std::string> component_list = { "Methane","Ethane","n-Propane","n-Butane","n-Pentane","n-Hexane" }; std::vector<std::string> fluid_set(component_list.begin(), component_list.begin() + Ncomp); auto model = build_multifluid_model(fluid_set, "../mycp", "../mycp/dev/mixtures/mixture_binary_pairs.json"); using id = IsochoricDerivatives<decltype(model), double>; auto rhovec = (D_molm3*Eigen::ArrayXd::Ones(Ncomp)/Ncomp).eval(); auto setup_REFPROP = [&]() { // Initialize the model { std::string name = fluid_set[0]; for (auto j = 1; j < fluid_set.size(); ++j) { name += "*" + fluid_set[j]; } int ierr = 0, nc = Ncomp; char herr[256] = " ", hfld[10001] = " ", hhmx[256] = "HMX.BNC", href[4] = "DEF"; #if defined(USE_TEQP_HMX) std::string rhs = std::string("./teqpHMX.BNC") + "\0"; strncpy(hhmx, rhs.c_str(), rhs.size()); #endif strcpy(hfld, (name + "\0").c_str()); SETUPdll(nc, hfld, hhmx, href, ierr, herr, 10000, 255, 3, 255); if (ierr != 0) { printf("This ierr: %d herr: %s\n", ierr, herr); } } }; setup_REFPROP(); std::valarray<double> z(20); z = 0.0; z[std::slice(0, Ncomp, 1)] = 1.0 / Ncomp; std::valarray<double> u(20); u = 0.0; int ierr = 0; char herr[256]; SECTION("same") { FUGCOFdll(T, D_moldm3, &(z[0]), &(u[0]), ierr, herr, 255); auto phiteqp = id::template get_fugacity_coefficients(model, T, rhovec); auto diff = (phiteqp - Eigen::Map<const Eigen::ArrayXd>(&(u[0]), phiteqp.size())).eval(); REQUIRE(diff.abs().minCoeff() < 1e-13); }; std::ostringstream ssteqp; ssteqp << Ncomp; BENCHMARK("teqp" + ssteqp.str()) { CAPTURE(Ncomp); return id::template get_fugacity_coefficients(model, T, rhovec); }; BENCHMARK("REFPROP" + ssteqp.str()) { CAPTURE(Ncomp); FUGCOFdll(T, D_moldm3, &(z[0]), &(u[0]), ierr, herr, 255); return u; }; }