From 6ca9bc0f1bc8d97762e35de9547dc969fb374565 Mon Sep 17 00:00:00 2001
From: Ian Bell <ian.bell@nist.gov>
Date: Fri, 5 Nov 2021 10:08:00 -0400
Subject: [PATCH] Add PCSAFT to JSON builder; move PCSAFT into its own
 namespace

---
 include/teqp/json_builder.hpp  | 13 ++++++++++---
 include/teqp/models/pcsaft.hpp | 22 +++++++++++++++++++++-
 interface/C/teqpc.cpp          | 22 +++++++++++++++++++++-
 interface/PCSAFT.cpp           |  2 ++
 src/bench.cpp                  |  1 +
 src/teqp_profile.cpp           |  1 +
 src/tests/catch_tests.cxx      |  1 +
 src/time_Ar0n.cpp              |  1 +
 8 files changed, 58 insertions(+), 5 deletions(-)

diff --git a/include/teqp/json_builder.hpp b/include/teqp/json_builder.hpp
index 0e1f4bc..d72ac70 100644
--- a/include/teqp/json_builder.hpp
+++ b/include/teqp/json_builder.hpp
@@ -3,14 +3,18 @@
 #include "teqp/models/vdW.hpp"
 #include "teqp/models/cubics.hpp"
 #include "teqp/models/CPA.hpp"
+#include "teqp/models/pcsaft.hpp"
 
 #include "nlohmann/json.hpp"
 
 using vad = std::valarray<double>;
-using cub = decltype(canonical_PR(vad{}, vad{}, vad{}));
-using cpatype = decltype(CPA::CPAfactory(nlohmann::json{})); // The type returned by the factory function
 
-using AllowedModels = std::variant<vdWEOS1, cub, cpatype>;
+// Define the EOS types by interrogating the types returned by the respective factory function
+using cub = decltype(canonical_PR(vad{}, vad{}, vad{})); 
+using cpatype = decltype(CPA::CPAfactory(nlohmann::json{}));
+using pcsafttype = decltype(PCSAFT::PCSAFTfactory(nlohmann::json{}));
+
+using AllowedModels = std::variant<vdWEOS1, cub, cpatype, pcsafttype>;
 
 AllowedModels build_model(const nlohmann::json& json) {
 
@@ -32,6 +36,9 @@ AllowedModels build_model(const nlohmann::json& json) {
     else if (kind == "CPA") {
         return CPA::CPAfactory(spec);
     }
+    else if (kind == "PCSAFT") {
+        return PCSAFT::PCSAFTfactory(spec);
+    }
     else {
         throw teqpcException(30, "Unknown kind:" + kind);
     }
diff --git a/include/teqp/models/pcsaft.hpp b/include/teqp/models/pcsaft.hpp
index 9d00650..30043a0 100644
--- a/include/teqp/models/pcsaft.hpp
+++ b/include/teqp/models/pcsaft.hpp
@@ -1,5 +1,9 @@
 #pragma once
 
+#include "nlohmann/json.hpp"
+
+namespace PCSAFT {
+
 /// Coefficients for one fluid
 struct SAFTCoeffs {
     std::string name; ///< Name of fluid
@@ -292,4 +296,20 @@ public:
         auto alphar_disp = -2 * MY_PI * rho_A3 * I1 * c.m2_epsilon_sigma3_bar - MY_PI * rho_A3 * mbar * C1(eta, mbar) * I2 * c.m2_epsilon2_sigma3_bar;
         return forceeval(alphar_hc + alphar_disp);
     }
-};
\ No newline at end of file
+};
+
+auto PCSAFTfactory(const nlohmann::json& json) {
+    std::vector<SAFTCoeffs> coeffs;
+    for (auto j : json) {
+        SAFTCoeffs c;
+        c.name = j.at("name");
+        c.m = j.at("m");
+        c.sigma_Angstrom = j.at("sigma_Angstrom");
+        c.epsilon_over_k = j.at("epsilon_over_k");
+        c.BibTeXKey = j.at("BibTeXKey");
+        coeffs.push_back(c);
+    }
+    return PCSAFTMixture(coeffs);
+};
+
+} /* namespace PCSAFT */
\ No newline at end of file
diff --git a/interface/C/teqpc.cpp b/interface/C/teqpc.cpp
index d72f2ba..47a82f1 100644
--- a/interface/C/teqpc.cpp
+++ b/interface/C/teqpc.cpp
@@ -96,7 +96,7 @@ int get_Arxy(char* uuid, const int NT, const int ND, const double T, const doubl
 #define CATCH_CONFIG_MAIN
 #include "catch/catch.hpp"
 
-TEST_CASE("Use of C interface with simple models") {
+TEST_CASE("Use of C interface") {
 
     constexpr int errmsg_length = 300;
     char uuid[33] = "", uuidPR[33] = "", errmsg[errmsg_length] = "";
@@ -192,6 +192,26 @@ TEST_CASE("Use of C interface with simple models") {
         REQUIRE(e3 == 0);
         return val;
     };
+
+    BENCHMARK("PCSAFT") {
+        nlohmann::json jmodel = nlohmann::json::array();
+        std::valarray<double> molefrac = { 0.4, 0.6 };
+        jmodel.push_back({ {"name", "Methane"}, { "m", 1.0 }, { "sigma_Angstrom", 3.7039},{"epsilon_over_k", 150.03}, {"BibTeXKey", "Gross-IECR-2001"} });
+        jmodel.push_back({ {"name", "Ethane"}, { "m", 1.6069 }, { "sigma_Angstrom", 3.5206},{"epsilon_over_k", 191.42}, {"BibTeXKey", "Gross-IECR-2001"} });
+        nlohmann::json j = {
+            {"kind", "PCSAFT"},
+            {"model", jmodel}
+        };
+        std::string js = j.dump(2);
+        int e1 = build_model(j.dump(2).c_str(), uuid, errmsg, errmsg_length);
+        int e2 = get_Arxy(uuid, 0, 1, 300, 3.0e-6, &(molefrac[0]), molefrac.size(), &val, errmsg, errmsg_length);
+        int e3 = free_model(uuid, errmsg, errmsg_length);
+        REQUIRE(e1 == 0);
+        REQUIRE(e2 == 0);
+        REQUIRE(e3 == 0);
+        return val;
+    };
+    
 }
 #else 
 int main() {
diff --git a/interface/PCSAFT.cpp b/interface/PCSAFT.cpp
index 3ca8af7..578b830 100644
--- a/interface/PCSAFT.cpp
+++ b/interface/PCSAFT.cpp
@@ -3,6 +3,8 @@
 #include "teqp/models/pcsaft.hpp"
 #include "teqp/derivs.hpp"
 
+using namespace PCSAFT;
+
 void add_PCSAFT(py::module& m) {
 
 	py::class_<SAFTCoeffs>(m, "SAFTCoeffs")
diff --git a/src/bench.cpp b/src/bench.cpp
index bdf772a..ee5118d 100644
--- a/src/bench.cpp
+++ b/src/bench.cpp
@@ -52,6 +52,7 @@ TEST_CASE("vdW derivatives", "[vdW]")
 
 TEST_CASE("PCSAFT derivatives", "[PCSAFT]")
 {
+    using namespace PCSAFT;
     std::vector<std::string> names = { "Methane", "Ethane" };
     auto model = PCSAFTMixture(names);
 
diff --git a/src/teqp_profile.cpp b/src/teqp_profile.cpp
index f6be0bb..c60f3f2 100644
--- a/src/teqp_profile.cpp
+++ b/src/teqp_profile.cpp
@@ -10,6 +10,7 @@
 //#include "teqp/models/CPA.hpp"
 #include "teqp/models/multifluid.hpp"
 #include "teqp/models/pcsaft.hpp"
+using namespace PCSAFT;
 #include "teqp/containers.hpp"
 #include <Eigen/Dense>
 #include "teqp/derivs.hpp"
diff --git a/src/tests/catch_tests.cxx b/src/tests/catch_tests.cxx
index 24be53b..6e581e1 100644
--- a/src/tests/catch_tests.cxx
+++ b/src/tests/catch_tests.cxx
@@ -3,6 +3,7 @@
 
 #include "teqp/core.hpp"
 #include "teqp/models/pcsaft.hpp"
+using namespace PCSAFT;
 #include "teqp/models/cubicsuperancillary.hpp"
 #include "teqp/models/CPA.hpp"
 #include "teqp/models/vdW.hpp"
diff --git a/src/time_Ar0n.cpp b/src/time_Ar0n.cpp
index ac73454..36d30fa 100644
--- a/src/time_Ar0n.cpp
+++ b/src/time_Ar0n.cpp
@@ -22,6 +22,7 @@
 #include "teqp/models/vdW.hpp"
 #include "teqp/models/cubics.hpp"
 #include "teqp/models/pcsaft.hpp"
+using namespace PCSAFT;
 #include "teqp/derivs.hpp"
 
 struct OneTiming {
-- 
GitLab