From 9d090ab5868d265bd256943a290ef2e02a63d6de Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 7 Jun 2022 10:27:39 -0400 Subject: [PATCH] Document consistency testing infrastructure --- test/data/consistency-cases.yaml | 30 ++++++++++++++++++++++++++++ test/thermo/consistency.cpp | 34 +++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/test/data/consistency-cases.yaml b/test/data/consistency-cases.yaml index ee6e605f49..2b6e6f17c3 100644 --- a/test/data/consistency-cases.yaml +++ b/test/data/consistency-cases.yaml @@ -1,4 +1,34 @@ # Parameters for test cases defined in test/thermo/consistency.cpp +# +# Each top-level entry here corresponds to a Googletest "test suite" instantiation, +# using the INSTANTIATE_TEST_SUITE_P macro. +# +# Each of these entries has two keys, 'setup' and 'states'. The 'setup' map defines the +# phase to be loaded, information on cases that are known to fail, and optional +# tolerance parameters that are used in some tests. Within the 'setup' map, the +# following keys are recognized: +# - file: the name of the input file, read from the usual data paths (which +# includes test/data when running the test suite) +# - phase: The name of the phase to read. Optional - by default, the first phase +# in the file is used. +# - known-failures: A map where the keys identify tests that should be skipped because +# they are known to fail and the values are messages to be printed in the test log +# explaining why the test has been skipped. The keys are regular expressions that are +# searched for in the test names (second argument to TEST_P) defined in +# consistency.cpp. The test name is suffixed with '/N' where 'N' is the (zero-indexed) +# index into the 'states' array and can be used to skip specific test instances. Where +# possible, known failures should reference GitHub Issue numbers documenting known +# errors. This mechanism is not used to handle test cases that raise +# NotImplementedError; Those tests should be skipped automatically. +# - atol: An absolute tolerance used for tests comparing molar energy-like quantities. +# Default 1.0e-5. +# - atol_v: An absolute tolerance used for tests comparing molar volumes. +# Default 1.0e-11. +# - rtol_fd: A relative tolerance used in some finite difference tests. Default 1.0e-6. +# +# The 'states' key defines a list of maps, where each map provides a complete state +# definition for the phase. The map is passed directly to ThermoPhase::setState(), and +# supports setting the state using any of the variables supported there. ideal-gas-h2o2: setup: {file: h2o2.yaml} diff --git a/test/thermo/consistency.cpp b/test/thermo/consistency.cpp index 419ca2510d..0004d24212 100644 --- a/test/thermo/consistency.cpp +++ b/test/thermo/consistency.cpp @@ -6,11 +6,30 @@ #include "cantera/base/utilities.h" #include +// This is a set of tests that check all ThermoPhase models implemented in Cantera +// for thermodynamic identities such as g = h - T*s and c_p = dh/dT at constant P. + +// Below the definition of the TestConsistency test fixture class, the individual +// consistency tests are implemented in the functions declared using the TEST_P macro. +// Each of these tests starts with the 'phase' object created and set to the +// thermodynamic state that should be used for the test. + +// Following the individual test definitions, a "test suite" is created for each phase +// model using the INSTANTIATE_TEST_SUITE_P macro. The string passed to the getSetup() +// and getStates() functions in the test suite instantiation corresponds to a top-level +// section of the file test/data/consistency-cases.yaml. Each of these sections defines +// a phase definition and a sequence of thermodynamic states to be used for each of the +// individual test functions. Generally, there is one test suite for each ThermoPhase +// model. However, there are a few phase models that have multiple test suites to allow +// testing the effects of parameters that can only be varied within the phase +// definition. + using namespace std; namespace Cantera { +// Helper functions to reduce code duplication in test suite instantiations vector getStates(const string& name) { static AnyMap cases = AnyMap::fromYamlFile("consistency-cases.yaml"); return cases[name]["states"].asVector(); @@ -45,6 +64,9 @@ class TestConsistency : public testing::TestWithParam auto param = GetParam(); setup = get<0>(param); AnyMap state = get<1>(param); + + // For efficiency, cache the instantiated phase object rather than recreating + // it for every single test case. pair key = {setup["file"].asString(), setup.getString("phase", "")}; if (cache.count(key) == 0) { cache[key].reset(newPhase(key.first, key.second)); @@ -62,6 +84,7 @@ class TestConsistency : public testing::TestWithParam } void SetUp() { + // See if we should skip this test specific test case if (setup.hasKey("known-failures")) { auto name = testing::UnitTest::GetInstance()->current_test_info()->name(); for (auto& item : setup["known-failures"].asMap()) { @@ -79,12 +102,15 @@ class TestConsistency : public testing::TestWithParam shared_ptr phase; size_t nsp; double T, p, RT; - double atol, atol_v; + double atol; // absolute tolerance for molar energy comparisons + double atol_v; // absolute tolerance for molar volume comparisons double rtol_fd; // relative tolerance for finite difference comparisons }; map, shared_ptr> TestConsistency::cache = {}; +// --------------- Definitions for individual consistency tests --------------- + TEST_P(TestConsistency, h_eq_u_plus_Pv) { double h = phase->enthalpy_mole(); double u = phase->intEnergy_mole(); @@ -319,6 +345,8 @@ TEST_P(TestConsistency, dSdv_const_T_eq_dPdT_const_V) { } } +// ---------- Tests for consistency of standard state properties --------------- + TEST_P(TestConsistency, hk0_eq_uk0_plus_p_vk0) { vector_fp h0(nsp), u0(nsp), v0(nsp); @@ -451,6 +479,8 @@ TEST_P(TestConsistency, log_activity_coeffs) { } } +// -------------------- Tests for reference state properties ------------------- + TEST_P(TestConsistency, hRef_eq_uRef_plus_P_vRef) { vector_fp hRef(nsp), uRef(nsp), vRef(nsp); @@ -506,6 +536,8 @@ TEST_P(TestConsistency, cpRef_eq_dhRefdT) } } +// ------- Instantiation of test suites defined in consistency-cases.yaml ------ + INSTANTIATE_TEST_SUITE_P(IdealGas, TestConsistency, testing::Combine( testing::Values(getSetup("ideal-gas-h2o2")),