From 8a3ef27de35670bf30b22c0ad26e097cfe3aaf61 Mon Sep 17 00:00:00 2001 From: Ian Bell <ian.bell@nist.gov> Date: Tue, 2 Aug 2022 17:51:15 -0400 Subject: [PATCH] Mixtures work now too for alphaig Just need to fill in the remaining terms and test, test, test --- include/teqp/ideal_eosterms.hpp | 49 ++++++++++++++++++++++++++++---- src/tests/catch_test_alphaig.cxx | 8 ++++-- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/include/teqp/ideal_eosterms.hpp b/include/teqp/ideal_eosterms.hpp index 6d22c14..537ee66 100644 --- a/include/teqp/ideal_eosterms.hpp +++ b/include/teqp/ideal_eosterms.hpp @@ -30,11 +30,11 @@ namespace teqp { using IdealHelmholtzTerms = std::variant<IdealHelmholtzLead>; - class IdealHelmholtz { + class PureIdealHelmholtz { public: std::vector<IdealHelmholtzTerms> contributions; - IdealHelmholtz(const nlohmann::json& j) { - for (auto& term : j) { + PureIdealHelmholtz(const nlohmann::json& jpure) { + for (auto& term : jpure) { if (term.at("type") == "Lead") { contributions.emplace_back(IdealHelmholtzLead(term.at("a_1"), term.at("a_2"))); } @@ -43,8 +43,8 @@ namespace teqp { } } } - template<typename TType, typename RhoType, typename MoleFrac> - auto alphaig(const TType& T, const RhoType &rho, const MoleFrac& /**/) const{ + template<typename TType, typename RhoType> + auto alphaig(const TType& T, const RhoType &rho) const{ std::common_type_t <TType, RhoType> ig = 0.0; for (const auto& term : contributions) { auto contrib = std::visit([&](auto& t) { return t.alphaig(T, rho); }, term); @@ -54,4 +54,43 @@ namespace teqp { } }; + /** + * @brief Ideal-gas Helmholtz energy container + * + * \f[ \alpha^{\rm ig} = \sum_i x_i[\alpha^{\rm ig}_{oi}(T,\rho) + x_i] \f] + * + * where x_i are mole fractions + * + */ + class IdealHelmholtz { + + public: + + std::vector<PureIdealHelmholtz> pures; + + IdealHelmholtz(const nlohmann::json &jpures){ + for (auto &jpure : jpures){ + pures.emplace_back(jpure); + } + } + + template<typename TType, typename RhoType, typename MoleFrac> + auto alphaig(const TType& T, const RhoType &rho, const MoleFrac &molefrac) const { + std::common_type_t <TType, RhoType, decltype(molefrac[0])> ig = 0.0; + if (molefrac.size() != pures.size()){ + throw teqp::InvalidArgument("molefrac and pures are not the same length"); + } + std::size_t i = 0; + for (auto &pure : pures){ + if (molefrac[i] != 0){ + ig += molefrac[i]*(pure.alphaig(T, rho) + log(molefrac[i])); + } + else{ + // lim_{x\to 0} x*ln(x) => 0 + } + i++; + } + return ig; + } + }; } \ No newline at end of file diff --git a/src/tests/catch_test_alphaig.cxx b/src/tests/catch_test_alphaig.cxx index ab1a40e..7a00f5e 100644 --- a/src/tests/catch_test_alphaig.cxx +++ b/src/tests/catch_test_alphaig.cxx @@ -10,8 +10,10 @@ using namespace teqp; TEST_CASE("Simplest case","[alphaig]") { double a_1 = 1, a_2 = 2, T = 300; + nlohmann::json j0 = nlohmann::json::array(); + j0.push_back({ {"type", "Lead"}, { "a_1", 1 }, { "a_2", 2 } }); nlohmann::json j = nlohmann::json::array(); - j.push_back({ {"type", "Lead"}, { "a_1", 1 }, { "a_2", 2 } }); + j.push_back(j0); IdealHelmholtz ih(j); std::valarray<double> molefrac{1.0}; REQUIRE(ih.alphaig(T, 1, molefrac) == log(1) + a_1 + a_2 / T); @@ -19,8 +21,10 @@ TEST_CASE("Simplest case","[alphaig]") { TEST_CASE("alphaig derivative", "[alphaig]") { double a_1 = 1, a_2 = 2, T = 300, rho = 1; + nlohmann::json j0 = nlohmann::json::array(); + j0.push_back({ {"type", "Lead"}, { "a_1", 1 }, { "a_2", 2 } }); // For the first component nlohmann::json j = nlohmann::json::array(); - j.push_back({ {"type", "Lead"}, { "a_1", 1 }, { "a_2", 2 } }); + j.push_back(j0); IdealHelmholtz ih(j); auto molefrac = (Eigen::ArrayXd(1) << 1.0).finished(); auto wih = AlphaCallWrapper<1, decltype(ih)>(ih); -- GitLab