diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index 39c09daa..8760229c 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -18,11 +18,15 @@ jobs: strategy: matrix: compiler: + - { cpp: g++-12, c: gcc-12 } - { cpp: g++-13, c: gcc-13 } - { cpp: g++-14, c: gcc-14 } - { cpp: clang++, c: clang } build_type: [Release] use_fmt: [OFF, ON] + exclude: + - compiler: { cpp: g++-12, c: gcc-12 } + use_fmt: OFF env: CC: ${{ matrix.compiler.c }} CXX: ${{ matrix.compiler.cpp }} @@ -30,8 +34,20 @@ jobs: - name: Checkout code uses: actions/checkout@v4 + # Clang on Ubuntu defaults to libstdc++, whose std::expected is not visible to + # clang-18 (no template named 'expected'). Build the clang job against libc++, + # which provides std::expected and std::format. + - name: Install libc++ (clang) + if: matrix.compiler.cpp == 'clang++' + run: sudo apt-get update && sudo apt-get install -y libc++-dev libc++abi-dev + - name: Configure CMake - run: cmake -S . -B build -D CMAKE_BUILD_TYPE=${{ matrix.build_type }} -D MECH_CONFIG_USE_FMT=${{ matrix.use_fmt }} -D MECH_CONFIG_COMPILE_WARNING_AS_ERROR=ON + run: | + EXTRA_FLAGS="" + if [ "${{ matrix.compiler.cpp }}" = "clang++" ]; then + EXTRA_FLAGS="-D CMAKE_CXX_FLAGS=-stdlib=libc++" + fi + cmake -S . -B build -D CMAKE_BUILD_TYPE=${{ matrix.build_type }} -D MECH_CONFIG_USE_FMT=${{ matrix.use_fmt }} -D MECH_CONFIG_COMPILE_WARNING_AS_ERROR=ON $EXTRA_FLAGS - name: Build run: cmake --build build --config ${{ matrix.build_type }} --parallel 10 diff --git a/CMakeLists.txt b/CMakeLists.txt index a9452d22..66237b60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) # must be on the same line so that pyproject.toml can correctly identify the version -project(mechanism_configuration VERSION 1.1.2 LANGUAGES CXX) +project(mechanism_configuration VERSION 2.0.0 LANGUAGES CXX) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING diff --git a/README.md b/README.md index 6b2fae30..cf757faf 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,7 @@ An attempt at defining a model-independent configuration schema for atmospheric chemical systems in JSON and YAML. [![GitHub Releases](https://img.shields.io/github/release/ncar/MechanismConfiguration.svg)](https://github.com/ncar/MechanismConfiguration/releases) -[![License](https://img.shields.io/github/license/ncar/MechanismConfiguration.svg)](https://github.com/ncar/MechanismConfiguration/blob/master/LICENSE) -[![Docs build](https://github.com/ncar/MechanismConfiguration/actions/workflows/gh-pages.yml/badge.svg)](https://github.com/ncar/MechanismConfiguration/actions/workflows/gh-pages.yml) +[![License](https://img.shields.io/badge/license-Apache_2.0-blue.svg)](https://github.com/NCAR/MechanismConfiguration/blob/main/LICENSE) [![Windows](https://github.com/ncar/MechanismConfiguration/actions/workflows/windows.yml/badge.svg)](https://github.com/ncar/MechanismConfiguration/actions/workflows/windows.yml) [![Mac](https://github.com/ncar/MechanismConfiguration/actions/workflows/mac.yml/badge.svg)](https://github.com/ncar/MechanismConfiguration/actions/workflows/mac.yml) [![Ubuntu](https://github.com/ncar/MechanismConfiguration/actions/workflows/ubuntu.yml/badge.svg)](https://github.com/ncar/MechanismConfiguration/actions/workflows/ubuntu.yml) @@ -15,6 +14,72 @@ Copyright (C) 2017–2026 University Corporation for Atmospheric Research, Unive The configuration documentation can be found [here](https://ncar.github.io/MechanismConfiguration/). +## Usage + +Everything goes through the canonical `mechanism_configuration::Mechanism`. You can either +**parse** a configuration file (the version is detected and dispatched automatically), or build +a `Mechanism` in code and **validate** it. `Validate()` runs the same semantic checks the parser +uses, so it applies to any mechanism regardless of where it came from. + +```cpp +#include + +#include + +using namespace mechanism_configuration; + +void print_errors(const Errors& errors) +{ + for (const auto& [code, message] : errors) + std::cerr << " [" << ErrorCodeToString(code) << "] " << message << '\n'; +} + +int main() +{ + int status = 0; + + // 1) Parse from a file (YAML or JSON; v0 or v1). Returns std::expected + // with both structural and semantic errors reported. + if (auto parsed = Parse("examples/v1/full_configuration.yaml")) + { + const Mechanism& mechanism = *parsed; + std::cout << "Parsed '" << mechanism.name << "': " << mechanism.species.size() + << " species, " << mechanism.reactions.arrhenius.size() << " Arrhenius reactions\n"; + } + else + { + std::cerr << "Failed to parse file:\n"; + print_errors(parsed.error()); + status = 1; + } + + // 2) Build a Mechanism in code and validate it (species exist, reactants are in their + // phase, no duplicate names, ...). + Mechanism mechanism; + mechanism.name = "example"; + mechanism.species = { { .name = "A" }, { .name = "B" } }; + mechanism.phases = { { .name = "gas", .species = { { .name = "A" }, { .name = "B" } } } }; + + types::Arrhenius reaction; + reaction.name = "A -> B"; + reaction.gas_phase = "gas"; + reaction.reactants = { { .name = "A" } }; // reactants must be registered in the phase + reaction.products = { { .name = "B" } }; // products may reference any phase + mechanism.reactions.arrhenius = { reaction }; + + if (Errors errors = Validate(mechanism); errors.empty()) + std::cout << "In-code mechanism is valid\n"; + else + { + std::cerr << "In-code mechanism is invalid:\n"; + print_errors(errors); + status = 1; + } + + return status; +} +``` + ## Building the Documentation With python and pip installed, go to the `docs/` folder and run: diff --git a/cmake/test_util.cmake b/cmake/test_util.cmake index bf0e20a8..828d371c 100644 --- a/cmake/test_util.cmake +++ b/cmake/test_util.cmake @@ -13,6 +13,10 @@ function(create_standard_test) add_executable(test_${TEST_NAME} ${TEST_SOURCES}) target_link_libraries(test_${TEST_NAME} PUBLIC musica::mechanism_configuration GTest::gtest_main) + target_include_directories(test_${TEST_NAME} + PUBLIC + ${PROJECT_SOURCE_DIR}/src + ) # link additional libraries diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst new file mode 100644 index 00000000..baaf1782 --- /dev/null +++ b/docs/source/changelog.rst @@ -0,0 +1,102 @@ +Changelog +========= + +Version 2.0.0 +------------- + +Version 2.0.0 introduces breaking changes to the C++ API compared to the 1.x series. +The configuration file formats (``v0`` and ``v1``) are unchanged; the breaking changes +are in how the library is consumed from C++. + +API Changes +^^^^^^^^^^^ + +- Parsing is now a free function that returns ``std::expected``: + ``std::expected Parse(const std::filesystem::path&)``. + The previous ``UniversalParser`` / ``ParserResult`` interface has been removed. +- A version-neutral ``Errors Validate(const Mechanism&)`` has been added so an in-code + ``Mechanism`` can be checked with the same semantic rules the parser uses. +- A single canonical ``mechanism_configuration::Mechanism`` (with ``mechanism_configuration::types::*``) + replaces the version-specific ``v0::types::Mechanism`` and ``v1::types::Mechanism``. +- Errors are reported through ``Errors`` (a list of ``{ErrorCode, std::string}``) and + ``ErrorCodeToString``; the previous parse-status helpers have been removed. + +Header Reorganization +^^^^^^^^^^^^^^^^^^^^^^ + +- A single public umbrella header is now provided. Including + ```` is sufficient to use the library. +- The public surface is limited to ``parse.hpp``, ``validate.hpp``, ``mechanism.hpp``, + ``types.hpp``, ``errors.hpp``, and ``version.hpp`` (plus the umbrella). +- Internal headers (the ``v0`` / ``v1`` parsers, schema and validation helpers) have moved + into a private ``detail`` tree and are no longer installed. Code that included headers such + as ``parser.hpp``, ``parser_result.hpp``, ``parse_status.hpp``, ``error_location.hpp``, or the + versioned ``v1/types.hpp`` / ``v1/mechanism.hpp`` must migrate to the public headers above. + +Removed Reactions +^^^^^^^^^^^^^^^^^ + +The following reaction types were removed from the ``v1`` mechanism: + +- ``AQUEOUS_EQUILIBRIUM`` +- ``CONDENSED_PHASE_ARRHENIUS`` +- ``CONDENSED_PHASE_PHOTOLYSIS`` +- ``HENRYS_LAW`` +- ``SIMPOL_PHASE_TRANSFER`` +- ``WET_DEPOSITION`` + +Other Changes +^^^^^^^^^^^^^ + +- Reaction components accept the legacy ``species name`` key as an alias for ``name``. +- A ``v1`` configuration may split ``species``, ``phases``, and ``reactions`` across multiple + files using the ``files`` list form (minor version 1.1 or later). +- Products may reference a species in any phase; only reactants must belong to the + reaction's phase. + +Migration +^^^^^^^^^ + +Old approach (1.x): + +.. code-block:: cpp + + #include + + using namespace mechanism_configuration; + + UniversalParser parser; + ParserResult result = parser.Parse("config.yaml"); + if (result) + { + GlobalMechanism& mechanism = *result; + // ... + } + else + { + for (const auto& error : result.errors) + { + // ... + } + } + +New approach (2.0): + +.. code-block:: cpp + + #include + + using namespace mechanism_configuration; + + if (auto parsed = Parse("config.yaml")) + { + const Mechanism& mechanism = *parsed; + // ... + } + else + { + for (const auto& [code, message] : parsed.error()) + { + // ... + } + } diff --git a/docs/source/index.rst b/docs/source/index.rst index be692b36..6d1205d4 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -12,7 +12,7 @@ .. ~ for subsubsubsections .. " for paragraphs -.. |project_version| replace:: 1.1.2 +.. |project_version| replace:: 2.0.0 ############################################################### Welcome to the NSF NCAR Mechanism Configuration documentation! @@ -24,6 +24,7 @@ Welcome to the NSF NCAR Mechanism Configuration documentation! v0/index v1/index + changelog bibliography diff --git a/docs/source/v1/reactions/index.rst b/docs/source/v1/reactions/index.rst index cca9324b..48b92f42 100644 --- a/docs/source/v1/reactions/index.rst +++ b/docs/source/v1/reactions/index.rst @@ -11,6 +11,7 @@ Their configuration is defined in this repository, as are the algorithms that mi * :doc:`branched` - :cpp:class:`micm::BranchedRateConstant` * :doc:`emission` - :cpp:class:`micm::UserDefinedRateConstant` * :doc:`first_order_loss` - :cpp:class:`micm::UserDefinedRateConstant` +* :doc:`lambda_rate_constant` - :cpp:class:`micm::UserDefinedRateConstant` * :doc:`photolysis` - :cpp:class:`micm::UserDefinedRateConstant` * :doc:`surface` - :cpp:class:`micm::SurfaceRateConstant` * :doc:`taylor_series` - :cpp:class:`micm::TaylorSeriesRateConstant` @@ -29,6 +30,7 @@ Their configuration is defined in this repository, as are the algorithms that mi branched emission first_order_loss + lambda_rate_constant photolysis surface taylor_series diff --git a/docs/source/v1/reactions/lambda_rate_constant.rst b/docs/source/v1/reactions/lambda_rate_constant.rst new file mode 100644 index 00000000..68a29749 --- /dev/null +++ b/docs/source/v1/reactions/lambda_rate_constant.rst @@ -0,0 +1,76 @@ +Lambda Rate Constant +==================== + +Lambda rate constant reactions compute the rate constant from a user-supplied lambda +function of temperature (and optionally pressure): + +.. math:: + + \ce{X_1 ( + X_2 \dots ) -> Y_1 ( + Y_2 \dots )} + +where :math:`\ce{X_n}` are the reactants, and :math:`\ce{Y_n}` are the products of the reaction. + +The rate constant is given by the value returned from the supplied ``lambda function`` when +evaluated at the current temperature :math:`T` (in K) and, optionally, pressure :math:`P` (in Pa). + +Input data for lambda rate constant reactions have the following format: + +.. tab-set:: + + .. tab-item:: YAML + + .. code-block:: yaml + + type: LAMBDA_RATE_CONSTANT + name: foo-lambda + gas phase: gas + lambda function: "[](double T, double P) { return 1.2e-5 * exp(-500.0 / T); }" + reactants: + - species name: foo + coefficient: 1.0 + products: + - species name: bar + coefficient: 0.5 + - species name: baz + coefficient: 0.3 + + + .. tab-item:: JSON + + .. code-block:: json + + { + "type": "LAMBDA_RATE_CONSTANT", + "name": "foo-lambda", + "gas phase": "gas", + "lambda function": "[](double T, double P) { return 1.2e-5 * exp(-500.0 / T); }", + "reactants": [ + { + "species name": "foo", + "coefficient": 1.0 + } + ], + "products": [ + { + "species name": "bar", + "coefficient": 0.5 + }, + { + "species name": "baz", + "coefficient": 0.3 + } + ] + } + +The key-value pairs ``reactants``, ``products``, and ``lambda function`` are required. +Any number of reactants and products may be present. Reactants and products without a specified ``coefficient`` are +assumed to have a ``coefficient`` of 1.0. + +The ``lambda function`` is a string holding a function that takes temperature :math:`T` and, +optionally, pressure :math:`P` and returns the rate constant. It is expected to be compiled +by a conforming implementation. + +The ``gas phase`` key is required and must be set to the name of the phase the +reaction takes place in. Each reactant must be present in the specified phase. + +Rate constants are in units of :math:`\mathrm{(m^{3}\ mol^{-1})^{(n-1)}\ s^{-1}}` where :math:`n` is the total number of reactants. diff --git a/examples/development/full_configuration.json b/examples/development/full_configuration.json deleted file mode 100644 index 563e72d9..00000000 --- a/examples/development/full_configuration.json +++ /dev/null @@ -1,586 +0,0 @@ -{ - "version": "2.0.0", - "name": "Full Configuration", - "species": [ - { - "name": "A", - "__absolute tolerance": 1.0e-30 - }, - { - "name": "B", - "constant concentration [mol m-3]": 1.0e19 - }, - { - "name": "C", - "is third body": true - }, - { - "name": "M" - }, - { - "name": "H2O2", - "HLC(298K) [mol m-3 Pa-1]": 1.011596348, - "HLC exponential factor [K]": 6340, - "diffusion coefficient [m2 s-1]": 1.46E-05, - "N star": 1.74, - "molecular weight [kg mol-1]": 0.0340147, - "density [kg m-3]": 1000.0, - "constant mixing ratio [mol mol-1]": 1.0e-6, - "__absolute tolerance": 1.0e-10 - }, - { - "name": "ethanol", - "diffusion coefficient [m2 s-1]": 0.95E-05, - "N star": 2.55, - "molecular weight [kg mol-1]": 0.04607, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "ethanol_aq", - "molecular weight [kg mol-1]": 0.04607, - "density [kg m-3]": 1000.0, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "H2O2_aq", - "molecular weight [kg mol-1]": 0.0340147, - "density [kg m-3]": 1000.0, - "__absolute tolerance": 1.0e-10 - }, - { - "name": "H2O", - "density [kg m-3]": 1000.0, - "molecular weight [kg mol-1]": 0.01801 - }, - { - "name": "aerosol stuff", - "molecular weight [kg mol-1]": 0.5, - "density [kg m-3]": 1000.0, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "more aerosol stuff", - "molecular weight [kg mol-1]": 0.2, - "density [kg m-3]": 1000.0, - "__absolute tolerance": 1.0e-20 - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "ethanol" - }, - { - "name": "H2O2" - }, - { - "name": "M" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O2_aq" - }, - { - "name": "ethanol_aq" - }, - { - "name": "H2O" - } - ] - }, - { - "name": "surface reacting phase", - "species": [ - { - "name": "aerosol stuff" - }, - { - "name": "more aerosol stuff" - } - ] - }, - { - "name": "organic", - "species": [ - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "models": [ - { - "name": "gas", - "type": "GAS_PHASE", - "phase": "gas" - }, - { - "name": "aqueous", - "type": "MODAL", - "modes": [ - { - "name": "aitken", - "geometric mean diameter [m]": 2.6e-8, - "geometric standard deviation": 1.6, - "phase": "aqueous" - }, - { - "name": "accumulation", - "geometric mean diameter [m]": 1.1e-7, - "geometric standard deviation": 1.8, - "phase": "organic" - } - ] - } - ], - "reactions": [ - { - "type": "TAYLOR_SERIES", - "gas phase": "gas", - "reactants": [ - { - "name": "A", - "coefficient": 1 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1.2 - }, - { - "name": "C", - "coefficient": 0.3 - } - ], - "A": 32.1, - "B": -2.3, - "C": 102.3, - "D": 63.4, - "E": -1.3, - "taylor coefficients": [ - 1.0, - 2.0, - 3.0 - ], - "name": "my taylor_series", - "__solver_param": 0.1 - }, - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "H2O2", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "H2O2_aq" - } - ], - "solvent": [ - { - "name": "H2O" - } - ] - }, - "name": "my henry's law" - }, - { - "type": "SIMPOL_PHASE_TRANSFER", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "ethanol" - } - ], - "condensed phase": "aqueous", - "condensed-phase species": [ - { - "name": "ethanol_aq" - } - ], - "B": [ - -1.97E+03, - 2.91E+00, - 1.96E-03, - -4.96E-01 - ], - "name": "my simpol" - }, - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "A": 1.14e-2, - "C": 2300.0, - "k_reverse": 0.32, - "reactants": [ - { - "name": "A", - "coefficient": 2 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1 - }, - { - "name": "C", - "coefficient": 1 - } - ], - "name": "my aqueous eq" - }, - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "A": 123.45, - "Ea": 123.45, - "B": 1.3, - "D": 300.0, - "E": 0.6E-5, - "reactants": [ - { - "name": "H2O2_aq", - "coefficient": 1 - }, - { - "name": "H2O", - "coefficient": 1 - } - ], - "products": [ - { - "name": "ethanol_aq", - "coefficient": 1 - } - ], - "name": "my condensed arrhenius" - }, - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "A": 123.45, - "C": 123.45, - "B": 1.3, - "D": 300.0, - "E": 0.6E-5, - "reactants": [ - { - "name": "H2O2_aq", - "coefficient": 1 - }, - { - "name": "H2O", - "coefficient": 1 - } - ], - "products": [ - { - "name": "ethanol_aq", - "coefficient": 1 - } - ], - "name": "my other condensed arrhenius" - }, - { - "type": "CONDENSED_PHASE_PHOTOLYSIS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "H2O2_aq", - "coefficient": 1 - } - ], - "products": [ - { - "name": "ethanol_aq", - "coefficient": 1 - } - ], - "scaling factor": 12.3, - "name": "condensed photo B" - }, - { - "type": "EMISSION", - "gas phase": "gas", - "products": [ - { - "name": "B", - "coefficient": 1 - } - ], - "name": "my emission", - "scaling factor": 12.3 - }, - { - "type": "FIRST_ORDER_LOSS", - "gas phase": "gas", - "reactants": [ - { - "name": "C", - "coefficient": 1 - } - ], - "name": "my first order loss", - "scaling factor": 12.3 - }, - { - "type": "PHOTOLYSIS", - "gas phase": "gas", - "reactants": [ - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 1 - } - ], - "name": "photo B", - "scaling factor": 12.3 - }, - { - "type": "SURFACE", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "reaction probability": 2.0e-2, - "gas-phase products": [ - { - "name": "B", - "coefficient": 1 - }, - { - "name": "C", - "coefficient": 1 - } - ], - "condensed phase": "surface reacting phase", - "name": "my surface" - }, - { - "type": "TROE", - "gas phase": "gas", - "reactants": [ - { - "name": "B", - "coefficient": 1 - }, - { - "name": "M", - "coefficient": 1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 1 - } - ], - "k0_A": 1.2e-12, - "k0_B": 167, - "k0_C": 3, - "kinf_A": 136, - "kinf_B": 5, - "kinf_C": 24, - "Fc": 0.9, - "N": 0.8, - "name": "my troe" - }, - { - "type": "TERNARY_CHEMICAL_ACTIVATION", - "gas phase": "gas", - "name": "my ternary chemical activation", - "reactants": [ - { - "name": "A", - "coefficient": 1 - }, - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "A", - "coefficient": 0.5 - }, - { - "name": "C", - "coefficient": 0.0 - } - ], - "k0_A": 32.1, - "k0_B": -2.3, - "k0_C": 102.3, - "kinf_A": 63.4, - "kinf_B": -1.3, - "kinf_C": 908.5, - "Fc": 1.3, - "N": 32.1 - }, - { - "type": "BRANCHED_NO_RO2", - "gas phase": "gas", - "reactants": [ - { - "name": "A", - "coefficient": 1 - } - ], - "alkoxy products": [ - { - "name": "B", - "coefficient": 1 - } - ], - "nitrate products": [ - { - "name": "C", - "coefficient": 1 - } - ], - "X": 1.2e-4, - "Y": 167, - "a0": 0.15, - "n": 9, - "name": "my branched" - }, - { - "gas phase": "gas", - "name": "my tunneling", - "type": "TUNNELING", - "A": 123.45, - "B": 1200.0, - "C": 1.0e8, - "reactants": [ - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 1 - } - ] - }, - { - "type": "WET_DEPOSITION", - "condensed phase": "aqueous", - "name": "rxn cloud", - "scaling factor": 12.3 - }, - { - "type": "ARRHENIUS", - "gas phase": "gas", - "reactants": [ - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 1 - } - ], - "A": 32.1, - "B": -2.3, - "C": 102.3, - "D": 63.4, - "E": -1.3, - "name": "my arrhenius" - }, - { - "type": "ARRHENIUS", - "gas phase": "gas", - "reactants": [ - { - "name": "A", - "coefficient": 1 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1.2 - } - ], - "A": 29.3, - "B": -1.5, - "Ea": 101.2, - "D": 82.6, - "E": -0.98, - "name": "my other arrhenius" - }, - { - "type": "USER_DEFINED", - "gas phase": "gas", - "reactants": [ - { - "name": "A", - "coefficient": 1 - }, - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 1.3 - } - ], - "name": "my user defined", - "scaling factor": 12.3 - } - ] -} \ No newline at end of file diff --git a/examples/development/full_configuration.yaml b/examples/development/full_configuration.yaml deleted file mode 100644 index 4d259d07..00000000 --- a/examples/development/full_configuration.yaml +++ /dev/null @@ -1,358 +0,0 @@ -version: 2.0.0 -name: Full Configuration -species: - - name: A - __absolute tolerance: 1.0e-30 - - name: B - constant concentration [mol m-3]: 1.0e19 - - name: C - is third body: true - - name: M - - name: H2O2 - HLC(298K) [mol m-3 Pa-1]: 1.011596348 - HLC exponential factor [K]: 6340 - diffusion coefficient [m2 s-1]: 1.46E-05 - N star: 1.74 - molecular weight [kg mol-1]: 0.0340147 - density [kg m-3]: 1000.0 - constant mixing ratio [mol mol-1]: 1.0e-6 - __absolute tolerance: 1.0e-10 - - name: ethanol - diffusion coefficient [m2 s-1]: 0.95E-05 - N star: 2.55 - molecular weight [kg mol-1]: 0.04607 - __absolute tolerance: 1.0e-20 - - name: ethanol_aq - molecular weight [kg mol-1]: 0.04607 - density [kg m-3]: 1000.0 - __absolute tolerance: 1.0e-20 - - name: H2O2_aq - molecular weight [kg mol-1]: 0.0340147 - density [kg m-3]: 1000.0 - __absolute tolerance: 1.0e-10 - - name: H2O - density [kg m-3]: 1000.0 - molecular weight [kg mol-1]: 0.01801 - - name: aerosol stuff - molecular weight [kg mol-1]: 0.5 - density [kg m-3]: 1000.0 - __absolute tolerance: 1.0e-20 - - name: more aerosol stuff - molecular weight [kg mol-1]: 0.2 - density [kg m-3]: 1000.0 - __absolute tolerance: 1.0e-20 - -phases: - - name: gas - species: - - name: A - - name: B - - name: C - - name: ethanol - - name: H2O2 - - name: M - - name: aqueous - species: - - name: A - - name: B - - name: C - - name: H2O2_aq - - name: ethanol_aq - - name: H2O - - name: surface reacting phase - species: - - name: aerosol stuff - - name: more aerosol stuff - - name: organic - species: - - name: B - - name: C - -models: - - name: gas - type: GAS_PHASE - phase: gas - - name: aqueous - type: MODAL - modes: - - name: aitken - geometric mean diameter [m]: 2.6e-8 - geometric standard deviation: 1.6 - phase: aqueous - - name: accumulation - geometric mean diameter [m]: 1.1e-7 - geometric standard deviation: 1.8 - phase: organic - -reactions: - - type: TAYLOR_SERIES - gas phase: gas - reactants: - - name: A - coefficient: 1 - products: - - name: B - coefficient: 1.2 - - name: C - coefficient: 0.3 - A: 32.1 - B: -2.3 - C: 102.3 - D: 63.4 - E: -1.3 - taylor coefficients: - - 1.0 - - 2.0 - - 3.0 - name: my taylor_series - __solver_param: 0.1 - - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: H2O2 - diffusion coefficient [m2 s-1]: 0.7 - particle: - phase: aqueous - solutes: - - name: H2O2_aq - solvent: - - name: H2O - name: my henry's law - - - type: SIMPOL_PHASE_TRANSFER - gas phase: gas - gas-phase species: - - name: ethanol - condensed phase: aqueous - condensed-phase species: - - name: ethanol_aq - B: - - -1.97E+03 - - 2.91E+00 - - 1.96E-03 - - -4.96E-01 - name: my simpol - - - type: AQUEOUS_EQUILIBRIUM - condensed phase: aqueous - condensed-phase water: H2O - A: 1.14e-2 - C: 2300.0 - k_reverse: 0.32 - reactants: - - name: A - coefficient: 2 - products: - - name: B - coefficient: 1 - - name: C - coefficient: 1 - name: my aqueous eq - - - type: CONDENSED_PHASE_ARRHENIUS - condensed phase: aqueous - A: 123.45 - Ea: 123.45 - B: 1.3 - D: 300.0 - E: 0.6E-5 - reactants: - - name: H2O2_aq - coefficient: 1 - - name: H2O - coefficient: 1 - products: - - name: ethanol_aq - coefficient: 1 - name: my condensed arrhenius - - - type: CONDENSED_PHASE_ARRHENIUS - condensed phase: aqueous - A: 123.45 - C: 123.45 - B: 1.3 - D: 300.0 - E: 0.6E-5 - reactants: - - name: H2O2_aq - coefficient: 1 - - name: H2O - coefficient: 1 - products: - - name: ethanol_aq - coefficient: 1 - name: my other condensed arrhenius - - - type: CONDENSED_PHASE_PHOTOLYSIS - condensed phase: aqueous - reactants: - - name: H2O2_aq - coefficient: 1 - products: - - name: ethanol_aq - coefficient: 1 - scaling factor: 12.3 - name: condensed photo B - - - type: EMISSION - gas phase: gas - products: - - name: B - coefficient: 1 - name: my emission - scaling factor: 12.3 - - - type: FIRST_ORDER_LOSS - gas phase: gas - reactants: - - name: C - coefficient: 1 - name: my first order loss - scaling factor: 12.3 - - - type: PHOTOLYSIS - gas phase: gas - reactants: - - name: B - coefficient: 1 - products: - - name: C - coefficient: 1 - name: photo B - scaling factor: 12.3 - - - type: SURFACE - gas phase: gas - gas-phase species: - - name: A - coefficient: 1 - reaction probability: 2.0e-2 - gas-phase products: - - name: B - coefficient: 1 - - name: C - coefficient: 1 - condensed phase: surface reacting phase - name: my surface - - - type: TROE - gas phase: gas - reactants: - - name: B - coefficient: 1 - - name: M - coefficient: 1 - products: - - name: C - coefficient: 1 - k0_A: 1.2e-12 - k0_B: 167 - k0_C: 3 - kinf_A: 136 - kinf_B: 5 - kinf_C: 24 - Fc: 0.9 - N: 0.8 - name: my troe - - - type: TERNARY_CHEMICAL_ACTIVATION - gas phase: gas - name: my ternary chemical activation - reactants: - - name: A - coefficient: 1 - - name: B - coefficient: 1 - products: - - name: A - coefficient: 0.5 - - name: C - coefficient: 0.0 - k0_A: 32.1 - k0_B: -2.3 - k0_C: 102.3 - kinf_A: 63.4 - kinf_B: -1.3 - kinf_C: 908.5 - Fc: 1.3 - N: 32.1 - - - type: BRANCHED_NO_RO2 - gas phase: gas - reactants: - - name: A - coefficient: 1 - alkoxy products: - - name: B - coefficient: 1 - nitrate products: - - name: C - coefficient: 1 - X: 1.2e-4 - Y: 167 - a0: 0.15 - n: 9 - name: my branched - - - type: TUNNELING - gas phase: gas - name: my tunneling - A: 123.45 - B: 1200.0 - C: 1.0e8 - reactants: - - name: B - coefficient: 1 - products: - - name: C - coefficient: 1 - - - type: WET_DEPOSITION - condensed phase: aqueous - name: rxn cloud - scaling factor: 12.3 - - - type: ARRHENIUS - gas phase: gas - reactants: - - name: B - coefficient: 1 - products: - - name: C - coefficient: 1 - A: 32.1 - B: -2.3 - C: 102.3 - D: 63.4 - E: -1.3 - name: my arrhenius - - - type: ARRHENIUS - gas phase: gas - reactants: - - name: A - coefficient: 1 - products: - - name: B - coefficient: 1.2 - A: 29.3 - B: -1.5 - Ea: 101.2 - D: 82.6 - E: -0.98 - name: my other arrhenius - - - type: USER_DEFINED - gas phase: gas - reactants: - - name: A - coefficient: 1 - - name: B - coefficient: 1 - products: - - name: C - coefficient: 1.3 - name: my user defined - scaling factor: 12.3 diff --git a/examples/v1/full_configuration.json b/examples/v1/full_configuration.json index bc61afd0..c67b108b 100644 --- a/examples/v1/full_configuration.json +++ b/examples/v1/full_configuration.json @@ -40,6 +40,7 @@ {"name": "A"}, {"name": "B"}, {"name": "C"}, + {"name": "M"}, { "name": "ethanol", "diffusion coefficient [m2 s-1]": 2.1e-5 @@ -154,21 +155,21 @@ "N": 32.1, "reactants": [ { - "species name": "bar", + "species name": "A", "coefficient": 1 }, { - "species name": "baz", + "species name": "B", "coefficient": 1 } ], "products": [ { - "species name": "bar", + "species name": "B", "coefficient": 0.5 }, { - "species name": "foo", + "species name": "C", "coefficient": 0.3 } ] @@ -308,6 +309,24 @@ "coefficient": 1 } ] + }, + { + "type": "LAMBDA_RATE_CONSTANT", + "name": "my lambda rate constant", + "gas phase": "gas", + "lambda function": "[](double T, double P) { return 1.2e-5 * exp(-500.0 / T); }", + "reactants": [ + { + "species name": "B", + "coefficient": 1 + } + ], + "products": [ + { + "species name": "C", + "coefficient": 1 + } + ] } ] } \ No newline at end of file diff --git a/examples/v1/full_configuration.yaml b/examples/v1/full_configuration.yaml index eeed8016..8a51f858 100644 --- a/examples/v1/full_configuration.yaml +++ b/examples/v1/full_configuration.yaml @@ -23,6 +23,7 @@ phases: - name: A - name: B - name: C + - name: M - name: ethanol diffusion coefficient [m2 s-1]: 2.1e-5 - name: H2O2 @@ -93,14 +94,14 @@ reactions: Fc: 1.3 N: 32.1 reactants: - - species name: bar + - species name: A coefficient: 1 - - species name: baz + - species name: B coefficient: 1 products: - - species name: bar + - species name: B coefficient: 0.5 - - species name: foo + - species name: C coefficient: 0.3 - type: BRANCHED_NO_RO2 name: my branched @@ -182,6 +183,16 @@ reactions: - 0.1 - -0.01 gas phase: gas + reactants: + - species name: B + coefficient: 1 + products: + - species name: C + coefficient: 1 + - type: LAMBDA_RATE_CONSTANT + name: my lambda rate constant + gas phase: gas + lambda function: "[](double T, double P) { return 1.2e-5 * exp(-500.0 / T); }" reactants: - species name: B coefficient: 1 diff --git a/include/mechanism_configuration/development/mechanism.hpp b/include/mechanism_configuration/development/mechanism.hpp deleted file mode 100644 index 01ec4ccd..00000000 --- a/include/mechanism_configuration/development/mechanism.hpp +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include - -#include - -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - namespace types - { - - /// @brief Represents a full mechanism definition - struct Mechanism : public ::mechanism_configuration::Mechanism - { - /// @brief Mechanism name (optional) - std::string name; - /// @brief Species list - std::vector species; - /// @brief Phases list - std::vector phases; - /// @brief Represents a collection of different reaction types, each stored in a vector - /// corresponding to a specific mechanism - Reactions reactions; - /// @brief Represents a general model (optional) - Models models; - }; - - } // namespace types - - class Parser - { - public: - Parser() = default; - - /// @brief Load a YAML file and return its root node - /// @throws std::runtime_error If the file is missing, not a regular file, or cannot be parsed - YAML::Node FileToYaml(const std::filesystem::path& config_path); - - /// @brief Validates mechanism YAML node. - /// @param object The YAML node to validate - /// @param read_from_config_file Whether to use the provided config path or the default - /// @return A collection of validation errors; empty if the node is valid - Errors Validate(const YAML::Node& object, bool read_from_config_file = true); - - /// @brief Constructs a Mechanism object from the provided YAML node - /// @note Must be called only after successful validation - types::Mechanism Parse(const YAML::Node& object); - - inline void SetConfigPath(const std::string& config_path) - { - config_path_ = config_path; - } - - private: - std::string config_path_; - - inline void SetDefaultConfigPath() - { - config_path_ = ""; - } - }; - - } // namespace development -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/development/model_parsers.hpp b/include/mechanism_configuration/development/model_parsers.hpp deleted file mode 100644 index 7952f693..00000000 --- a/include/mechanism_configuration/development/model_parsers.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include - -#include - -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Abstract interface for model parsers - class IModelParser - { - public: - /// @brief Validates a YAML node representing a model - /// @param object The YAML node containing model information - /// @param existing_phases A list of chemical phases - /// @return A list of any validation errors encountered - virtual Errors Validate(const YAML::Node& object, const std::vector& existing_phases) = 0; - - /// @brief Parses a YAML node representing a model and populate the models object - /// @param object The YAML node containing model information - /// @param models The container to which the parsed models will be added - virtual void Parse(const YAML::Node& object, types::Models& models) = 0; - - /// @brief Destructor - virtual ~IModelParser() = default; - }; - - /// @brief Parser for gas-phase models - class GasModelParser : public IModelParser - { - public: - Errors Validate(const YAML::Node& object, const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Models& models) override; - }; - - /// @brief Parser for modal aerosol models - class ModalModelParser : public IModelParser - { - public: - Errors Validate(const YAML::Node& object, const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Models& models) override; - }; - - /// @brief Returns a static map of model type keys to their parser instances - inline std::map>& GetModelParserMap() - { - static std::map> model_parsers = [] - { - std::map> map; - map[validation::GasModel_key] = std::make_unique(); - map[validation::ModalModel_key] = std::make_unique(); - return map; - }(); - - return model_parsers; - } - - } // namespace development -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/development/model_types.hpp b/include/mechanism_configuration/development/model_types.hpp deleted file mode 100644 index 12a04d9a..00000000 --- a/include/mechanism_configuration/development/model_types.hpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - namespace types - { - - /// @brief Represents gas model - struct GasModel - { - std::string name; - std::string type; - std::string phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - /// @brief Represents a single mode with log-normal size distribution - struct Mode - { - std::string name; - double geometric_mean_diameter; - double geometric_standard_deviation; - std::string phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - /// @brief Models a collection of multiple modes - struct ModalModel - { - std::string name; - std::string type; - std::vector modes; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - /// @brief Represents a collection of different model types - struct Models - { - GasModel gas_model; - ModalModel modal_model; - }; - } // namespace types - } // namespace development -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/development/reaction_parsers.hpp b/include/mechanism_configuration/development/reaction_parsers.hpp deleted file mode 100644 index f70b9fb6..00000000 --- a/include/mechanism_configuration/development/reaction_parsers.hpp +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include - -#include - -#include - -namespace mechanism_configuration -{ - namespace development - { - - /// @brief Abstract interface for reaction parsers - class IReactionParser - { - public: - /// @brief Validates a YAML node representing a chemical reaction - /// @param object The YAML node containing reaction information - /// @param existing_species A list of species previously defined in the mechanism - /// @param existing_phases A list of chemical phases relevant to the reaction - /// @return A list of any validation errors encountered - virtual Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) = 0; - - /// @brief Parses a YAML node representing a chemical reaction - /// @param object The YAML node containing reaction information - /// @param reactions The container to which the parsed reactions will be added - virtual void Parse(const YAML::Node& object, types::Reactions& reactions) = 0; - - /// @brief Destructor - virtual ~IReactionParser() = default; - }; - - class ArrheniusParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class BranchedParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class CondensedPhaseArrheniusParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class CondensedPhasePhotolysisParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class EmissionParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class FirstOrderLossParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class SimpolPhaseTransferParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class AqueousEquilibriumParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class WetDepositionParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class HenrysLawParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class PhotolysisParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class SurfaceParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class TaylorSeriesParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class TroeParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class TernaryChemicalActivationParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class TunnelingParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class UserDefinedParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - class LambdaRateConstantParser : public IReactionParser - { - public: - Errors Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) override; - - void Parse(const YAML::Node& object, types::Reactions& reactions) override; - }; - - /// @brief Returns a static map of reaction type keys to their parser instances - inline std::map>& GetReactionParserMap() - { - static std::map> reaction_parsers = [] - { - std::map> map; - map[validation::Arrhenius_key] = std::make_unique(); - map[validation::HenrysLaw_key] = std::make_unique(); - map[validation::WetDeposition_key] = std::make_unique(); - map[validation::AqueousPhaseEquilibrium_key] = std::make_unique(); - map[validation::SimpolPhaseTransfer_key] = std::make_unique(); - map[validation::FirstOrderLoss_key] = std::make_unique(); - map[validation::Emission_key] = std::make_unique(); - map[validation::CondensedPhasePhotolysis_key] = std::make_unique(); - map[validation::Photolysis_key] = std::make_unique(); - map[validation::Surface_key] = std::make_unique(); - map[validation::TaylorSeries_key] = std::make_unique(); - map[validation::Tunneling_key] = std::make_unique(); - map[validation::Branched_key] = std::make_unique(); - map[validation::Troe_key] = std::make_unique(); - map[validation::TernaryChemicalActivation_key] = std::make_unique(); - map[validation::CondensedPhaseArrhenius_key] = std::make_unique(); - map[validation::UserDefined_key] = std::make_unique(); - map[validation::LambdaRateConstant_key] = std::make_unique(); - return map; - }(); - - return reaction_parsers; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/development/reaction_types.hpp b/include/mechanism_configuration/development/reaction_types.hpp deleted file mode 100644 index a820537c..00000000 --- a/include/mechanism_configuration/development/reaction_types.hpp +++ /dev/null @@ -1,402 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - namespace types - { - - struct Arrhenius - { - /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] - double A{ 1 }; - /// @brief Unitless exponential factor - double B{ 0 }; - /// @brief Activation threshold, expected to be the negative activation energy divided by the boltzman constant - /// [-E_a / k_b), K] - double C{ 0 }; - /// @brief A factor that determines temperature dependence [K] - double D{ 300 }; - /// @brief A factor that determines pressure dependence [Pa-1] - double E{ 0 }; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Branched - { - /// @brief pre-exponential factor - double X; - /// @brief exponential factor - double Y; - /// @brief branching factor - double a0; - /// @brief number of heavy atoms in the RO2 reacting species (excluding the peroxy moiety) - int n; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of nitrate products - std::vector nitrate_products; - /// @brief A list of alkoxy products - std::vector alkoxy_products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct CondensedPhaseArrhenius - { - /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] - double A{ 1 }; - /// @brief Unitless exponential factor - double B{ 0 }; - /// @brief Activation threshold, expected to be the negative activation energy divided by the boltzman constant - /// [-E_a / k_b), K] - double C{ 0 }; - /// @brief A factor that determines temperature dependence [K] - double D{ 300 }; - /// @brief A factor that determines pressure dependence [Pa-1] - double E{ 0 }; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier for the condensed phase where this reaction occurs - std::string condensed_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct CondensedPhasePhotolysis - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief A single reactant - ReactionComponent reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier for the condensed phase where this reaction occurs - std::string condensed_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Emission - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct FirstOrderLoss - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief A single reactant - ReactionComponent reactants; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct SimpolPhaseTransfer - { - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief The species in the gas phase participating in this reaction - std::vector gas_phase_species; - /// @brief An identifier for the condensed phase where this reaction occurs - std::string condensed_phase; - /// @brief The species in the condensed phase participating in this reaction - std::vector condensed_phase_species; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief The 4 SIMPOL parameters - std::array B; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct AqueousEquilibrium - { - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier for the condensed phase where this reaction occurs - std::string condensed_phase; - /// @brief Name for condensed-phase water - std::string condensed_phase_water; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief Pre-exponential factor (s-1) - double A{ 1 }; - /// @brief A constant - double C{ 0 }; - /// @brief Reverse reation rate constant (s-1) - double k_reverse{ 0 }; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct WetDeposition - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier for the condensed phase where this reaction occurs - std::string condensed_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct HenrysLaw - { - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief Represents the composition of a gas mixture - Phase gas; - /// @brief Represents a particle within a solution, including its phase and chemical composition - Particle particle; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Photolysis - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief A single reactant - ReactionComponent reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Surface - { - /// @brief Reaction probability (0-1) [unitless] - double reaction_probability{ 1.0 }; - /// @brief A single gas-phase species - ReactionComponent gas_phase_species; - /// @brief A list of products - std::vector gas_phase_products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief An identifier for the condensed phase where this reaction occurs - std::string condensed_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct TaylorSeries - { - /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] - double A{ 1 }; - /// @brief Unitless exponential factor - double B{ 0 }; - /// @brief Activation threshold, expected to be the negative activation energy divided by the boltzman constant - /// [-E_a / k_b), K] - double C{ 0 }; - /// @brief A factor that determines temperature dependence [K] - double D{ 300 }; - /// @brief A factor that determines pressure dependence [Pa-1] - double E{ 0 }; - /// @brief An array of coefficients for the Taylor series expansion - std::vector taylor_coefficients{ 1.0 }; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Troe - { - /// @brief low-pressure pre-exponential factor - double k0_A = 1.0; - /// @brief low-pressure temperature-scaling parameter - double k0_B = 0.0; - /// @brief low-pressure exponential factor - double k0_C = 0.0; - /// @brief high-pressure pre-exponential factor - double kinf_A = 1.0; - /// @brief high-pressure temperature-scaling parameter - double kinf_B = 0.0; - /// @brief high-pressure exponential factor - double kinf_C = 0.0; - /// @brief Troe F_c parameter - double Fc = 0.6; - /// @brief Troe N parameter - double N = 1.0; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct TernaryChemicalActivation - { - /// @brief low-pressure pre-exponential factor - double k0_A = 1.0; - /// @brief low-pressure temperature-scaling parameter - double k0_B = 0.0; - /// @brief low-pressure exponential factor - double k0_C = 0.0; - /// @brief high-pressure pre-exponential factor - double kinf_A = 1.0; - /// @brief high-pressure temperature-scaling parameter - double kinf_B = 0.0; - /// @brief high-pressure exponential factor - double kinf_C = 0.0; - /// @brief TernaryChemicalActivation F_c parameter - double Fc = 0.6; - /// @brief TernaryChemicalActivation N parameter - double N = 1.0; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Tunneling - { - /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] - double A = 1.0; - /// @brief Linear temperature-dependent parameter [K] - double B = 0.0; - /// @brief Cubed temperature-dependent parameter [K^3] - double C = 0.0; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct UserDefined - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct LambdaRateConstant - { - /// @brief A lambda function as a string, expected to be a function of temperature (T) and optionally pressure (P) - std::string lambda_function; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - /// @brief Represents a collection of different reaction types - struct Reactions - { - std::vector arrhenius; - std::vector branched; - std::vector condensed_phase_arrhenius; - std::vector condensed_phase_photolysis; - std::vector emission; - std::vector first_order_loss; - std::vector simpol_phase_transfer; - std::vector aqueous_equilibrium; - std::vector wet_deposition; - std::vector henrys_law; - std::vector photolysis; - std::vector surface; - std::vector taylor_series; - std::vector troe; - std::vector ternary_chemical_activation; - std::vector tunneling; - std::vector user_defined; - std::vector lambda_rate_constant; - }; - - } // namespace types - } // namespace development -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/development/type_parsers.hpp b/include/mechanism_configuration/development/type_parsers.hpp deleted file mode 100644 index 080df5c3..00000000 --- a/include/mechanism_configuration/development/type_parsers.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include - -#include - -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Parses a YAML node into a vector of Species - /// The input must be validated using ValidateSpecies(). - /// This function assumes the structure and types are correct. - /// @param objects YAML node representing species list - /// @return A vector of parsed species - std::vector ParseSpecies(const YAML::Node& objects); - - /// @brief Parses a YAML node into a vector of Phases - /// Extracts each phase's name and its associated species (including optional properties). - /// Assumes the input YAML has already been validated for required structure and keys. - /// @param objects YAML node representing phase list - /// @return A vector of parsed Phases - std::vector ParsePhases(const YAML::Node& objects); - - /// @brief Parses a YAML node into reaction components - /// @param object YAML node representing ReactionComponents - /// @param key Key of the sequence to parse - /// @return Vector of `types::ReactionComponent` with names, optional coefficients, and comments - std::vector ParseReactionComponents(const YAML::Node& object, const std::string& key); - - /// @brief Parses a single reaction component from a YAML node. - /// The parser performs no validation or error checking. - /// @param object YAML node representing ReactionComponents - /// @param key Key identifying the reaction component - /// @return The parsed `types::ReactionComponent`, or a default-constructed one if none found - types::ReactionComponent ParseReactionComponent(const YAML::Node& object, const std::string& key); - - /// @brief Parses a collection of YAML nodes into reaction objects - /// Iterates over the given YAML nodes, identifies the parser for each reaction type, - /// and populates a `types::Reactions` container with the parsed reactions. - /// @param objects YAML node containing multiple reaction definitions - /// @return A `types::Reactions` object with all successfully parsed reactions - types::Reactions ParseReactions(const YAML::Node& objects); - - /// @brief Parses a collection of YAML nodes into model objects - /// Iterates over the given YAML nodes, identifies the parser for each model type, - /// and populates a `types::Models` container with the parsed models. - /// @param objects YAML node containing multiple model definitions - /// @return A `types::Models` object with all successfully parsed models - types::Models ParseModels(const YAML::Node& objects); - - } // namespace development -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/development/type_validators.hpp b/include/mechanism_configuration/development/type_validators.hpp deleted file mode 100644 index f8c1593e..00000000 --- a/include/mechanism_configuration/development/type_validators.hpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a list of species definitions from a YAML node. - /// This function checks each species object in the input YAML list to ensure that: - /// - All required keys are present - /// - Optional keys are properly handled - /// - No duplicate species names exist - /// @param species_list YAML node containing species entries - /// @return List of validation errors, or empty if all entries are valid - Errors ValidateSpecies(const YAML::Node& species_list); - - /// @brief Validates the structure and content of phase definitions in a YAML node. - /// Performs schema validation for each phase and its associated species. - /// - All required keys are present - /// - Detects duplicate species within a single phase - /// - Detects species not defined in the existing_species list - /// - Detects duplicate phase names - /// @param phases_list YAML node containing the list of phase entries - /// @param existing_species List of defined species to validate against - /// @return List of validation errors, or empty if all entries are valid - Errors ValidatePhases(const YAML::Node& phases_list, const std::vector& existing_species); - - /// @brief Validates the content of reactants or products definitions in a YAML node - /// @param list YAML node representing a sequence of reactants or products. - /// @return List of validation errors, or empty if all entries are valid - Errors ValidateReactantsOrProducts(const YAML::Node& object); - - /// @brief Validates a list of particle definitions in a YAML node - /// @param list YAML node containing particle - /// @return List of validation errors, or empty if all entries are valid - Errors ValidateParticles(const YAML::Node& list); - - /// @brief Validates a YAML list of reactions for type correctness and supported schema. - /// Performs a two-pass validation over the reaction list. The first pass checks that each - /// reaction has a defined and recognized type. The second pass validates the content of - /// reactions using their respective parser. - /// @param reactions_list YAML node containing the list of reactions - /// @param existing_species List of known species to validate species references - /// @param existing_phases List of known phases to validate phase references - /// @return list of validation errors, if any - Errors ValidateReactions( - const YAML::Node& reactions_list, - const std::vector& existing_species, - const std::vector& existing_phases); - - /// @brief Validates a list of model definitions in a YAML node - /// @param models_list YAML node containing the list of models - /// @param existing_phases List of known phases to validate phase references - /// @return list of validation errors, if any - Errors ValidateModels(const YAML::Node& models_list, const std::vector& existing_phases); - - } // namespace development -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/development/types.hpp b/include/mechanism_configuration/development/types.hpp deleted file mode 100644 index bfc88fd3..00000000 --- a/include/mechanism_configuration/development/types.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - namespace types - { - - struct Species - { - std::string name; - std::optional absolute_tolerance; - std::optional diffusion_coefficient; - std::optional molecular_weight; - std::optional henrys_law_constant_298; - std::optional henrys_law_constant_exponential_factor; - std::optional n_star; - std::optional density; - std::optional tracer_type; - std::optional constant_concentration; - std::optional constant_mixing_ratio; - std::optional is_third_body; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - Errors validate(); - }; - - struct PhaseSpecies - { - std::string name; - std::optional diffusion_coefficient; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Phase - { - std::string name; - std::vector species; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct ReactionComponent - { - std::string name; - double coefficient{ 1.0 }; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Particle - { - /// @brief Describes the physical state of the particle - std::string phase; - /// @brief Lists the chemical species dissolved in the solvent - std::vector solutes; - /// @brief Specifies the liquid medium in which solutes are dissolved - ReactionComponent solvent; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - } // namespace types - } // namespace development -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/development/utils.hpp b/include/mechanism_configuration/development/utils.hpp deleted file mode 100644 index 2009a327..00000000 --- a/include/mechanism_configuration/development/utils.hpp +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - struct NodeInfo - { - std::string name; - YAML::Node nodes; - }; - - struct DuplicateEntryInfo - { - std::string name; - std::vector nodes; - }; - - /// @brief Ensures a YAML node is treated as a sequence - /// @param node The YAML node to convert - /// @return A YAML sequence node containing the original node(s) - YAML::Node AsSequence(const YAML::Node& node); - - void AppendFilePath(const std::string& config_path, Errors& errors); - - std::unordered_map GetComments(const YAML::Node& object); - - /// @brief Extract species names from a vector of PhaseSpecies - std::vector GetSpeciesNames(const std::vector& phase_species); - - void ReportUnknownSpecies( - const YAML::Node& object, - const std::vector& unknown_species, - Errors& errors, - const ConfigParseStatus& parser_status = ConfigParseStatus::UnknownSpecies); - - std::optional> CheckPhaseExists( - const YAML::Node& object, - const std::string& phase_key, - const std::vector& existing_phases, - Errors& errors, - const ConfigParseStatus& parser_status = ConfigParseStatus::UnknownPhase, - std::string type = {}); - - void CheckSpeciesPresenceInPhase( - const YAML::Node& object, - const types::Phase& phase, - const std::vector>& species_node_pairs, - Errors& errors, - const ConfigParseStatus& parser_status = ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase); - - template - std::vector FindDuplicateObjectsByName(const std::vector>& collection) - { - std::unordered_map> name_to_nodes; - - if constexpr (std::is_same_v) - { - for (const auto& [elem, node] : collection) - { - name_to_nodes[elem].push_back(node); - } - } - else - { - for (const auto& [elem, node] : collection) - { - name_to_nodes[elem.name].push_back(node); - } - } - - std::vector duplicates; - - for (const auto& [name, nodes] : name_to_nodes) - { - if (nodes.size() > 1) - { - duplicates.push_back({ name, nodes }); - } - } - - return duplicates; - } - - template - std::vector FindUnknownObjectsByName( - const std::vector& existing_objects, - std::vector>& requested_objects) - { - std::unordered_set existing_names; - - if constexpr (std::is_same_v) - { - for (const auto& name : existing_objects) - { - existing_names.insert(name); - } - } - else - { - for (const auto& object : existing_objects) - { - existing_names.insert(object.name); - } - } - - std::vector unknowns; - - if constexpr (std::is_same_v) - { - for (const auto& [name, node] : requested_objects) - { - if (existing_names.find(name) == existing_names.end()) - { - unknowns.emplace_back(name, node); - } - } - } - else - { - for (const auto& [elem, node] : requested_objects) - { - const auto& name = elem.name; - if (existing_names.find(name) == existing_names.end()) - { - unknowns.emplace_back(name, node); - } - } - } - - return unknowns; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/development/validation.hpp b/include/mechanism_configuration/development/validation.hpp deleted file mode 100644 index fc949365..00000000 --- a/include/mechanism_configuration/development/validation.hpp +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -namespace mechanism_configuration -{ - namespace development - { - namespace validation - { - // Shared, but also Mechanism - static constexpr const char* version = "version"; - static constexpr const char* name = "name"; - - // Configuration - static constexpr const char* species = "species"; - static constexpr const char* phases = "phases"; - static constexpr const char* models = "models"; - static constexpr const char* reactions = "reactions"; - - // Species - static constexpr const char* absolute_tolerance = "absolute tolerance"; - static constexpr const char* diffusion_coefficient = "diffusion coefficient [m2 s-1]"; - static constexpr const char* molecular_weight = "molecular weight [kg mol-1]"; - static constexpr const char* henrys_law_constant_298 = "HLC(298K) [mol m-3 Pa-1]"; - static constexpr const char* henrys_law_constant_exponential_factor = "HLC exponential factor [K]"; - static constexpr const char* phase = "phase"; - static constexpr const char* n_star = "N star"; - static constexpr const char* density = "density [kg m-3]"; - static constexpr const char* tracer_type = "tracer type"; - static constexpr const char* constant_concentration = "constant concentration [mol m-3]"; - static constexpr const char* constant_mixing_ratio = "constant mixing ratio [mol mol-1]"; - static constexpr const char* is_third_body = "is third body"; - static constexpr const char* third_body = "THIRD_BODY"; - - // Reactions - static constexpr const char* reactants = "reactants"; - static constexpr const char* products = "products"; - static constexpr const char* type = "type"; - static constexpr const char* gas_phase = "gas phase"; - - // Reactant and product - static constexpr const char* coefficient = "coefficient"; - // also name - - // ---------------------------------------- - // Reaction types - // ---------------------------------------- - - // Arrhenius - static constexpr const char* Arrhenius_key = "ARRHENIUS"; - static constexpr const char* A = "A"; - static constexpr const char* B = "B"; - static constexpr const char* C = "C"; - static constexpr const char* D = "D"; - static constexpr const char* E = "E"; - static constexpr const char* Ea = "Ea"; - - // TaylorSeries - static constexpr const char* TaylorSeries_key = "TAYLOR_SERIES"; - static constexpr const char* taylor_coefficients = "taylor coefficients"; - // also these - // A - // B - // C - // D - // E - // Ea - - // Condensed Phase Arrhenius - static constexpr const char* CondensedPhaseArrhenius_key = "CONDENSED_PHASE_ARRHENIUS"; - // also these - // condensed phase - // A - // B - // C - // D - // E - // Ea - - // Troe - static constexpr const char* Troe_key = "TROE"; - static constexpr const char* k0_A = "k0_A"; - static constexpr const char* k0_B = "k0_B"; - static constexpr const char* k0_C = "k0_C"; - static constexpr const char* kinf_A = "kinf_A"; - static constexpr const char* kinf_B = "kinf_B"; - static constexpr const char* kinf_C = "kinf_C"; - static constexpr const char* Fc = "Fc"; - static constexpr const char* N = "N"; - - // Ternary Chemical Activation - static constexpr const char* TernaryChemicalActivation_key = "TERNARY_CHEMICAL_ACTIVATION"; - // also k0_A - // k0_B - // k0_C - // kinf_A - // kinf_B - // kinf_C - // Fc - // N - - // Branched - static constexpr const char* Branched_key = "BRANCHED_NO_RO2"; - static constexpr const char* X = "X"; - static constexpr const char* Y = "Y"; - static constexpr const char* a0 = "a0"; - static constexpr const char* n = "n"; - static constexpr const char* nitrate_products = "nitrate products"; - static constexpr const char* alkoxy_products = "alkoxy products"; - - // Tunneling - static constexpr const char* Tunneling_key = "TUNNELING"; - // also these, but they are defined above - // A - // B - // C - - // Surface - static constexpr const char* Surface_key = "SURFACE"; - static constexpr const char* reaction_probability = "reaction probability"; - static constexpr const char* gas_phase_species = "gas-phase species"; - static constexpr const char* gas_phase_products = "gas-phase products"; - static constexpr const char* condensed_phase = "condensed phase"; - - // Photolysis - static constexpr const char* Photolysis_key = "PHOTOLYSIS"; - static constexpr const char* scaling_factor = "scaling factor"; - - // Condensed Phae Photolysis - static constexpr const char* CondensedPhasePhotolysis_key = "CONDENSED_PHASE_PHOTOLYSIS"; - // also - // scaling factor - // condensed phase - - // Emissions - static constexpr const char* Emission_key = "EMISSION"; - // also scaling factor - - // First Order Loss - static constexpr const char* FirstOrderLoss_key = "FIRST_ORDER_LOSS"; - // also scaling factor - - // Simpol Phase Transfer - static constexpr const char* SimpolPhaseTransfer_key = "SIMPOL_PHASE_TRANSFER"; - static constexpr const char* condensed_phase_species = "condensed-phase species"; - // also - // gas phase - // gas-phase species - // condensed phase - // condensed-phase species - // B - - // Aqueous Equilibrium - static constexpr const char* AqueousPhaseEquilibrium_key = "AQUEOUS_EQUILIBRIUM"; - static constexpr const char* condensed_phase_water = "condensed-phase water"; - // also - // condensed phase - // A - // C - static constexpr const char* k_reverse = "k_reverse"; - - // Wet Deposition - static constexpr const char* WetDeposition_key = "WET_DEPOSITION"; - // also - // scaling factor - // condensed phase - - // Henry's Law Phase Transfer - static constexpr const char* HenrysLaw_key = "HL_PHASE_TRANSFER"; - static constexpr const char* gas = "gas"; - static constexpr const char* particle = "particle"; - static constexpr const char* solutes = "solutes"; - static constexpr const char* solvent = "solvent"; - // also - // phase - // species - - // User Defined - static constexpr const char* UserDefined_key = "USER_DEFINED"; - // also - // gas phase - // reactants - // products - // scaling factor - - // Lambda Rate Constant - static constexpr const char* LambdaRateConstant_key = "LAMBDA_RATE_CONSTANT"; - static constexpr const char* lambda_function = "lambda function"; - // also - // gas phase - // reactants - // products - // name - - // ---------------------------------------- - // Model types - // ---------------------------------------- - // Gas model - static constexpr const char* GasModel_key = "GAS_PHASE"; - // also - // name - // phases - - // Modal model - static constexpr const char* ModalModel_key = "MODAL"; - static constexpr const char* modes = "modes"; - static constexpr const char* geometric_mean_diameter = "geometric mean diameter [m]"; - static constexpr const char* geometric_standard_deviation = "geometric standard deviation"; - // also - // name - // phase - - } // namespace validation - } // namespace development -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/error_location.hpp b/include/mechanism_configuration/error_location.hpp deleted file mode 100644 index 7d4edf48..00000000 --- a/include/mechanism_configuration/error_location.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include - -namespace mechanism_configuration -{ - struct ErrorLocation - { - int line, column; - - /// @brief Constructor that adjusts 0-based indices to 1-based - /// @param line_number 0-based line number (from YAML::Mark) - /// @param column_number 0-based column number (from YAML::Mark) - ErrorLocation(int line_number, int column_number) - : line(line_number + 1), - column(column_number + 1) - { - } - }; -} // namespace mechanism_configuration - -#ifdef MECH_CONFIG_USE_FMT -template<> -struct fmt::formatter -{ - constexpr auto parse(fmt::format_parse_context& ctx) const - { - return ctx.begin(); - } - template - auto format(const mechanism_configuration::ErrorLocation& loc, FormatContext& ctx) const - { - return fmt::format_to(ctx.out(), "{}:{}", loc.line, loc.column); - } -}; -#else -template<> -struct std::formatter -{ - constexpr auto parse(std::format_parse_context& ctx) const - { - return ctx.begin(); - } - template - auto format(const mechanism_configuration::ErrorLocation& loc, FormatContext& ctx) const - { - return std::format_to(ctx.out(), "{}:{}", loc.line, loc.column); - } -}; -#endif \ No newline at end of file diff --git a/include/mechanism_configuration/errors.hpp b/include/mechanism_configuration/errors.hpp index a49235d6..a838f9ea 100644 --- a/include/mechanism_configuration/errors.hpp +++ b/include/mechanism_configuration/errors.hpp @@ -4,13 +4,94 @@ #pragma once -#include +#include +#include #include #include #include namespace mechanism_configuration { - using Errors = std::vector>; -} // namespace mechanism_configuration \ No newline at end of file + struct ErrorLocation + { + int line, column; + + /// @brief Constructor that adjusts 0-based indices to 1-based + /// @param line_number 0-based line number (from YAML::Mark) + /// @param column_number 0-based column number (from YAML::Mark) + ErrorLocation(int line_number, int column_number) + : line(line_number + 1), + column(column_number + 1) + { + } + }; + + enum class ErrorCode + { + Success, + None, + InvalidKey, + UnknownKey, + InvalidFilePath, + ObjectTypeNotFound, + RequiredKeyNotFound, + MutuallyExclusiveOption, + DuplicateSpeciesDetected, + DuplicatePhasesDetected, + DuplicateSpeciesInPhaseDetected, + PhaseRequiresUnknownSpecies, + ReactionRequiresUnknownSpecies, + UnknownSpecies, + UnknownPhase, + RequestedSpeciesNotRegisteredInPhase, + TooManyReactionComponents, + InvalidVersion, + MissingVersionField, + InvalidType, + UnknownType, + FileNotFound, + UnexpectedError, + EmptyObject, + }; + + std::string ErrorCodeToString(const ErrorCode& status); + + // For Google Test printing + inline void PrintTo(const ErrorCode& status, std::ostream* os) + { + *os << ErrorCodeToString(status); + } + + using Errors = std::vector>; +} // namespace mechanism_configuration + +#ifdef MECH_CONFIG_USE_FMT +template<> +struct fmt::formatter +{ + constexpr auto parse(fmt::format_parse_context& ctx) const + { + return ctx.begin(); + } + template + auto format(const mechanism_configuration::ErrorLocation& loc, FormatContext& ctx) const + { + return fmt::format_to(ctx.out(), "{}:{}", loc.line, loc.column); + } +}; +#else +template<> +struct std::formatter +{ + constexpr auto parse(std::format_parse_context& ctx) const + { + return ctx.begin(); + } + template + auto format(const mechanism_configuration::ErrorLocation& loc, FormatContext& ctx) const + { + return std::format_to(ctx.out(), "{}:{}", loc.line, loc.column); + } +}; +#endif \ No newline at end of file diff --git a/include/mechanism_configuration/mechanism.hpp b/include/mechanism_configuration/mechanism.hpp index f1088339..2c656adc 100644 --- a/include/mechanism_configuration/mechanism.hpp +++ b/include/mechanism_configuration/mechanism.hpp @@ -4,7 +4,7 @@ #pragma once -#include +#include #include #include @@ -13,7 +13,7 @@ namespace mechanism_configuration { -// Trying to build on linux for the python release, I learned that glibc had a bug which defined + // Trying to build on linux for the python release, I learned that glibc had a bug which defined // a macro called major and minor. This caused a conflict with the Version struct. To fix this, I // undefine the macros before defining the struct and then redefine them after the struct. // https://stackoverflow.com/a/22253389/5217293 @@ -74,20 +74,21 @@ namespace mechanism_configuration #pragma pop_macro("minor") #pragma pop_macro("major") + /// @brief Represents a full mechanism definition struct Mechanism { + /// @brief Mechanism name (optional) + std::string name; + /// @brief Species list + std::vector species; + /// @brief Phases list + std::vector phases; + /// @brief Represents a collection of different reaction types, each stored in a vector + /// corresponding to a specific mechanism + types::Reactions reactions; + /// @brief Version of the mechanism configuration format used, in major.minor.patch format Version version; - - Mechanism(Version version) - : version(version) - { - } - Mechanism() - : version() - { - } - virtual ~Mechanism() = default; + /// @brief Relative tolerance for solver (optional, default: 1e-6) + double relative_tolerance{ 1e-6 }; }; - - using GlobalMechanism = ::mechanism_configuration::Mechanism; } // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/mechanism_configuration.hpp b/include/mechanism_configuration/mechanism_configuration.hpp new file mode 100644 index 00000000..db2e42a5 --- /dev/null +++ b/include/mechanism_configuration/mechanism_configuration.hpp @@ -0,0 +1,13 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include +#include +#include +#include +#include +#include diff --git a/include/mechanism_configuration/parse.hpp b/include/mechanism_configuration/parse.hpp new file mode 100644 index 00000000..ee3d3849 --- /dev/null +++ b/include/mechanism_configuration/parse.hpp @@ -0,0 +1,20 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include +#include + +namespace mechanism_configuration +{ + /// @brief Parse a mechanism configuration file, dispatching on its version. + /// @param config_path Path to a configuration file (a std::string converts implicitly), + /// or a directory of version-0 CAMP files. + /// @return The parsed Mechanism, or all structural and semantic errors encountered. + std::expected Parse(const std::filesystem::path& config_path); +} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/parse_status.hpp b/include/mechanism_configuration/parse_status.hpp deleted file mode 100644 index 51a04d7d..00000000 --- a/include/mechanism_configuration/parse_status.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -namespace mechanism_configuration -{ - enum class ConfigParseStatus - { - Success, - None, - InvalidKey, - UnknownKey, - InvalidFilePath, - ObjectTypeNotFound, - RequiredKeyNotFound, - MutuallyExclusiveOption, - DuplicateSpeciesDetected, - DuplicatePhasesDetected, - DuplicateSpeciesInPhaseDetected, - PhaseRequiresUnknownSpecies, - ReactionRequiresUnknownSpecies, - UnknownSpecies, - UnknownPhase, - RequestedSpeciesNotRegisteredInPhase, - TooManyReactionComponents, - InvalidIonPair, - InvalidVersion, - MissingVersionField, - InvalidParameterNumber, - InvalidType, - UnknownType, - FileNotFound, - UnexpectedError, - EmptyObject, - }; - - std::string configParseStatusToString(const ConfigParseStatus& status); - - // For Google Test printing - inline void PrintTo(const ConfigParseStatus& status, std::ostream* os) - { - *os << configParseStatusToString(status); - } -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/parser.hpp b/include/mechanism_configuration/parser.hpp deleted file mode 100644 index 1b0a020b..00000000 --- a/include/mechanism_configuration/parser.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include - -namespace mechanism_configuration -{ - struct VersionInfo - { - unsigned int version; // major version - Errors errors; - }; - - class UniversalParser - { - public: - /// @brief Extracts the major version from the given configuration file - /// @return VersionInfo containing the version and validation errors - VersionInfo GetVersion(const std::filesystem::path& config_path); - - /// @brief Parses a configuration file using the appropriate versioned parser. - /// Determines the configuration version and calls the corresponding parser - /// implementation. If the version field is missing, the function falls - /// back to the version 0 parser. - /// @param config_path Path to the YAML configuration file - /// @return ParserResult containing the parsed GlobalMechanism on success, - /// or a list of accumulated errors on failure - ParserResult Parse(const std::filesystem::path& config_path); - }; -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/parser_result.hpp b/include/mechanism_configuration/parser_result.hpp deleted file mode 100644 index 8615ac22..00000000 --- a/include/mechanism_configuration/parser_result.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - - template - struct ParserResult - { - std::unique_ptr mechanism = nullptr; - Errors errors; - - bool has_errors() const - { - return !errors.empty(); - } - - operator bool() const - { - return mechanism != nullptr && errors.empty(); - } - - MechanismType& operator*() - { - return *mechanism; - } - }; -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/types.hpp b/include/mechanism_configuration/types.hpp new file mode 100644 index 00000000..fb568711 --- /dev/null +++ b/include/mechanism_configuration/types.hpp @@ -0,0 +1,329 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace mechanism_configuration::types +{ + + struct Species + { + std::string name; + std::optional absolute_tolerance; + std::optional diffusion_coefficient; + std::optional molecular_weight; + std::optional henrys_law_constant_298; + std::optional henrys_law_constant_exponential_factor; + std::optional n_star; + std::optional density; + std::optional tracer_type; + std::optional constant_concentration; + std::optional constant_mixing_ratio; + std::optional is_third_body; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct PhaseSpecies + { + std::string name; + std::optional diffusion_coefficient; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct Phase + { + std::string name; + std::vector species; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct ReactionComponent + { + std::string name; + double coefficient{ 1.0 }; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct Arrhenius + { + /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] + double A{ 1 }; + /// @brief Unitless exponential factor + double B{ 0 }; + /// @brief Activation threshold, expected to be the negative activation energy divided by the boltzman constant + /// [-E_a / k_b), K] + double C{ 0 }; + /// @brief A factor that determines temperature dependence [K] + double D{ 300 }; + /// @brief A factor that determines pressure dependence [Pa-1] + double E{ 0 }; + /// @brief A list of reactants + std::vector reactants; + /// @brief A list of products + std::vector products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct Branched + { + /// @brief pre-exponential factor + double X; + /// @brief exponential factor + double Y; + /// @brief branching factor + double a0; + /// @brief number of heavy atoms in the RO2 reacting species (excluding the peroxy moiety) + int n; + /// @brief A list of reactants + std::vector reactants; + /// @brief A list of nitrate products + std::vector nitrate_products; + /// @brief A list of alkoxy products + std::vector alkoxy_products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct Emission + { + /// @brief Scaling factor to apply to user-provided rate constants + double scaling_factor{ 1.0 }; + /// @brief A list of products + std::vector products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct FirstOrderLoss + { + /// @brief Scaling factor to apply to user-provided rate constants + double scaling_factor{ 1.0 }; + /// @brief A single reactant + ReactionComponent reactants; + /// @brief A list of products, optional for first-order loss reactions + std::vector products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct Photolysis + { + /// @brief Scaling factor to apply to user-provided rate constants + double scaling_factor{ 1.0 }; + /// @brief A single reactant + ReactionComponent reactants; + /// @brief A list of products + std::vector products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct Surface + { + /// @brief Reaction probability (0-1) [unitless] + double reaction_probability{ 1.0 }; + /// @brief A single gas-phase species + ReactionComponent gas_phase_species; + /// @brief A list of products + std::vector gas_phase_products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief An identifier for the condensed phase where this reaction occurs + std::string condensed_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct TaylorSeries + { + /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] + double A{ 1 }; + /// @brief Unitless exponential factor + double B{ 0 }; + /// @brief Activation threshold, expected to be the negative activation energy divided by the boltzman constant + /// [-E_a / k_b), K] + double C{ 0 }; + /// @brief A factor that determines temperature dependence [K] + double D{ 300 }; + /// @brief A factor that determines pressure dependence [Pa-1] + double E{ 0 }; + /// @brief An array of coefficients for the Taylor series expansion + std::vector taylor_coefficients{ 1.0 }; + /// @brief A list of reactants + std::vector reactants; + /// @brief A list of products + std::vector products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct Troe + { + /// @brief low-pressure pre-exponential factor + double k0_A = 1.0; + /// @brief low-pressure temperature-scaling parameter + double k0_B = 0.0; + /// @brief low-pressure exponential factor + double k0_C = 0.0; + /// @brief high-pressure pre-exponential factor + double kinf_A = 1.0; + /// @brief high-pressure temperature-scaling parameter + double kinf_B = 0.0; + /// @brief high-pressure exponential factor + double kinf_C = 0.0; + /// @brief Troe F_c parameter + double Fc = 0.6; + /// @brief Troe N parameter + double N = 1.0; + /// @brief A list of reactants + std::vector reactants; + /// @brief A list of products + std::vector products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct TernaryChemicalActivation + { + /// @brief low-pressure pre-exponential factor + double k0_A = 1.0; + /// @brief low-pressure temperature-scaling parameter + double k0_B = 0.0; + /// @brief low-pressure exponential factor + double k0_C = 0.0; + /// @brief high-pressure pre-exponential factor + double kinf_A = 1.0; + /// @brief high-pressure temperature-scaling parameter + double kinf_B = 0.0; + /// @brief high-pressure exponential factor + double kinf_C = 0.0; + /// @brief TernaryChemicalActivation F_c parameter + double Fc = 0.6; + /// @brief TernaryChemicalActivation N parameter + double N = 1.0; + /// @brief A list of reactants + std::vector reactants; + /// @brief A list of products + std::vector products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct Tunneling + { + /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] + double A = 1.0; + /// @brief Linear temperature-dependent parameter [K] + double B = 0.0; + /// @brief Cubed temperature-dependent parameter [K^3] + double C = 0.0; + /// @brief A list of reactants + std::vector reactants; + /// @brief A list of products + std::vector products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct UserDefined + { + /// @brief Scaling factor to apply to user-provided rate constants + double scaling_factor{ 1.0 }; + /// @brief A list of reactants + std::vector reactants; + /// @brief A list of products + std::vector products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + struct LambdaRateConstant + { + /// @brief A lambda function as a string, expected to be a function of temperature (T) and optionally pressure (P) + std::string lambda_function; + /// @brief A list of reactants + std::vector reactants; + /// @brief A list of products + std::vector products; + /// @brief An identifier, optional, uniqueness not enforced + std::string name; + /// @brief An identifier indicating which gas phase this reaction takes place in + std::string gas_phase; + /// @brief Unknown properties, prefixed with two underscores (__) + std::unordered_map unknown_properties; + }; + + /// @brief Represents a collection of different reaction types + struct Reactions + { + std::vector arrhenius; + std::vector branched; + std::vector emission; + std::vector first_order_loss; + std::vector photolysis; + std::vector surface; + std::vector taylor_series; + std::vector troe; + std::vector ternary_chemical_activation; + std::vector tunneling; + std::vector user_defined; + std::vector lambda_rate_constant; + }; + +} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/v0/parser.hpp b/include/mechanism_configuration/v0/parser.hpp deleted file mode 100644 index 9742fd23..00000000 --- a/include/mechanism_configuration/v0/parser.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2023-2024 National Center for Atmospheric Research -// SPDX-License-Identifier: Apache-2.0 -#pragma once - -#include -#include -#include -#include - -#include - -#include -#include - -namespace mechanism_configuration -{ - namespace v0 - { - class Parser - { - const std::string DEFAULT_CONFIG_FILE_JSON = "config.json"; - const std::string DEFAULT_CONFIG_FILE_YAML = "config.yaml"; - const std::string CAMP_FILES = "camp-files"; - const std::string CAMP_DATA = "camp-data"; - const std::string TYPE = "type"; - - Errors GetCampFiles(const std::filesystem::path& config_path, std::vector& camp_files); - - public: - ParserResult Parse(const std::filesystem::path& config_path); - }; - } // namespace v0 -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/v0/parser_types.hpp b/include/mechanism_configuration/v0/parser_types.hpp deleted file mode 100644 index 55a597f7..00000000 --- a/include/mechanism_configuration/v0/parser_types.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2023-2024 National Center for Atmospheric Research, University of Illinois at Urbana-Champaign -// -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include - -#include - -#include - -namespace mechanism_configuration -{ - namespace v0 - { - // species and mechanism - Errors ParseChemicalSpecies(std::unique_ptr& mechanism, const YAML::Node& object); - Errors ParseProducts(const YAML::Node& object, std::vector& products); - Errors ParseReactants(const YAML::Node& object, std::vector& reactants); - Errors ParseRelativeTolerance(std::unique_ptr& mechanism, const YAML::Node& object); - - // reactions - Errors ArrheniusParser(std::unique_ptr& mechanism, const YAML::Node& object); - Errors BranchedParser(std::unique_ptr& mechanism, const YAML::Node& object); - Errors EmissionParser(std::unique_ptr& mechanism, const YAML::Node& object); - Errors FirstOrderLossParser(std::unique_ptr& mechanism, const YAML::Node& object); - Errors PhotolysisParser(std::unique_ptr& mechanism, const YAML::Node& object); - Errors SurfaceParser(std::unique_ptr& mechanism, const YAML::Node& object); - Errors TernaryChemicalActivationParser(std::unique_ptr& mechanism, const YAML::Node& object); - Errors TroeParser(std::unique_ptr& mechanism, const YAML::Node& object); - Errors TunnelingParser(std::unique_ptr& mechanism, const YAML::Node& object); - Errors UserDefinedParser(std::unique_ptr& mechanism, const YAML::Node& object); - - } // namespace v0 -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/v0/types.hpp b/include/mechanism_configuration/v0/types.hpp deleted file mode 100644 index a8c026fc..00000000 --- a/include/mechanism_configuration/v0/types.hpp +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright (C) 2023-2024 National Center for Atmospheric Research, University of Illinois at Urbana-Champaign -// -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v0 - { - namespace types - { - struct Species - { - std::string name; - std::optional molecular_weight; - std::optional diffusion_coefficient; - std::optional absolute_tolerance; - std::optional tracer_type; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Phase - { - std::string name; - std::vector species; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct ReactionComponent - { - std::string species_name; - double coefficient{ 1.0 }; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Arrhenius - { - /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] - double A{ 1 }; - /// @brief Unitless exponential factor - double B{ 0 }; - /// @brief Activation threshold, expected to be the negative activation energy divided by the boltzman constant - /// [-E_a / k_b), K] - double C{ 0 }; - /// @brief A factor that determines temperature dependence [K] - double D{ 300 }; - /// @brief A factor that determines pressure dependence [Pa-1] - double E{ 0 }; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Troe - { - /// @brief low-pressure pre-exponential factor - double k0_A = 1.0; - /// @brief low-pressure temperature-scaling parameter - double k0_B = 0.0; - /// @brief low-pressure exponential factor - double k0_C = 0.0; - /// @brief high-pressure pre-exponential factor - double kinf_A = 1.0; - /// @brief high-pressure temperature-scaling parameter - double kinf_B = 0.0; - /// @brief high-pressure exponential factor - double kinf_C = 0.0; - /// @brief Troe F_c parameter - double Fc = 0.6; - /// @brief Troe N parameter - double N = 1.0; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct TernaryChemicalActivation - { - /// @brief low-pressure pre-exponential factor - double k0_A = 1.0; - /// @brief low-pressure temperature-scaling parameter - double k0_B = 0.0; - /// @brief low-pressure exponential factor - double k0_C = 0.0; - /// @brief high-pressure pre-exponential factor - double kinf_A = 1.0; - /// @brief high-pressure temperature-scaling parameter - double kinf_B = 0.0; - /// @brief high-pressure exponential factor - double kinf_C = 0.0; - /// @brief TernaryChemicalActivation F_c parameter - double Fc = 0.6; - /// @brief TernaryChemicalActivation N parameter - double N = 1.0; - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Branched - { - /// @brief pre-exponential factor - double X; - /// @brief exponential factor - double Y; - /// @brief branching factor - double a0; - /// @brief number of heavy atoms in the RO2 reacting species (excluding the peroxy moiety) - int n; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of nitrate products - std::vector nitrate_products; - /// @brief A list of alkoxy products - std::vector alkoxy_products; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Tunneling - { - /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] - double A = 1.0; - /// @brief Linear temperature-dependent parameter [K] - double B = 0.0; - /// @brief Cubed temperature-dependent parameter [K^3] - double C = 0.0; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Surface - { - /// @brief Reaction probability (0-1) [unitless] - double reaction_probability{ 1.0 }; - /// @brief A list of reactants - ReactionComponent gas_phase_species; - /// @brief A list of products - std::vector gas_phase_products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct UserDefined - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Reactions - { - std::vector arrhenius; - std::vector branched; - std::vector user_defined; - std::vector surface; - std::vector troe; - std::vector ternary_chemical_activation; - std::vector tunneling; - }; - - struct Mechanism : public ::mechanism_configuration::Mechanism - { - /// @brief An identifier, optional - std::string name; - std::vector species; - std::vector phases; - Reactions reactions; - double relative_tolerance{ 1e-6 }; - }; - - } // namespace types - } // namespace v0 -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/v0/validation.hpp b/include/mechanism_configuration/v0/validation.hpp deleted file mode 100644 index c4f2e027..00000000 --- a/include/mechanism_configuration/v0/validation.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (C) 2023-2024 National Center for Atmospheric Research, University of Illinois at Urbana-Champaign -// -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -namespace mechanism_configuration -{ - namespace v0 - { - namespace validation - { - static constexpr const char* NAME = "name"; - static constexpr const char* TYPE = "type"; - - static constexpr const char* VALUE = "value"; - - static constexpr const char* REACTIONS = "reactions"; - - static constexpr const char* TRACER_TYPE = "tracer type"; - static constexpr const char* ABS_TOLERANCE = "absolute tolerance"; - static constexpr const char* DIFFUSION_COEFF = "diffusion coefficient [m2 s-1]"; - static constexpr const char* MOL_WEIGHT = "molecular weight [kg mol-1]"; - static constexpr const char* THIRD_BODY = "THIRD_BODY"; - - static constexpr const char* REACTANTS = "reactants"; - static constexpr const char* PRODUCTS = "products"; - static constexpr const char* MUSICA_NAME = "MUSICA name"; - static constexpr const char* SCALING_FACTOR = "scaling factor"; - static constexpr const char* GAS_PHASE_REACTANT = "gas-phase reactant"; - static constexpr const char* GAS_PHASE_PRODUCTS = "gas-phase products"; - - static constexpr const char* QTY = "qty"; - static constexpr const char* YIELD = "yield"; - - static constexpr const char* SPECIES = "species"; - - static constexpr const char* ALKOXY_PRODUCTS = "alkoxy products"; - static constexpr const char* NITRATE_PRODUCTS = "nitrate products"; - static constexpr const char* X = "X"; - static constexpr const char* Y = "Y"; - static constexpr const char* A0 = "a0"; - static constexpr const char* N = "N"; - static constexpr const char* n = "n"; - - static constexpr const char* PROBABILITY = "reaction probability"; - - static constexpr const char* A = "A"; - static constexpr const char* B = "B"; - static constexpr const char* C = "C"; - static constexpr const char* D = "D"; - static constexpr const char* E = "E"; - static constexpr const char* Ea = "Ea"; - - static constexpr const char* K0_A = "k0_A"; - static constexpr const char* K0_B = "k0_B"; - static constexpr const char* K0_C = "k0_C"; - static constexpr const char* KINF_A = "kinf_A"; - static constexpr const char* KINF_B = "kinf_B"; - static constexpr const char* KINF_C = "kinf_C"; - static constexpr const char* FC = "Fc"; - } // namespace validation - } // namespace v0 -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/v1/mechanism.hpp b/include/mechanism_configuration/v1/mechanism.hpp deleted file mode 100644 index 7bc1ef8a..00000000 --- a/include/mechanism_configuration/v1/mechanism.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include - -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - namespace types - { - - struct Mechanism : public ::mechanism_configuration::Mechanism - { - /// @brief Mechanism name - /// @note This is optional. - std::string name; - /// @brief Represents species - std::vector species; - /// @brief Represents phases - std::vector phases; - /// @brief Represents a collection of different reaction types, each stored in a vector - /// corresponding to a specific mechanism - Reactions reactions; - }; - } // namespace types - } // namespace v1 -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/v1/mechanism_parsers.hpp b/include/mechanism_configuration/v1/mechanism_parsers.hpp deleted file mode 100644 index 938bfeae..00000000 --- a/include/mechanism_configuration/v1/mechanism_parsers.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include - -#include - -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - std::pair> ParseSpecies(const YAML::Node& objects); - - std::pair> ParsePhases( - const YAML::Node& objects, - const std::vector existing_species); - - std::pair ParseReactionComponent(const YAML::Node& object); - - std::pair> ParseReactantsOrProducts( - const std::string& key, - const YAML::Node& object); - - std::pair ParseReactions( - const YAML::Node& objects, - const std::vector& existing_species, - const std::vector& existing_phases); - - } // namespace v1 -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/v1/parser.hpp b/include/mechanism_configuration/v1/parser.hpp deleted file mode 100644 index 7891f0d7..00000000 --- a/include/mechanism_configuration/v1/parser.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include - -namespace YAML -{ - class Node; -} // namespace YAML - -namespace mechanism_configuration -{ - namespace v1 - { - class Parser - { - private: - enum class EntityFormat - { - FileList, // { "files": [...] } - Inline, // [ { "name": ... }, ... ] - Invalid, - }; - - EntityFormat GetEntityFormat(const YAML::Node& node); - - ParserResult ParseFromFileConfig( - const YAML::Node& object, - const std::filesystem::path& config_path, - EntityFormat spc_format, - EntityFormat phs_format, - EntityFormat rxn_format); - - public: - ParserResult Parse(const std::filesystem::path& config_path); - ParserResult ParseFromString(const std::string& content); - ParserResult ParseFromNode(const YAML::Node& object); - }; - } // namespace v1 -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/v1/reaction_parsers.hpp b/include/mechanism_configuration/v1/reaction_parsers.hpp deleted file mode 100644 index ef44c8ae..00000000 --- a/include/mechanism_configuration/v1/reaction_parsers.hpp +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include - -#include - -#include - -namespace mechanism_configuration -{ - namespace v1 - { - - /// @brief Abstract interface for reaction parsers - class IReactionParser - { - public: - /// @brief Parses a YAML node representing a chemical reaction - /// @param object The YAML node containing reaction information - /// @param existing_species A list of species previously defined in the mechanism - /// @param existing_phases A list of chemical phases relevant to the reaction - /// @param reactions The container to which the parsed reactions will be added - /// @return A list of any parsing errors encountered - virtual Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) = 0; - - /// @brief Destructor - virtual ~IReactionParser() = default; - }; - - class ArrheniusParser : public IReactionParser - { - public: - /// @brief Parser for Arrhenius reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class BranchedParser : public IReactionParser - { - public: - /// @brief Parser for branched reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class CondensedPhaseArrheniusParser : public IReactionParser - { - public: - /// @brief Parser for condensed-phase Arrhenius reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class CondensedPhasePhotolysisParser : public IReactionParser - { - public: - /// @brief Parser for condensed-phase photolysis reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class EmissionParser : public IReactionParser - { - public: - /// @brief Parser for emission reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class FirstOrderLossParser : public IReactionParser - { - public: - /// @brief Parser for first-order loss reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class SimpolPhaseTransferParser : public IReactionParser - { - public: - /// @brief Parser for SIMPOL-phase transfer reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class AqueousEquilibriumParser : public IReactionParser - { - public: - /// @brief Parser for aqueous equilibrium reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class WetDepositionParser : public IReactionParser - { - public: - /// @brief Parser for wet deposition reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class HenrysLawParser : public IReactionParser - { - public: - /// @brief Parser for Henry's Law reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class PhotolysisParser : public IReactionParser - { - public: - /// @brief Parser for photolysis reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class SurfaceParser : public IReactionParser - { - public: - /// @brief Parser for surface reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class TaylorSeriesParser : public IReactionParser - { - public: - /// @brief Parser for Taylor series reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class TroeParser : public IReactionParser - { - public: - /// @brief Parser for Troe reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class TernaryChemicalActivationParser : public IReactionParser - { - public: - /// @brief Parser for Ternary Chemical Activation reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class TunnelingParser : public IReactionParser - { - public: - /// @brief Parser for tunneling reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class UserDefinedParser : public IReactionParser - { - public: - /// @brief Parser for user-defined reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - class LambdaRateConstantParser : public IReactionParser - { - public: - /// @brief Parser for lambda rate constant reactions - Errors parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) override; - }; - - } // namespace v1 -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/v1/reaction_types.hpp b/include/mechanism_configuration/v1/reaction_types.hpp deleted file mode 100644 index 89901b65..00000000 --- a/include/mechanism_configuration/v1/reaction_types.hpp +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - namespace types - { - - struct Arrhenius - { - /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] - double A{ 1 }; - /// @brief Unitless exponential factor - double B{ 0 }; - /// @brief Activation threshold, expected to be the negative activation energy divided by the boltzman constant - /// [-E_a / k_b), K] - double C{ 0 }; - /// @brief A factor that determines temperature dependence [K] - double D{ 300 }; - /// @brief A factor that determines pressure dependence [Pa-1] - double E{ 0 }; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Branched - { - /// @brief pre-exponential factor - double X; - /// @brief exponential factor - double Y; - /// @brief branching factor - double a0; - /// @brief number of heavy atoms in the RO2 reacting species (excluding the peroxy moiety) - int n; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of nitrate products - std::vector nitrate_products; - /// @brief A list of alkoxy products - std::vector alkoxy_products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Emission - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct FirstOrderLoss - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief A list of products - std::vector products; - /// @brief A list of reactants - std::vector reactants; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Photolysis - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Surface - { - /// @brief Reaction probability (0-1) [unitless] - double reaction_probability{ 1.0 }; - /// @brief A list of reactants - ReactionComponent gas_phase_species; - /// @brief A list of products - std::vector gas_phase_products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct TaylorSeries - { - /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] - double A{ 1 }; - /// @brief Unitless exponential factor - double B{ 0 }; - /// @brief Activation threshold, expected to be the negative activation energy divided by the boltzman constant - /// [-E_a / k_b), K] - double C{ 0 }; - /// @brief A factor that determines temperature dependence [K] - double D{ 300 }; - /// @brief A factor that determines pressure dependence [Pa-1] - double E{ 0 }; - /// @brief An array of coefficients for the Taylor series expansion - std::vector taylor_coefficients{ 1.0 }; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Troe - { - /// @brief low-pressure pre-exponential factor - double k0_A = 1.0; - /// @brief low-pressure temperature-scaling parameter - double k0_B = 0.0; - /// @brief low-pressure exponential factor - double k0_C = 0.0; - /// @brief high-pressure pre-exponential factor - double kinf_A = 1.0; - /// @brief high-pressure temperature-scaling parameter - double kinf_B = 0.0; - /// @brief high-pressure exponential factor - double kinf_C = 0.0; - /// @brief Troe F_c parameter - double Fc = 0.6; - /// @brief Troe N parameter - double N = 1.0; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct TernaryChemicalActivation - { - /// @brief low-pressure pre-exponential factor - double k0_A = 1.0; - /// @brief low-pressure temperature-scaling parameter - double k0_B = 0.0; - /// @brief low-pressure exponential factor - double k0_C = 0.0; - /// @brief high-pressure pre-exponential factor - double kinf_A = 1.0; - /// @brief high-pressure temperature-scaling parameter - double kinf_B = 0.0; - /// @brief high-pressure exponential factor - double kinf_C = 0.0; - /// @brief TernaryChemicalActivation F_c parameter - double Fc = 0.6; - /// @brief TernaryChemicalActivation N parameter - double N = 1.0; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Tunneling - { - /// @brief Pre-exponential factor [(mol m−3)^(−(𝑛−1)) s−1] - double A = 1.0; - /// @brief Linear temperature-dependent parameter [K] - double B = 0.0; - /// @brief Cubed temperature-dependent parameter [K^3] - double C = 0.0; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct UserDefined - { - /// @brief Scaling factor to apply to user-provided rate constants - double scaling_factor{ 1.0 }; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct LambdaRateConstant - { - /// @brief A lambda function as a string, expected to be a function of temperature (T) and optionally pressure (P) - std::string lambda_function; - /// @brief A list of reactants - std::vector reactants; - /// @brief A list of products - std::vector products; - /// @brief An identifier, optional, uniqueness not enforced - std::string name; - /// @brief An identifier indicating which gas phase this reaction takes place in - std::string gas_phase; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - /// @brief Represents a collection of different reaction types - struct Reactions - { - std::vector arrhenius; - std::vector branched; - std::vector emission; - std::vector first_order_loss; - std::vector photolysis; - std::vector surface; - std::vector taylor_series; - std::vector troe; - std::vector ternary_chemical_activation; - std::vector tunneling; - std::vector user_defined; - std::vector lambda_rate_constant; - }; - - } // namespace types - } // namespace v1 -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/v1/types.hpp b/include/mechanism_configuration/v1/types.hpp deleted file mode 100644 index 789f1ab7..00000000 --- a/include/mechanism_configuration/v1/types.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - namespace types - { - - struct Species - { - std::string name; - std::optional molecular_weight; - std::optional constant_concentration; - std::optional constant_mixing_ratio; - std::optional is_third_body; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct PhaseSpecies - { - std::string name; - std::optional diffusion_coefficient; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct Phase - { - std::string name; - std::vector species; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - struct ReactionComponent - { - std::string species_name; - double coefficient{ 1.0 }; - /// @brief Unknown properties, prefixed with two underscores (__) - std::unordered_map unknown_properties; - }; - - } // namespace types - } // namespace v1 -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/v1/utils.hpp b/include/mechanism_configuration/v1/utils.hpp deleted file mode 100644 index 1f5f0257..00000000 --- a/include/mechanism_configuration/v1/utils.hpp +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - struct DuplicateEntryInfo - { - std::string name; - std::vector nodes; - }; - - std::unordered_map GetComments(const YAML::Node& object); - - /// @brief Extract species names from a vector of PhaseSpecies - std::vector GetSpeciesNames(const std::vector& phase_species); - - template - std::vector FindDuplicateObjectsByName(const std::vector>& collection) - { - std::unordered_map> name_to_nodes; - - if constexpr (std::is_same_v) - { - for (const auto& [elem, node] : collection) - { - name_to_nodes[elem].push_back(node); - } - } - else - { - for (const auto& [elem, node] : collection) - { - name_to_nodes[elem.name].push_back(node); - } - } - - std::vector duplicates; - - for (const auto& [name, nodes] : name_to_nodes) - { - if (nodes.size() > 1) - { - duplicates.push_back({ name, nodes }); - } - } - - return duplicates; - } - - template - std::vector FindUnknownSpecies( - const std::vector& requested_species, - const std::vector& existing_species) - { - std::unordered_set existing_names; - - if constexpr (std::is_same_v) - { - for (const auto& species : existing_species) - { - existing_names.insert(species); - } - } - else - { - for (const auto& species : existing_species) - { - existing_names.insert(species.name); - } - } - - std::vector unknown_species; - for (const auto& name : requested_species) - { - if (existing_names.find(name) == existing_names.end()) - { - unknown_species.emplace_back(name); - } - } - - return unknown_species; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/v1/validation.hpp b/include/mechanism_configuration/v1/validation.hpp deleted file mode 100644 index 6813ec8f..00000000 --- a/include/mechanism_configuration/v1/validation.hpp +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -namespace mechanism_configuration -{ - namespace v1 - { - namespace validation - { - // Shared, but also Mechanism - static constexpr const char* version = "version"; - static constexpr const char* name = "name"; - - // Configuration - static constexpr const char* species = "species"; - static constexpr const char* phases = "phases"; - static constexpr const char* reactions = "reactions"; - - // Species - static constexpr const char* molecular_weight = "molecular weight [kg mol-1]"; - static constexpr const char* constant_concentration = "constant concentration [mol m-3]"; - static constexpr const char* constant_mixing_ratio = "constant mixing ratio [mol mol-1]"; - static constexpr const char* is_third_body = "is third body"; - - // Phase-species - static constexpr const char* diffusion_coefficient = "diffusion coefficient [m2 s-1]"; - - // Reactions - static constexpr const char* reactants = "reactants"; - static constexpr const char* products = "products"; - static constexpr const char* type = "type"; - static constexpr const char* gas_phase = "gas phase"; - - // Reactant and product - static constexpr const char* species_name = "species name"; - static constexpr const char* coefficient = "coefficient"; - - // ---------------------------------------- - // Reaction types - // ---------------------------------------- - - // Arrhenius - static constexpr const char* Arrhenius_key = "ARRHENIUS"; - static constexpr const char* A = "A"; - static constexpr const char* B = "B"; - static constexpr const char* C = "C"; - static constexpr const char* D = "D"; - static constexpr const char* E = "E"; - static constexpr const char* Ea = "Ea"; - - // TaylorSeries - static constexpr const char* TaylorSeries_key = "TAYLOR_SERIES"; - static constexpr const char* taylor_coefficients = "taylor coefficients"; - // also these - // A - // B - // C - // D - // E - // Ea - - // Troe - static constexpr const char* Troe_key = "TROE"; - static constexpr const char* k0_A = "k0_A"; - static constexpr const char* k0_B = "k0_B"; - static constexpr const char* k0_C = "k0_C"; - static constexpr const char* kinf_A = "kinf_A"; - static constexpr const char* kinf_B = "kinf_B"; - static constexpr const char* kinf_C = "kinf_C"; - static constexpr const char* Fc = "Fc"; - static constexpr const char* N = "N"; - - // Ternary Chemical Activation - static constexpr const char* TernaryChemicalActivation_key = "TERNARY_CHEMICAL_ACTIVATION"; - // also k0_A - // k0_B - // k0_C - // kinf_A - // kinf_B - // kinf_C - // Fc - // N - - // Branched - static constexpr const char* Branched_key = "BRANCHED_NO_RO2"; - static constexpr const char* X = "X"; - static constexpr const char* Y = "Y"; - static constexpr const char* a0 = "a0"; - static constexpr const char* n = "n"; - static constexpr const char* nitrate_products = "nitrate products"; - static constexpr const char* alkoxy_products = "alkoxy products"; - - // Tunneling - static constexpr const char* Tunneling_key = "TUNNELING"; - // also these, but they are defined above - // A - // B - // C - - // Surface - static constexpr const char* Surface_key = "SURFACE"; - static constexpr const char* reaction_probability = "reaction probability"; - static constexpr const char* gas_phase_species = "gas-phase species"; - static constexpr const char* gas_phase_products = "gas-phase products"; - - // Photolysis - static constexpr const char* Photolysis_key = "PHOTOLYSIS"; - static constexpr const char* scaling_factor = "scaling factor"; - - // Emissions - static constexpr const char* Emission_key = "EMISSION"; - // also scaling factor - - // First Order Loss - static constexpr const char* FirstOrderLoss_key = "FIRST_ORDER_LOSS"; - // also scaling factor - - // User Defined - static constexpr const char* UserDefined_key = "USER_DEFINED"; - // also - // gas phase - // reactants - // products - // scaling factor - - // Lambda Rate Constant - static constexpr const char* LambdaRateConstant_key = "LAMBDA_RATE_CONSTANT"; - static constexpr const char* lambda_function = "lambda function"; - // also - // gas phase - // reactants - // products - // name - - } // namespace validation - } // namespace v1 -} // namespace mechanism_configuration \ No newline at end of file diff --git a/include/mechanism_configuration/validate.hpp b/include/mechanism_configuration/validate.hpp new file mode 100644 index 00000000..c603271a --- /dev/null +++ b/include/mechanism_configuration/validate.hpp @@ -0,0 +1,63 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include +#include +#include + +namespace mechanism_configuration +{ + // Intermediate over which all semantic validation runs. Both a parsed document and an + // in-code Mechanism produce one of these and hand it to ValidateSemantics, so the rules + // live in exactly one place. A parsed document fills in source locations (so errors carry + // line:col); an in-code Mechanism leaves them empty. The domain types stay location-free. + namespace semantics + { + struct NamedRef + { + std::string name; + std::optional location; + }; + + struct PhaseRef + { + std::string name; + std::vector species; + std::optional location; + }; + + struct ReactionRef + { + std::string type; + std::string phase; + std::vector reactants; // must exist and be registered in `phase` + std::vector products; // must exist; may belong to any phase + std::optional location; + }; + + struct Input + { + std::vector species; + std::vector phases; + std::vector reactions; + }; + } // namespace semantics + + /// @brief The single home for the mechanism's semantic rules. Errors include `line:col` + /// for any element whose source location was supplied. + Errors ValidateSemantics(const semantics::Input& input); + + /// @brief Validates the semantic invariants of a canonical Mechanism, independent of how it + /// was produced (parsed from any version, or constructed in code). Convenience wrapper + /// that builds a location-free semantics::Input and calls ValidateSemantics. + /// + /// Structural/deserialization concerns (YAML keys, types, formatting) are the responsibility + /// of the version-specific parsers and are not repeated here. + Errors Validate(const Mechanism& mechanism); +} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/validate_schema.hpp b/include/mechanism_configuration/validate_schema.hpp deleted file mode 100644 index d6232eed..00000000 --- a/include/mechanism_configuration/validate_schema.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#pragma once - -#include -#include - -#include - -#include -#include - -namespace mechanism_configuration -{ - Errors ValidateSchema( - const YAML::Node& object, - const std::vector& required_keys, - const std::vector& optional_keys); -} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/version.hpp b/include/mechanism_configuration/version.hpp index ea47ad36..a3e11ce6 100644 --- a/include/mechanism_configuration/version.hpp +++ b/include/mechanism_configuration/version.hpp @@ -1,3 +1,7 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + // clang-format off #pragma once @@ -9,19 +13,19 @@ extern "C" { const char* getVersionString() { - return "1.1.2"; + return "2.0.0"; } unsigned getVersionMajor() { - return 1; + return 2; } unsigned getVersionMinor() { - return 1+0; + return 0+0; } unsigned getVersionPatch() { - return 2+0; + return 0+0; } unsigned getVersionTweak() { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8a686138..be92c6e0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,7 +10,7 @@ endif() add_library(musica::mechanism_configuration ALIAS mechanism_configuration) -target_compile_features(mechanism_configuration PUBLIC cxx_std_20) +target_compile_features(mechanism_configuration PUBLIC cxx_std_23) if(MECH_CONFIG_USE_FMT) target_compile_definitions(mechanism_configuration PUBLIC MECH_CONFIG_USE_FMT) @@ -27,20 +27,22 @@ set_target_properties(mechanism_configuration PROPERTIES target_sources(mechanism_configuration PRIVATE - parse_status.cpp - parser.cpp - validate_schema.cpp + errors.cpp + parse.cpp + validate.cpp + check_schema.cpp ) target_include_directories(mechanism_configuration PUBLIC $ $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR} ) add_subdirectory(v0) add_subdirectory(v1) -add_subdirectory(development) target_link_libraries(mechanism_configuration PUBLIC diff --git a/src/validate_schema.cpp b/src/check_schema.cpp similarity index 53% rename from src/validate_schema.cpp rename to src/check_schema.cpp index 64f17cd1..8d7704c7 100644 --- a/src/validate_schema.cpp +++ b/src/check_schema.cpp @@ -2,18 +2,18 @@ // University of Illinois at Urbana-Champaign // SPDX-License-Identifier: Apache-2.0 -#include #include -#include +#include "detail/check_schema.hpp" #include namespace mechanism_configuration { - Errors ValidateSchema( + Errors CheckSchema( const YAML::Node& object, - const std::vector& required_keys, - const std::vector& optional_keys) + const std::vector& required_keys, + const std::vector& optional_keys, + const std::vector>& exactly_one_of) { Errors errors; ErrorLocation error_location{ object.Mark().line, object.Mark().column }; @@ -21,7 +21,7 @@ namespace mechanism_configuration if (!object || object.IsNull()) { std::string message = mc_fmt::format("{} error: Object is null.", error_location); - errors.push_back({ ConfigParseStatus::EmptyObject, message }); + errors.push_back({ ErrorCode::EmptyObject, message }); return errors; } @@ -33,9 +33,9 @@ namespace mechanism_configuration object_keys.emplace_back(key.first.as()); } - // Sort keys for comparison - auto sorted_required_keys = required_keys; - auto sorted_optional_keys = optional_keys; + // Sort keys for comparison (own the strings so comparisons stay homogeneous) + std::vector sorted_required_keys(required_keys.begin(), required_keys.end()); + std::vector sorted_optional_keys(optional_keys.begin(), optional_keys.end()); std::sort(object_keys.begin(), object_keys.end()); std::sort(sorted_required_keys.begin(), sorted_required_keys.end()); std::sort(sorted_optional_keys.begin(), sorted_optional_keys.end()); @@ -52,9 +52,46 @@ namespace mechanism_configuration for (const auto& key : missing_keys) { std::string message = mc_fmt::format("{} error: Required key '{}' is missing.", error_location, key); - errors.push_back({ ConfigParseStatus::RequiredKeyNotFound, message }); + errors.push_back({ ErrorCode::RequiredKeyNotFound, message }); } + // Exactly-one-of groups: exactly one member of each group must be present. + // Group members also count as allowed keys, so they are never flagged as invalid. + for (const auto& group : exactly_one_of) + { + std::vector present; + for (const auto& key : group) + { + std::string key_str(key); + sorted_optional_keys.push_back(key_str); + if (std::find(object_keys.begin(), object_keys.end(), key_str) != object_keys.end()) + present.push_back(key_str); + } + + if (present.size() != 1) + { + std::string joined; + for (size_t i = 0; i < group.size(); ++i) + { + joined += "'" + std::string(group[i]) + "'"; + if (i + 1 < group.size()) + joined += ", "; + } + + if (present.empty()) + { + std::string message = mc_fmt::format("{} error: Exactly one of {} is required.", error_location, joined); + errors.push_back({ ErrorCode::RequiredKeyNotFound, message }); + } + else + { + std::string message = mc_fmt::format("{} error: Only one of {} may be specified.", error_location, joined); + errors.push_back({ ErrorCode::MutuallyExclusiveOption, message }); + } + } + } + std::sort(sorted_optional_keys.begin(), sorted_optional_keys.end()); + // Find keys that are neither required nor optional std::vector extra_keys; std::set_difference( @@ -78,7 +115,7 @@ namespace mechanism_configuration if (key.find("__") == std::string::npos) { std::string message = mc_fmt::format("{} error: Non-standard key '{}' found.", error_location, key); - errors.push_back({ ConfigParseStatus::InvalidKey, message }); + errors.push_back({ ErrorCode::InvalidKey, message }); } } diff --git a/src/detail/check_schema.hpp b/src/detail/check_schema.hpp new file mode 100644 index 00000000..0aa0b997 --- /dev/null +++ b/src/detail/check_schema.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +#include + +#include +#include +#include + +namespace mechanism_configuration +{ + /// @brief Checks the keys of a YAML object against a schema. + /// @param object The YAML node to validate + /// @param required_keys Keys that must all be present + /// @param optional_keys Keys that may be present + /// @param exactly_one_of Groups of mutually-exclusive keys; exactly one member of each + /// group must be present (zero -> RequiredKeyNotFound, more than one -> + /// MutuallyExclusiveOption). Group members are treated as allowed keys. + /// @return A collection of schema errors; empty if the object conforms. + Errors CheckSchema( + const YAML::Node& object, + const std::vector& required_keys, + const std::vector& optional_keys, + const std::vector>& exactly_one_of = {}); +} // namespace mechanism_configuration diff --git a/include/mechanism_configuration/constants.hpp b/src/detail/constants.hpp similarity index 100% rename from include/mechanism_configuration/constants.hpp rename to src/detail/constants.hpp diff --git a/include/mechanism_configuration/conversions.hpp b/src/detail/conversions.hpp similarity index 89% rename from include/mechanism_configuration/conversions.hpp rename to src/detail/conversions.hpp index 41f0f6ff..7eb5c9d8 100644 --- a/include/mechanism_configuration/conversions.hpp +++ b/src/detail/conversions.hpp @@ -4,7 +4,7 @@ #pragma once -#include +#include namespace mechanism_configuration { diff --git a/src/detail/v0/keys.hpp b/src/detail/v0/keys.hpp new file mode 100644 index 00000000..b6ec9200 --- /dev/null +++ b/src/detail/v0/keys.hpp @@ -0,0 +1,61 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +namespace mechanism_configuration::v0::keys +{ + inline constexpr std::string_view NAME = "name"; + inline constexpr std::string_view TYPE = "type"; + + inline constexpr std::string_view VALUE = "value"; + + inline constexpr std::string_view REACTIONS = "reactions"; + + inline constexpr std::string_view TRACER_TYPE = "tracer type"; + inline constexpr std::string_view ABS_TOLERANCE = "absolute tolerance"; + inline constexpr std::string_view DIFFUSION_COEFF = "diffusion coefficient [m2 s-1]"; + inline constexpr std::string_view MOL_WEIGHT = "molecular weight [kg mol-1]"; + inline constexpr std::string_view THIRD_BODY = "THIRD_BODY"; + + inline constexpr std::string_view REACTANTS = "reactants"; + inline constexpr std::string_view PRODUCTS = "products"; + inline constexpr std::string_view MUSICA_NAME = "MUSICA name"; + inline constexpr std::string_view SCALING_FACTOR = "scaling factor"; + inline constexpr std::string_view GAS_PHASE_REACTANT = "gas-phase reactant"; + inline constexpr std::string_view GAS_PHASE_PRODUCTS = "gas-phase products"; + + inline constexpr std::string_view QTY = "qty"; + inline constexpr std::string_view YIELD = "yield"; + + inline constexpr std::string_view SPECIES = "species"; + + inline constexpr std::string_view ALKOXY_PRODUCTS = "alkoxy products"; + inline constexpr std::string_view NITRATE_PRODUCTS = "nitrate products"; + inline constexpr std::string_view X = "X"; + inline constexpr std::string_view Y = "Y"; + inline constexpr std::string_view A0 = "a0"; + inline constexpr std::string_view N = "N"; + inline constexpr std::string_view n = "n"; + + inline constexpr std::string_view PROBABILITY = "reaction probability"; + + inline constexpr std::string_view A = "A"; + inline constexpr std::string_view B = "B"; + inline constexpr std::string_view C = "C"; + inline constexpr std::string_view D = "D"; + inline constexpr std::string_view E = "E"; + inline constexpr std::string_view Ea = "Ea"; + + inline constexpr std::string_view K0_A = "k0_A"; + inline constexpr std::string_view K0_B = "k0_B"; + inline constexpr std::string_view K0_C = "k0_C"; + inline constexpr std::string_view KINF_A = "kinf_A"; + inline constexpr std::string_view KINF_B = "kinf_B"; + inline constexpr std::string_view KINF_C = "kinf_C"; + inline constexpr std::string_view FC = "Fc"; +} // namespace mechanism_configuration::v0::keys \ No newline at end of file diff --git a/src/detail/v0/parser.hpp b/src/detail/v0/parser.hpp new file mode 100644 index 00000000..bb63ab8c --- /dev/null +++ b/src/detail/v0/parser.hpp @@ -0,0 +1,31 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include + +#include +#include +#include + +namespace mechanism_configuration::v0 +{ + class Parser + { + const std::string DEFAULT_CONFIG_FILE_JSON = "config.json"; + const std::string DEFAULT_CONFIG_FILE_YAML = "config.yaml"; + const std::string CAMP_FILES = "camp-files"; + const std::string CAMP_DATA = "camp-data"; + const std::string TYPE = "type"; + + Errors GetCampFiles(const std::filesystem::path& config_path, std::vector& camp_files); + + public: + std::expected Parse(const std::filesystem::path& config_path); + }; +} // namespace mechanism_configuration::v0 diff --git a/src/detail/v0/parser_types.hpp b/src/detail/v0/parser_types.hpp new file mode 100644 index 00000000..9dae5f2f --- /dev/null +++ b/src/detail/v0/parser_types.hpp @@ -0,0 +1,34 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include +#include + +#include + +#include + +namespace mechanism_configuration::v0 +{ + // species and mechanism + Errors ParseChemicalSpecies(Mechanism& mechanism, const YAML::Node& object); + Errors ParseProducts(const YAML::Node& object, std::vector& products); + Errors ParseReactants(const YAML::Node& object, std::vector& reactants); + Errors ParseRelativeTolerance(Mechanism& mechanism, const YAML::Node& object); + + // reactions + Errors ArrheniusParser(Mechanism& mechanism, const YAML::Node& object); + Errors BranchedParser(Mechanism& mechanism, const YAML::Node& object); + Errors EmissionParser(Mechanism& mechanism, const YAML::Node& object); + Errors FirstOrderLossParser(Mechanism& mechanism, const YAML::Node& object); + Errors PhotolysisParser(Mechanism& mechanism, const YAML::Node& object); + Errors SurfaceParser(Mechanism& mechanism, const YAML::Node& object); + Errors TernaryChemicalActivationParser(Mechanism& mechanism, const YAML::Node& object); + Errors TroeParser(Mechanism& mechanism, const YAML::Node& object); + Errors TunnelingParser(Mechanism& mechanism, const YAML::Node& object); + Errors UserDefinedParser(Mechanism& mechanism, const YAML::Node& object); +} // namespace mechanism_configuration::v0 diff --git a/src/detail/v1/keys.hpp b/src/detail/v1/keys.hpp new file mode 100644 index 00000000..939a1337 --- /dev/null +++ b/src/detail/v1/keys.hpp @@ -0,0 +1,179 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include + +namespace mechanism_configuration::v1::keys +{ + // Shared, but also Mechanism + inline constexpr std::string_view version = "version"; + inline constexpr std::string_view name = "name"; + // Legacy alias for a reaction component's species reference, accepted alongside `name` + // for backward compatibility with v1 configuration files. + inline constexpr std::string_view species_name = "species name"; + + // Configuration + inline constexpr std::string_view species = "species"; + inline constexpr std::string_view phases = "phases"; + inline constexpr std::string_view models = "models"; + inline constexpr std::string_view reactions = "reactions"; + + // Species + inline constexpr std::string_view absolute_tolerance = "absolute tolerance"; + inline constexpr std::string_view diffusion_coefficient = "diffusion coefficient [m2 s-1]"; + inline constexpr std::string_view molecular_weight = "molecular weight [kg mol-1]"; + inline constexpr std::string_view henrys_law_constant_298 = "HLC(298K) [mol m-3 Pa-1]"; + inline constexpr std::string_view henrys_law_constant_exponential_factor = "HLC exponential factor [K]"; + inline constexpr std::string_view n_star = "N star"; + inline constexpr std::string_view density = "density [kg m-3]"; + inline constexpr std::string_view tracer_type = "tracer type"; + inline constexpr std::string_view constant_concentration = "constant concentration [mol m-3]"; + inline constexpr std::string_view constant_mixing_ratio = "constant mixing ratio [mol mol-1]"; + inline constexpr std::string_view is_third_body = "is third body"; + inline constexpr std::string_view third_body = "THIRD_BODY"; + + // Reactions + inline constexpr std::string_view reactants = "reactants"; + inline constexpr std::string_view products = "products"; + inline constexpr std::string_view type = "type"; + inline constexpr std::string_view gas_phase = "gas phase"; + + // Reactant and product + inline constexpr std::string_view coefficient = "coefficient"; + // also name + + // ---------------------------------------- + // Reaction types + // ---------------------------------------- + + // Arrhenius + inline constexpr std::string_view Arrhenius_key = "ARRHENIUS"; + inline constexpr std::string_view A = "A"; + inline constexpr std::string_view B = "B"; + inline constexpr std::string_view C = "C"; + inline constexpr std::string_view D = "D"; + inline constexpr std::string_view E = "E"; + inline constexpr std::string_view Ea = "Ea"; + + // TaylorSeries + inline constexpr std::string_view TaylorSeries_key = "TAYLOR_SERIES"; + inline constexpr std::string_view taylor_coefficients = "taylor coefficients"; + // also these + // A + // B + // C + // D + // E + // Ea + + // Condensed Phase Arrhenius + inline constexpr std::string_view CondensedPhaseArrhenius_key = "CONDENSED_PHASE_ARRHENIUS"; + // also these + // condensed phase + // A + // B + // C + // D + // E + // Ea + + // Troe + inline constexpr std::string_view Troe_key = "TROE"; + inline constexpr std::string_view k0_A = "k0_A"; + inline constexpr std::string_view k0_B = "k0_B"; + inline constexpr std::string_view k0_C = "k0_C"; + inline constexpr std::string_view kinf_A = "kinf_A"; + inline constexpr std::string_view kinf_B = "kinf_B"; + inline constexpr std::string_view kinf_C = "kinf_C"; + inline constexpr std::string_view Fc = "Fc"; + inline constexpr std::string_view N = "N"; + + // Ternary Chemical Activation + inline constexpr std::string_view TernaryChemicalActivation_key = "TERNARY_CHEMICAL_ACTIVATION"; + // also k0_A + // k0_B + // k0_C + // kinf_A + // kinf_B + // kinf_C + // Fc + // N + + // Branched + inline constexpr std::string_view Branched_key = "BRANCHED_NO_RO2"; + inline constexpr std::string_view X = "X"; + inline constexpr std::string_view Y = "Y"; + inline constexpr std::string_view a0 = "a0"; + inline constexpr std::string_view n = "n"; + inline constexpr std::string_view nitrate_products = "nitrate products"; + inline constexpr std::string_view alkoxy_products = "alkoxy products"; + + // Tunneling + inline constexpr std::string_view Tunneling_key = "TUNNELING"; + // also these, but they are defined above + // A + // B + // C + + // Surface + inline constexpr std::string_view Surface_key = "SURFACE"; + inline constexpr std::string_view reaction_probability = "reaction probability"; + inline constexpr std::string_view gas_phase_species = "gas-phase species"; + inline constexpr std::string_view gas_phase_products = "gas-phase products"; + inline constexpr std::string_view condensed_phase = "condensed phase"; + + // Photolysis + inline constexpr std::string_view Photolysis_key = "PHOTOLYSIS"; + inline constexpr std::string_view scaling_factor = "scaling factor"; + + // Condensed Phae Photolysis + inline constexpr std::string_view CondensedPhasePhotolysis_key = "CONDENSED_PHASE_PHOTOLYSIS"; + // also + // scaling factor + // condensed phase + + // Emissions + inline constexpr std::string_view Emission_key = "EMISSION"; + // also scaling factor + + // First Order Loss + inline constexpr std::string_view FirstOrderLoss_key = "FIRST_ORDER_LOSS"; + // also scaling factor + + // Simpol Phase Transfer + inline constexpr std::string_view SimpolPhaseTransfer_key = "SIMPOL_PHASE_TRANSFER"; + inline constexpr std::string_view condensed_phase_species = "condensed-phase species"; + // also + // gas phase + // gas-phase species + // condensed phase + // condensed-phase species + // B + + // Wet Deposition + inline constexpr std::string_view WetDeposition_key = "WET_DEPOSITION"; + // also + // scaling factor + // condensed phase + + // User Defined + inline constexpr std::string_view UserDefined_key = "USER_DEFINED"; + // also + // gas phase + // reactants + // products + // scaling factor + + // Lambda Rate Constant + inline constexpr std::string_view LambdaRateConstant_key = "LAMBDA_RATE_CONSTANT"; + inline constexpr std::string_view lambda_function = "lambda function"; + // also + // gas phase + // reactants + // products + // name + +} // namespace mechanism_configuration::v1::keys diff --git a/src/detail/v1/parser.hpp b/src/detail/v1/parser.hpp new file mode 100644 index 00000000..22197bf7 --- /dev/null +++ b/src/detail/v1/parser.hpp @@ -0,0 +1,73 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include + +#include +#include +#include + +namespace mechanism_configuration::v1 +{ + /// @brief Extracts a located semantics::Input from a fully-resolved (inline) v1 YAML node, so + /// the version-neutral ValidateSemantics can run the semantic checks with line:col. + semantics::Input BuildSemanticInput(const YAML::Node& object); + + class Parser + { + public: + Parser() = default; + + /// @brief Parse a v1 mechanism from a configuration file: resolves any file-list sections + /// (v1.1+ `{ files: [...] }`) into a single document, validates it, and builds the + /// Mechanism. This is the file entry point — no separate resolve/validate step. + /// @param config_path Path to the main configuration file. + /// @return The parsed Mechanism, or all structural / file-loading / semantic errors. + std::expected Parse(const std::filesystem::path& config_path); + + /// @brief Parse a v1 mechanism from an in-memory YAML/JSON document string. + /// @param content The document contents (not a file path). + /// @return The parsed Mechanism, or all structural and semantic errors. + std::expected Parse(const std::string& content); + + /// @brief Validate an already-loaded YAML node (structure + semantics) and build the + /// Mechanism. Validation always runs first, so a caller cannot build from an + /// unvalidated node. + /// @param object The YAML node to validate and parse + /// @return The parsed Mechanism, or all structural and semantic errors encountered + std::expected Parse(const YAML::Node& object); + + private: + std::string config_path_; + + /// @brief Resolves a configuration file's file-list sections into a single inline node. + std::expected ResolveFileConfig(const std::filesystem::path& config_path); + + /// @brief Runs structural then semantic validation and, if both pass, builds the Mechanism, + /// mapping any thrown exception to an error. Uses config_path_ for message prefixes. + std::expected ValidateAndBuild(const YAML::Node& object); + + /// @brief Checks the structural schema of a mechanism YAML node (keys/shape only). Semantic + /// invariants are checked separately by ValidateSemantics. + Errors CheckSchema(const YAML::Node& object); + + /// @brief Constructs a Mechanism from an already-validated node. + Mechanism Build(const YAML::Node& object); + + inline void SetConfigPath(const std::string& config_path) + { + config_path_ = config_path; + } + + inline void SetDefaultConfigPath() + { + config_path_ = ""; + } + }; +} // namespace mechanism_configuration::v1 \ No newline at end of file diff --git a/src/detail/v1/reaction_parsers.hpp b/src/detail/v1/reaction_parsers.hpp new file mode 100644 index 00000000..41455c5f --- /dev/null +++ b/src/detail/v1/reaction_parsers.hpp @@ -0,0 +1,195 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include +#include + +#include + +namespace mechanism_configuration::v1 +{ + /// @brief Abstract interface for reaction parsers + class IReactionParser + { + public: + /// @brief Checks the schema of a YAML node representing a chemical reaction + /// @param object The YAML node containing reaction information + /// @param existing_species A list of species previously defined in the mechanism + /// @param existing_phases A list of chemical phases relevant to the reaction + /// @return A list of any validation errors encountered + virtual Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) = 0; + + /// @brief Parses a YAML node representing a chemical reaction + /// @param object The YAML node containing reaction information + /// @param reactions The container to which the parsed reactions will be added + virtual void Parse(const YAML::Node& object, types::Reactions& reactions) = 0; + + /// @brief Destructor + virtual ~IReactionParser() = default; + }; + + class ArrheniusParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class BranchedParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class EmissionParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class FirstOrderLossParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class PhotolysisParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class SurfaceParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class TaylorSeriesParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class TroeParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class TernaryChemicalActivationParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class TunnelingParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class UserDefinedParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + class LambdaRateConstantParser : public IReactionParser + { + public: + Errors CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) override; + + void Parse(const YAML::Node& object, types::Reactions& reactions) override; + }; + + /// @brief Returns a static map of reaction type keys to their parser instances + inline std::map>& GetReactionParserMap() + { + static std::map> reaction_parsers = [] + { + std::map> map; + map[std::string(keys::Arrhenius_key)] = std::make_unique(); + map[std::string(keys::FirstOrderLoss_key)] = std::make_unique(); + map[std::string(keys::Emission_key)] = std::make_unique(); + map[std::string(keys::Photolysis_key)] = std::make_unique(); + map[std::string(keys::Surface_key)] = std::make_unique(); + map[std::string(keys::TaylorSeries_key)] = std::make_unique(); + map[std::string(keys::Tunneling_key)] = std::make_unique(); + map[std::string(keys::Branched_key)] = std::make_unique(); + map[std::string(keys::Troe_key)] = std::make_unique(); + map[std::string(keys::TernaryChemicalActivation_key)] = std::make_unique(); + map[std::string(keys::UserDefined_key)] = std::make_unique(); + map[std::string(keys::LambdaRateConstant_key)] = std::make_unique(); + return map; + }(); + + return reaction_parsers; + } +} // namespace mechanism_configuration::v1 diff --git a/src/detail/v1/type_parsers.hpp b/src/detail/v1/type_parsers.hpp new file mode 100644 index 00000000..51ef29e6 --- /dev/null +++ b/src/detail/v1/type_parsers.hpp @@ -0,0 +1,51 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include + +#include +#include + +namespace mechanism_configuration::v1 +{ + /// @brief Parses a YAML node into a vector of Species + /// The input must be validated using CheckSpeciesSchema(). + /// This function assumes the structure and types are correct. + /// @param objects YAML node representing species list + /// @return A vector of parsed species + std::vector ParseSpecies(const YAML::Node& objects); + + /// @brief Parses a YAML node into a vector of Phases + /// Extracts each phase's name and its associated species (including optional properties). + /// Assumes the input YAML has already been validated for required structure and keys. + /// @param objects YAML node representing phase list + /// @return A vector of parsed Phases + std::vector ParsePhases(const YAML::Node& objects); + + /// @brief Parses a YAML node into reaction components + /// @param object YAML node representing ReactionComponents + /// @param key Key of the sequence to parse + /// @return Vector of `types::ReactionComponent` with names, optional coefficients, and comments + std::vector ParseReactionComponents(const YAML::Node& object, std::string_view key); + + /// @brief Parses a single reaction component from a YAML node. + /// The parser performs no validation or error checking. + /// @param object YAML node representing ReactionComponents + /// @param key Key identifying the reaction component + /// @return The parsed `types::ReactionComponent`, or a default-constructed one if none found + types::ReactionComponent ParseReactionComponent(const YAML::Node& object, std::string_view key); + + /// @brief Parses a collection of YAML nodes into reaction objects + /// Iterates over the given YAML nodes, identifies the parser for each reaction type, + /// and populates a `types::Reactions` container with the parsed reactions. + /// @param objects YAML node containing multiple reaction definitions + /// @return A `types::Reactions` object with all successfully parsed reactions + types::Reactions ParseReactions(const YAML::Node& objects); + +} // namespace mechanism_configuration::v1 diff --git a/src/detail/v1/type_schema.hpp b/src/detail/v1/type_schema.hpp new file mode 100644 index 00000000..7d5e9c6a --- /dev/null +++ b/src/detail/v1/type_schema.hpp @@ -0,0 +1,46 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include + +namespace mechanism_configuration::v1 +{ + // Structural (schema) validation of v1 YAML. These check required/optional keys and value + // shape only; semantic invariants (duplicate names, unknown species, phase membership) are + // checked separately by the version-neutral ValidateSemantics on the built Mechanism. + + /// @brief Schema-validates each species entry's keys. + /// @param species_list YAML node containing species entries + /// @return List of structural errors, or empty if all entries conform + Errors CheckSpeciesSchema(const YAML::Node& species_list); + + /// @brief Schema-validates each phase and its phase-species entries. + /// @param phases_list YAML node containing the list of phase entries + /// @param existing_species Unused; retained for call-site compatibility + /// @return List of structural errors, or empty if all entries conform + Errors CheckPhasesSchema(const YAML::Node& phases_list, const std::vector& existing_species); + + /// @brief Schema-validates a sequence of reaction components (reactants or products), + /// requiring exactly one of `name` / `species name` plus an optional coefficient. + /// @param object YAML node representing a sequence of reactants or products + /// @return List of structural errors, or empty if all entries conform + Errors CheckReactantsOrProductsSchema(const YAML::Node& object); + + /// @brief Schema-validates a YAML list of reactions: each has a defined, recognized type, + /// and then each reaction's keys are validated by its parser. + /// @param reactions_list YAML node containing the list of reactions + /// @param existing_species Unused; retained for call-site compatibility + /// @param existing_phases Unused; retained for call-site compatibility + /// @return List of structural errors, or empty if all entries conform + Errors CheckReactionsSchema( + const YAML::Node& reactions_list, + const std::vector& existing_species, + const std::vector& existing_phases); + +} // namespace mechanism_configuration::v1 \ No newline at end of file diff --git a/src/detail/v1/utils.hpp b/src/detail/v1/utils.hpp new file mode 100644 index 00000000..4411c8a3 --- /dev/null +++ b/src/detail/v1/utils.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#pragma once + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration::v1 +{ + /// @brief Ensures a YAML node is treated as a sequence + /// @param node The YAML node to convert + /// @return A YAML sequence node containing the original node(s) + YAML::Node AsSequence(const YAML::Node& node); + + void AppendFilePath(const std::string& config_path, Errors& errors); + + std::unordered_map GetComments(const YAML::Node& object); + + /// @brief Reads a reaction component's species reference, accepting either the + /// canonical `name` key or the legacy `species name` alias (v1 files). + /// @note Assumes the component has already been validated to contain exactly one of them. + std::string GetReactionComponentName(const YAML::Node& component); + +} // namespace mechanism_configuration::v1 diff --git a/src/development/CMakeLists.txt b/src/development/CMakeLists.txt deleted file mode 100644 index f482a88c..00000000 --- a/src/development/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -target_sources(mechanism_configuration - PRIVATE - mechanism.cpp - type_parsers.cpp - type_validators.cpp - utils.cpp -) - -add_subdirectory(models) -add_subdirectory(reactions) \ No newline at end of file diff --git a/src/development/mechanism.cpp b/src/development/mechanism.cpp deleted file mode 100644 index 4627bdac..00000000 --- a/src/development/mechanism.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace mechanism_configuration -{ - namespace development - { - - YAML::Node Parser::FileToYaml(const std::filesystem::path& config_path) - { - if (!std::filesystem::exists(config_path) || !std::filesystem::is_regular_file(config_path)) - { - throw std::runtime_error( - mc_fmt::format("Configuration file '{}' does not exist or is not a regular file.", config_path.string())); - } - - SetConfigPath(config_path.string()); - - try - { - return YAML::LoadFile(config_path.string()); - } - catch (const YAML::Exception& e) - { - throw std::runtime_error(mc_fmt::format("Failed to parse '{}': {}", config_path.string(), e.what())); - } - } - - Errors Parser::Validate(const YAML::Node& object, bool read_from_config_file) - { - if (!read_from_config_file) - { - SetDefaultConfigPath(); - } - - Errors errors; - - std::vector required_keys = { - validation::version, validation::species, validation::phases, validation::reactions - }; - std::vector optional_keys = { validation::name, validation::models }; - - // Return early if the required keys are not found - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - AppendFilePath(config_path_, validation_errors); - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - constexpr unsigned int MAJOR_VERSION = 2; - Version version = Version(object[validation::version].as()); - if (version.major != MAJOR_VERSION) - { - ErrorLocation error_location{ object[validation::version].Mark().line, object[validation::version].Mark().column }; - - std::string message = mc_fmt::format( - "{} error: The version must be '{}' but the invalid version number '{}' found.", - error_location, - MAJOR_VERSION, - version.major); - errors.push_back({ ConfigParseStatus::InvalidVersion, config_path_ + ":" + message }); - } - - validation_errors = ValidateSpecies(object[validation::species]); - if (!validation_errors.empty()) - { - AppendFilePath(config_path_, validation_errors); - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - auto parsed_species = ParseSpecies(object[validation::species]); - - validation_errors = ValidatePhases(object[validation::phases], parsed_species); - if (!validation_errors.empty()) - { - AppendFilePath(config_path_, validation_errors); - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - auto parsed_phases = ParsePhases(object[validation::phases]); - - validation_errors = ValidateReactions(object[validation::reactions], parsed_species, parsed_phases); - if (!validation_errors.empty()) - { - AppendFilePath(config_path_, validation_errors); - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - } - - if (object[validation::models]) - { - validation_errors = ValidateModels(object[validation::models], parsed_phases); - if (!validation_errors.empty()) - { - AppendFilePath(config_path_, validation_errors); - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - } - } - - return errors; - } - - types::Mechanism Parser::Parse(const YAML::Node& object) - { - types::Mechanism mechanism; - - mechanism.version = Version(object[validation::version].as()); - mechanism.species = ParseSpecies(object[validation::species]); - mechanism.phases = ParsePhases(object[validation::phases]); - mechanism.reactions = ParseReactions(object[validation::reactions]); - - if (object[validation::name]) - { - mechanism.name = object[validation::name].as(); - } - if (object[validation::models]) - { - mechanism.models = ParseModels(object[validation::models]); - } - - return mechanism; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/models/CMakeLists.txt b/src/development/models/CMakeLists.txt deleted file mode 100644 index dc2ea034..00000000 --- a/src/development/models/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_subdirectory(parsers) -add_subdirectory(validators) \ No newline at end of file diff --git a/src/development/models/parsers/CMakeLists.txt b/src/development/models/parsers/CMakeLists.txt deleted file mode 100644 index 4fdd2d4c..00000000 --- a/src/development/models/parsers/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -target_sources(mechanism_configuration - PRIVATE - gas.cpp - modal.cpp -) \ No newline at end of file diff --git a/src/development/models/parsers/gas.cpp b/src/development/models/parsers/gas.cpp deleted file mode 100644 index 58135ff5..00000000 --- a/src/development/models/parsers/gas.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include - -#include - -namespace mechanism_configuration -{ - namespace development - { - void GasModelParser::Parse(const YAML::Node& object, types::Models& models) - { - types::GasModel model; - - model.type = object[validation::type].as(); - model.phase = object[validation::phase].as(); - model.unknown_properties = GetComments(object); - - if (object[validation::name]) - { - model.name = object[validation::name].as(); - } - - models.gas_model = std::move(model); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/models/parsers/modal.cpp b/src/development/models/parsers/modal.cpp deleted file mode 100644 index 79af762b..00000000 --- a/src/development/models/parsers/modal.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include - -#include - -namespace mechanism_configuration -{ - namespace development - { - void ModalModelParser::Parse(const YAML::Node& object, types::Models& models) - { - types::ModalModel model; - - model.type = object[validation::type].as(); - model.unknown_properties = GetComments(object); - - for (const auto& mode_object : object[validation::modes]) - { - types::Mode mode; - mode.name = mode_object[validation::name].as(); - mode.geometric_mean_diameter = mode_object[validation::geometric_mean_diameter].as(); - mode.geometric_standard_deviation = mode_object[validation::geometric_standard_deviation].as(); - mode.phase = mode_object[validation::phase].as(); - mode.unknown_properties = GetComments(mode_object); - model.modes.emplace_back(std::move(mode)); - } - - if (object[validation::name]) - { - model.name = object[validation::name].as(); - } - - models.modal_model = std::move(model); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/models/validators/CMakeLists.txt b/src/development/models/validators/CMakeLists.txt deleted file mode 100644 index 4fdd2d4c..00000000 --- a/src/development/models/validators/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -target_sources(mechanism_configuration - PRIVATE - gas.cpp - modal.cpp -) \ No newline at end of file diff --git a/src/development/models/validators/gas.cpp b/src/development/models/validators/gas.cpp deleted file mode 100644 index c9da44e8..00000000 --- a/src/development/models/validators/gas.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -#include - -namespace mechanism_configuration -{ - namespace development - { - Errors GasModelParser::Validate(const YAML::Node& object, const std::vector& existing_phases) - { - std::vector required_keys = { validation::type, validation::phase }; - std::vector optional_keys = { validation::name }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - CheckPhaseExists(object, validation::phase, existing_phases, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/models/validators/modal.cpp b/src/development/models/validators/modal.cpp deleted file mode 100644 index dfbadd24..00000000 --- a/src/development/models/validators/modal.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -#include - -namespace mechanism_configuration -{ - namespace development - { - Errors ModalModelParser::Validate(const YAML::Node& object, const std::vector& existing_phases) - { - std::vector required_top_level_keys = { validation::type, validation::modes }; - std::vector optional_top_level_keys = { validation::name }; - - std::vector required_second_level_keys = { - validation::name, validation::geometric_mean_diameter, validation::geometric_standard_deviation, validation::phase - }; - std::vector optional_second_level_keys = {}; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_top_level_keys, optional_top_level_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - if (!object[validation::modes].IsSequence()) - { - const auto& node = object[validation::modes]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: Expected 'modes' to be a sequence, but found a different type in the '{}' model.", - error_location, - object[validation::type].as()); - - errors.push_back({ ConfigParseStatus::InvalidType, message }); - - return errors; - } - - for (const auto& mode_object : object[validation::modes]) - { - validation_errors = ValidateSchema(mode_object, required_second_level_keys, optional_second_level_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - continue; - } - - CheckPhaseExists( - mode_object, - validation::phase, - existing_phases, - errors, - ConfigParseStatus::UnknownPhase, - object[validation::type].as()); - } - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/CMakeLists.txt b/src/development/reactions/CMakeLists.txt deleted file mode 100644 index dc2ea034..00000000 --- a/src/development/reactions/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_subdirectory(parsers) -add_subdirectory(validators) \ No newline at end of file diff --git a/src/development/reactions/parsers/CMakeLists.txt b/src/development/reactions/parsers/CMakeLists.txt deleted file mode 100644 index ce25ac23..00000000 --- a/src/development/reactions/parsers/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -target_sources(mechanism_configuration - PRIVATE - aqueous_equilibrium.cpp - arrhenius.cpp - branched.cpp - condensed_phase_arrhenius.cpp - condensed_phase_photolysis.cpp - emission.cpp - first_order_loss.cpp - henrys_law.cpp - photolysis.cpp - simpol_phase_transfer.cpp - surface.cpp - taylor_series.cpp - ternary_chemical_activation.cpp - troe.cpp - tunneling.cpp - user_defined.cpp - lambda_rate_constant.cpp - wet_deposition.cpp -) \ No newline at end of file diff --git a/src/development/reactions/parsers/aqueous_equilibrium.cpp b/src/development/reactions/parsers/aqueous_equilibrium.cpp deleted file mode 100644 index 170cf261..00000000 --- a/src/development/reactions/parsers/aqueous_equilibrium.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void AqueousEquilibriumParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::AqueousEquilibrium aqueous_equilibrium; - - aqueous_equilibrium.condensed_phase = object[validation::condensed_phase].as(); - aqueous_equilibrium.condensed_phase_water = object[validation::condensed_phase_water].as(); - aqueous_equilibrium.k_reverse = object[validation::k_reverse].as(); - aqueous_equilibrium.reactants = ParseReactionComponents(object, validation::reactants); - aqueous_equilibrium.products = ParseReactionComponents(object, validation::products); - aqueous_equilibrium.unknown_properties = GetComments(object); - - if (object[validation::A]) - { - aqueous_equilibrium.A = object[validation::A].as(); - } - if (object[validation::C]) - { - aqueous_equilibrium.C = object[validation::C].as(); - } - if (object[validation::name]) - { - aqueous_equilibrium.name = object[validation::name].as(); - } - - reactions.aqueous_equilibrium.emplace_back(std::move(aqueous_equilibrium)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/arrhenius.cpp b/src/development/reactions/parsers/arrhenius.cpp deleted file mode 100644 index ada280fb..00000000 --- a/src/development/reactions/parsers/arrhenius.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Parses a YAML-defined Arrhenius reaction and appends it to the reaction list. - /// Extracts reactants, products, kinetic parameters (A–E, Ea), gas phase, - /// optional metadata (name, comments), and constructs a `types::Arrhenius` object. - /// @param object The YAML node representing the reaction - /// @param reactions The reactions container to append the parsed reaction to - void ArrheniusParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::Arrhenius arrhenius; - - arrhenius.gas_phase = object[validation::gas_phase].as(); - arrhenius.reactants = ParseReactionComponents(object, validation::reactants); - arrhenius.products = ParseReactionComponents(object, validation::products); - arrhenius.unknown_properties = GetComments(object); - - if (object[validation::A]) - { - arrhenius.A = object[validation::A].as(); - } - if (object[validation::B]) - { - arrhenius.B = object[validation::B].as(); - } - if (object[validation::C]) - { - arrhenius.C = object[validation::C].as(); - } - if (object[validation::D]) - { - arrhenius.D = object[validation::D].as(); - } - if (object[validation::E]) - { - arrhenius.E = object[validation::E].as(); - } - if (object[validation::Ea]) - { - arrhenius.C = -1 * object[validation::Ea].as() / constants::boltzmann; - } - if (object[validation::name]) - { - arrhenius.name = object[validation::name].as(); - } - - reactions.arrhenius.emplace_back(std::move(arrhenius)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/branched.cpp b/src/development/reactions/parsers/branched.cpp deleted file mode 100644 index c8a11e0c..00000000 --- a/src/development/reactions/parsers/branched.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void BranchedParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::Branched branched; - - branched.gas_phase = object[validation::gas_phase].as(); - branched.reactants = ParseReactionComponents(object, validation::reactants); - branched.alkoxy_products = ParseReactionComponents(object, validation::alkoxy_products); - branched.nitrate_products = ParseReactionComponents(object, validation::nitrate_products); - branched.unknown_properties = GetComments(object); - - if (object[validation::X]) - { - branched.X = object[validation::X].as(); - } - if (object[validation::Y]) - { - branched.Y = object[validation::Y].as(); - } - if (object[validation::a0]) - { - branched.a0 = object[validation::a0].as(); - } - if (object[validation::n]) - { - branched.n = object[validation::n].as(); - } - if (object[validation::name]) - { - branched.name = object[validation::name].as(); - } - - reactions.branched.emplace_back(std::move(branched)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/condensed_phase_arrhenius.cpp b/src/development/reactions/parsers/condensed_phase_arrhenius.cpp deleted file mode 100644 index e70b68ee..00000000 --- a/src/development/reactions/parsers/condensed_phase_arrhenius.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void CondensedPhaseArrheniusParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::CondensedPhaseArrhenius condensed_phase_arrhenius; - - condensed_phase_arrhenius.condensed_phase = object[validation::condensed_phase].as(); - condensed_phase_arrhenius.reactants = ParseReactionComponents(object, validation::reactants); - condensed_phase_arrhenius.products = ParseReactionComponents(object, validation::products); - condensed_phase_arrhenius.unknown_properties = GetComments(object); - - if (object[validation::A]) - { - condensed_phase_arrhenius.A = object[validation::A].as(); - } - if (object[validation::B]) - { - condensed_phase_arrhenius.B = object[validation::B].as(); - } - if (object[validation::C]) - { - condensed_phase_arrhenius.C = object[validation::C].as(); - } - if (object[validation::D]) - { - condensed_phase_arrhenius.D = object[validation::D].as(); - } - if (object[validation::E]) - { - condensed_phase_arrhenius.E = object[validation::E].as(); - } - if (object[validation::Ea]) - { - condensed_phase_arrhenius.C = -1 * object[validation::Ea].as() / constants::boltzmann; - } - if (object[validation::name]) - { - condensed_phase_arrhenius.name = object[validation::name].as(); - } - - reactions.condensed_phase_arrhenius.emplace_back(std::move(condensed_phase_arrhenius)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/condensed_phase_photolysis.cpp b/src/development/reactions/parsers/condensed_phase_photolysis.cpp deleted file mode 100644 index f6c37ae4..00000000 --- a/src/development/reactions/parsers/condensed_phase_photolysis.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void CondensedPhasePhotolysisParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::CondensedPhasePhotolysis condensed_phase_photolysis; - - condensed_phase_photolysis.condensed_phase = object[validation::condensed_phase].as(); - condensed_phase_photolysis.reactants = ParseReactionComponent(object, validation::reactants); - condensed_phase_photolysis.products = ParseReactionComponents(object, validation::products); - condensed_phase_photolysis.unknown_properties = GetComments(object); - - if (object[validation::scaling_factor]) - { - condensed_phase_photolysis.scaling_factor = object[validation::scaling_factor].as(); - } - if (object[validation::name]) - { - condensed_phase_photolysis.name = object[validation::name].as(); - } - - reactions.condensed_phase_photolysis.emplace_back(std::move(condensed_phase_photolysis)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/emission.cpp b/src/development/reactions/parsers/emission.cpp deleted file mode 100644 index fa3510a9..00000000 --- a/src/development/reactions/parsers/emission.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void EmissionParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::Emission emission; - - emission.gas_phase = object[validation::gas_phase].as(); - emission.products = ParseReactionComponents(object, validation::products); - emission.unknown_properties = GetComments(object); - - if (object[validation::scaling_factor]) - { - emission.scaling_factor = object[validation::scaling_factor].as(); - } - if (object[validation::name]) - { - emission.name = object[validation::name].as(); - } - - reactions.emission.emplace_back(std::move(emission)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/first_order_loss.cpp b/src/development/reactions/parsers/first_order_loss.cpp deleted file mode 100644 index c16b7157..00000000 --- a/src/development/reactions/parsers/first_order_loss.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void FirstOrderLossParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::FirstOrderLoss first_order_loss; - - first_order_loss.gas_phase = object[validation::gas_phase].as(); - first_order_loss.reactants = ParseReactionComponent(object, validation::reactants); - first_order_loss.unknown_properties = GetComments(object); - - if (object[validation::scaling_factor]) - { - first_order_loss.scaling_factor = object[validation::scaling_factor].as(); - } - if (object[validation::name]) - { - first_order_loss.name = object[validation::name].as(); - } - - reactions.first_order_loss.emplace_back(std::move(first_order_loss)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/henrys_law.cpp b/src/development/reactions/parsers/henrys_law.cpp deleted file mode 100644 index d7b3b9f2..00000000 --- a/src/development/reactions/parsers/henrys_law.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void HenrysLawParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::HenrysLaw henrys_law; - - // Parse gas - types::Phase gas; - gas.name = object[validation::gas][validation::name].as(); - - for (const auto& elem : object[validation::gas][validation::species]) - { - types::PhaseSpecies phase_species; - phase_species.name = elem[validation::name].as(); - phase_species.unknown_properties = GetComments(elem); - if (elem[validation::diffusion_coefficient]) - { - phase_species.diffusion_coefficient = elem[validation::diffusion_coefficient].as(); - } - gas.species.emplace_back(std::move(phase_species)); - } - - henrys_law.gas = std::move(gas); - henrys_law.particle.phase = object[validation::particle][validation::phase].as(); - henrys_law.particle.solutes = ParseReactionComponents(object[validation::particle], validation::solutes); - henrys_law.particle.solvent = ParseReactionComponent(object[validation::particle], validation::solvent); - henrys_law.unknown_properties = GetComments(object); - - if (object[validation::name]) - { - henrys_law.name = object[validation::name].as(); - } - - reactions.henrys_law.emplace_back(std::move(henrys_law)); - } - - } // namespace development -} // namespace mechanism_configuration \ No newline at end of file diff --git a/src/development/reactions/parsers/lambda_rate_constant.cpp b/src/development/reactions/parsers/lambda_rate_constant.cpp deleted file mode 100644 index 86fdaed6..00000000 --- a/src/development/reactions/parsers/lambda_rate_constant.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void LambdaRateConstantParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::LambdaRateConstant lambda_rate_constant; - - lambda_rate_constant.reactants = ParseReactionComponents(object, validation::reactants); - lambda_rate_constant.products = ParseReactionComponents(object, validation::products); - lambda_rate_constant.gas_phase = object[validation::gas_phase].as(); - lambda_rate_constant.lambda_function = object[validation::lambda_function].as(); - lambda_rate_constant.unknown_properties = GetComments(object); - - if (object[validation::name]) - { - lambda_rate_constant.name = object[validation::name].as(); - } - - reactions.lambda_rate_constant.emplace_back(std::move(lambda_rate_constant)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/photolysis.cpp b/src/development/reactions/parsers/photolysis.cpp deleted file mode 100644 index ea3db3cd..00000000 --- a/src/development/reactions/parsers/photolysis.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void PhotolysisParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::Photolysis photolysis; - - photolysis.gas_phase = object[validation::gas_phase].as(); - photolysis.reactants = ParseReactionComponent(object, validation::reactants); - photolysis.products = ParseReactionComponents(object, validation::products); - photolysis.unknown_properties = GetComments(object); - - if (object[validation::scaling_factor]) - { - photolysis.scaling_factor = object[validation::scaling_factor].as(); - } - if (object[validation::name]) - { - photolysis.name = object[validation::name].as(); - } - - reactions.photolysis.emplace_back(std::move(photolysis)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/simpol_phase_transfer.cpp b/src/development/reactions/parsers/simpol_phase_transfer.cpp deleted file mode 100644 index 210c71ea..00000000 --- a/src/development/reactions/parsers/simpol_phase_transfer.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void SimpolPhaseTransferParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::SimpolPhaseTransfer simpol_phase_transfer; - - simpol_phase_transfer.gas_phase = object[validation::gas_phase].as(); - simpol_phase_transfer.condensed_phase = object[validation::condensed_phase].as(); - simpol_phase_transfer.gas_phase_species = ParseReactionComponents(object, validation::gas_phase_species); - simpol_phase_transfer.condensed_phase_species = ParseReactionComponents(object, validation::condensed_phase_species); - simpol_phase_transfer.unknown_properties = GetComments(object); - - for (size_t i = 0; i < 4; ++i) - { - simpol_phase_transfer.B[i] = object[validation::B][i].as(); - } - - if (object[validation::name]) - { - simpol_phase_transfer.name = object[validation::name].as(); - } - - reactions.simpol_phase_transfer.emplace_back(std::move(simpol_phase_transfer)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/surface.cpp b/src/development/reactions/parsers/surface.cpp deleted file mode 100644 index bd898c1e..00000000 --- a/src/development/reactions/parsers/surface.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void SurfaceParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::Surface surface; - - surface.gas_phase = object[validation::gas_phase].as(); - surface.condensed_phase = object[validation::condensed_phase].as(); - surface.gas_phase_species = ParseReactionComponent(object, validation::gas_phase_species); - surface.gas_phase_products = ParseReactionComponents(object, validation::gas_phase_products); - surface.unknown_properties = GetComments(object); - - if (object[validation::reaction_probability]) - { - surface.reaction_probability = object[validation::reaction_probability].as(); - } - if (object[validation::name]) - { - surface.name = object[validation::name].as(); - } - - reactions.surface.emplace_back(std::move(surface)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/taylor_series.cpp b/src/development/reactions/parsers/taylor_series.cpp deleted file mode 100644 index c97c92cb..00000000 --- a/src/development/reactions/parsers/taylor_series.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Parses a YAML-defined Taylor Series reaction and appends it to the reaction list. - /// Extracts reactants, products, kinetic parameters (A–E, Ea), gas phase, - /// optional metadata (name, comments), and constructs a `types::TaylorSeries` object. - /// @param object The YAML node representing the reaction - /// @param reactions The reactions container to append the parsed reaction to - void TaylorSeriesParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::TaylorSeries taylor_series; - - taylor_series.gas_phase = object[validation::gas_phase].as(); - taylor_series.reactants = ParseReactionComponents(object, validation::reactants); - taylor_series.products = ParseReactionComponents(object, validation::products); - taylor_series.unknown_properties = GetComments(object); - - if (object[validation::A]) - { - taylor_series.A = object[validation::A].as(); - } - if (object[validation::B]) - { - taylor_series.B = object[validation::B].as(); - } - if (object[validation::C]) - { - taylor_series.C = object[validation::C].as(); - } - if (object[validation::D]) - { - taylor_series.D = object[validation::D].as(); - } - if (object[validation::E]) - { - taylor_series.E = object[validation::E].as(); - } - if (object[validation::Ea]) - { - taylor_series.C = -1 * object[validation::Ea].as() / constants::boltzmann; - } - if (object[validation::taylor_coefficients]) - { - taylor_series.taylor_coefficients = object[validation::taylor_coefficients].as>(); - } - if (object[validation::name]) - { - taylor_series.name = object[validation::name].as(); - } - - reactions.taylor_series.emplace_back(std::move(taylor_series)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/ternary_chemical_activation.cpp b/src/development/reactions/parsers/ternary_chemical_activation.cpp deleted file mode 100644 index f41b983c..00000000 --- a/src/development/reactions/parsers/ternary_chemical_activation.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void TernaryChemicalActivationParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::TernaryChemicalActivation ternary; - - ternary.gas_phase = object[validation::gas_phase].as(); - ternary.reactants = ParseReactionComponents(object, validation::reactants); - ternary.products = ParseReactionComponents(object, validation::products); - ternary.unknown_properties = GetComments(object); - - if (object[validation::k0_A]) - { - ternary.k0_A = object[validation::k0_A].as(); - } - if (object[validation::k0_B]) - { - ternary.k0_B = object[validation::k0_B].as(); - } - if (object[validation::k0_C]) - { - ternary.k0_C = object[validation::k0_C].as(); - } - if (object[validation::kinf_A]) - { - ternary.kinf_A = object[validation::kinf_A].as(); - } - if (object[validation::kinf_B]) - { - ternary.kinf_B = object[validation::kinf_B].as(); - } - if (object[validation::kinf_C]) - { - ternary.kinf_C = object[validation::kinf_C].as(); - } - if (object[validation::Fc]) - { - ternary.Fc = object[validation::Fc].as(); - } - if (object[validation::N]) - { - ternary.N = object[validation::N].as(); - } - if (object[validation::name]) - { - ternary.name = object[validation::name].as(); - } - - reactions.ternary_chemical_activation.emplace_back(std::move(ternary)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/troe.cpp b/src/development/reactions/parsers/troe.cpp deleted file mode 100644 index 7a45bb97..00000000 --- a/src/development/reactions/parsers/troe.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void TroeParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::Troe troe; - - troe.gas_phase = object[validation::gas_phase].as(); - troe.reactants = ParseReactionComponents(object, validation::reactants); - troe.products = ParseReactionComponents(object, validation::products); - troe.unknown_properties = GetComments(object); - - if (object[validation::k0_A]) - { - troe.k0_A = object[validation::k0_A].as(); - } - if (object[validation::k0_B]) - { - troe.k0_B = object[validation::k0_B].as(); - } - if (object[validation::k0_C]) - { - troe.k0_C = object[validation::k0_C].as(); - } - if (object[validation::kinf_A]) - { - troe.kinf_A = object[validation::kinf_A].as(); - } - if (object[validation::kinf_B]) - { - troe.kinf_B = object[validation::kinf_B].as(); - } - if (object[validation::kinf_C]) - { - troe.kinf_C = object[validation::kinf_C].as(); - } - if (object[validation::Fc]) - { - troe.Fc = object[validation::Fc].as(); - } - if (object[validation::N]) - { - troe.N = object[validation::N].as(); - } - if (object[validation::name]) - { - troe.name = object[validation::name].as(); - } - - reactions.troe.emplace_back(std::move(troe)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/tunneling.cpp b/src/development/reactions/parsers/tunneling.cpp deleted file mode 100644 index ed25cabf..00000000 --- a/src/development/reactions/parsers/tunneling.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void TunnelingParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::Tunneling tunneling; - - tunneling.gas_phase = object[validation::gas_phase].as(); - tunneling.reactants = ParseReactionComponents(object, validation::reactants); - tunneling.products = ParseReactionComponents(object, validation::products); - tunneling.unknown_properties = GetComments(object); - - if (object[validation::A]) - { - tunneling.A = object[validation::A].as(); - } - if (object[validation::B]) - { - tunneling.B = object[validation::B].as(); - } - if (object[validation::C]) - { - tunneling.C = object[validation::C].as(); - } - if (object[validation::name]) - { - tunneling.name = object[validation::name].as(); - } - - reactions.tunneling.emplace_back(std::move(tunneling)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/user_defined.cpp b/src/development/reactions/parsers/user_defined.cpp deleted file mode 100644 index a4702370..00000000 --- a/src/development/reactions/parsers/user_defined.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void UserDefinedParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::UserDefined user_defined; - - user_defined.reactants = ParseReactionComponents(object, validation::reactants); - user_defined.products = ParseReactionComponents(object, validation::products); - user_defined.gas_phase = object[validation::gas_phase].as(); - user_defined.unknown_properties = GetComments(object); - - if (object[validation::scaling_factor]) - { - user_defined.scaling_factor = object[validation::scaling_factor].as(); - } - - if (object[validation::name]) - { - user_defined.name = object[validation::name].as(); - } - - reactions.user_defined.emplace_back(std::move(user_defined)); - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/parsers/wet_deposition.cpp b/src/development/reactions/parsers/wet_deposition.cpp deleted file mode 100644 index 14642776..00000000 --- a/src/development/reactions/parsers/wet_deposition.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - void WetDepositionParser::Parse(const YAML::Node& object, types::Reactions& reactions) - { - types::WetDeposition wet_deposition; - - wet_deposition.condensed_phase = object[validation::condensed_phase].as(); - wet_deposition.unknown_properties = GetComments(object); - - if (object[validation::scaling_factor]) - { - wet_deposition.scaling_factor = object[validation::scaling_factor].as(); - } - - if (object[validation::name]) - { - wet_deposition.name = object[validation::name].as(); - } - - reactions.wet_deposition.emplace_back(std::move(wet_deposition)); - } - - } // namespace development -} // namespace mechanism_configuration \ No newline at end of file diff --git a/src/development/reactions/validators/CMakeLists.txt b/src/development/reactions/validators/CMakeLists.txt deleted file mode 100644 index ce25ac23..00000000 --- a/src/development/reactions/validators/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -target_sources(mechanism_configuration - PRIVATE - aqueous_equilibrium.cpp - arrhenius.cpp - branched.cpp - condensed_phase_arrhenius.cpp - condensed_phase_photolysis.cpp - emission.cpp - first_order_loss.cpp - henrys_law.cpp - photolysis.cpp - simpol_phase_transfer.cpp - surface.cpp - taylor_series.cpp - ternary_chemical_activation.cpp - troe.cpp - tunneling.cpp - user_defined.cpp - lambda_rate_constant.cpp - wet_deposition.cpp -) \ No newline at end of file diff --git a/src/development/reactions/validators/aqueous_equilibrium.cpp b/src/development/reactions/validators/aqueous_equilibrium.cpp deleted file mode 100644 index ddb14d77..00000000 --- a/src/development/reactions/validators/aqueous_equilibrium.cpp +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Aqueous Equilibrium reaction entry. - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors AqueousEquilibriumParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { validation::type, - validation::reactants, - validation::products, - validation::condensed_phase, - validation::condensed_phase_water, - validation::k_reverse }; - std::vector optional_keys = { validation::name, validation::A, validation::C }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::condensed_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/arrhenius.cpp b/src/development/reactions/validators/arrhenius.cpp deleted file mode 100644 index 43ebbdba..00000000 --- a/src/development/reactions/validators/arrhenius.cpp +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Arrhenius reaction entry - /// Performs schema validation, checks for mutually exclusive parameters (`Ea` vs `C`), - /// ensures all referenced species and phases exist, and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors ArrheniusParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::A, validation::B, validation::C, validation::D, - validation::E, validation::Ea, validation::name }; - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (object[validation::Ea] && object[validation::C]) - { - const auto& node = object[validation::Ea]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: Mutually exclusive option of 'Ea' and 'C' found in '{}' reaction.", - error_location, - object[validation::type].as()); - - errors.push_back({ ConfigParseStatus::MutuallyExclusiveOption, message }); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/branched.cpp b/src/development/reactions/validators/branched.cpp deleted file mode 100644 index 5c1783d2..00000000 --- a/src/development/reactions/validators/branched.cpp +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Branched reaction entry - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors BranchedParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { validation::type, - validation::gas_phase, - validation::reactants, - validation::alkoxy_products, - validation::nitrate_products }; - std::vector optional_keys = { - validation::name, validation::X, validation::Y, validation::a0, validation::n - }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Alkoxy products - validation_errors = ValidateReactantsOrProducts(object[validation::alkoxy_products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Nitrate products - validation_errors = ValidateReactantsOrProducts(object[validation::nitrate_products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::alkoxy_products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::nitrate_products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/condensed_phase_arrhenius.cpp b/src/development/reactions/validators/condensed_phase_arrhenius.cpp deleted file mode 100644 index c1f11e3d..00000000 --- a/src/development/reactions/validators/condensed_phase_arrhenius.cpp +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Condensed-phase Arrhenius reaction entry - /// Performs schema validation, checks for mutually exclusive parameters (`Ea` vs `C`), - /// ensures all referenced species and phases exist, and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors CondensedPhaseArrheniusParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::condensed_phase - }; - std::vector optional_keys = { validation::A, validation::B, validation::C, validation::D, - validation::E, validation::Ea, validation::name }; - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (object[validation::Ea] && object[validation::C]) - { - const auto& node = object[validation::Ea]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: Mutually exclusive option of 'Ea' and 'C' found in '{}' reaction.", - error_location, - object[validation::type].as()); - - errors.push_back({ ConfigParseStatus::MutuallyExclusiveOption, message }); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::condensed_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Validate reaction species presence in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/condensed_phase_photolysis.cpp b/src/development/reactions/validators/condensed_phase_photolysis.cpp deleted file mode 100644 index 6469fb6f..00000000 --- a/src/development/reactions/validators/condensed_phase_photolysis.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Condensed-phase Photolysis reaction entry. - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors CondensedPhasePhotolysisParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::condensed_phase - }; - std::vector optional_keys = { validation::name, validation::scaling_factor }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Validates the number of reactants - // This must be done before collecting errors from the products - if (species_node_pairs.size() > 1) - { - const auto& node = object[validation::reactants]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: '{}' reaction requires one reactant, but {} were provided.", - error_location, - object[validation::type].as(), - species_node_pairs.size()); - - errors.push_back({ ConfigParseStatus::TooManyReactionComponents, message }); - } - - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::condensed_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/emission.cpp b/src/development/reactions/validators/emission.cpp deleted file mode 100644 index 5bd8aa17..00000000 --- a/src/development/reactions/validators/emission.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Emission reaction entry. - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors EmissionParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { validation::products, validation::type, validation::gas_phase }; - std::vector optional_keys = { validation::name, validation::scaling_factor }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/first_order_loss.cpp b/src/development/reactions/validators/first_order_loss.cpp deleted file mode 100644 index 5adf1b48..00000000 --- a/src/development/reactions/validators/first_order_loss.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined First order loss reaction entry. - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors FirstOrderLossParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { validation::reactants, validation::type, validation::gas_phase }; - std::vector optional_keys = { validation::name, validation::scaling_factor }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - if (species_node_pairs.size() > 1) - { - const auto& node = object[validation::reactants]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: '{}' reaction requires one reactant, but {} were provided.", - error_location, - object[validation::type].as(), - species_node_pairs.size()); - - errors.push_back({ ConfigParseStatus::TooManyReactionComponents, message }); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/henrys_law.cpp b/src/development/reactions/validators/henrys_law.cpp deleted file mode 100644 index c9839d12..00000000 --- a/src/development/reactions/validators/henrys_law.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Henry's Law reaction entry. - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors HenrysLawParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { validation::type, validation::gas, validation::particle }; - std::vector opt_keys = { validation::name }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, opt_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Gas phase - validation_errors = ValidatePhases(object[validation::gas], existing_species); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Particle - validation_errors = ValidateParticles(object[validation::particle]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - // Gather gas and particle species node pairs - std::vector> gas_species_node_pairs; - - // Although the type being validated is PhaseSpecies instead of ReactionComponent, - // the corresponding struct is conceptually the same. (diffusion coefficient vs. coefficient) - // Treating these entries as ReactionComponent objects is acceptable. - for (const auto& obj : object[validation::gas][validation::species]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - gas_species_node_pairs.emplace_back(std::move(component), obj); - } - - std::vector> particle_species_node_pairs; - - // Solvent - for (const auto& obj : object[validation::particle][validation::solvent]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - particle_species_node_pairs.emplace_back(component, obj); - } - - // Validates the number of solvent - // This must be done before collecting errors from the solutes - if (particle_species_node_pairs.size() > 1) - { - const auto& node = object[validation::particle][validation::solvent]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: '{}' reaction requires one solute, but {} were provided.", - error_location, - object[validation::type].as(), - particle_species_node_pairs.size()); - - errors.push_back({ ConfigParseStatus::TooManyReactionComponents, message }); - } - - // Solutes - for (const auto& obj : object[validation::particle][validation::solutes]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - particle_species_node_pairs.emplace_back(std::move(component), obj); - } - - // Unknown species - std::vector unknown_species = FindUnknownObjectsByName(existing_species, gas_species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - unknown_species = FindUnknownObjectsByName(existing_species, particle_species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - auto gas_phase_opt = CheckPhaseExists( - object[validation::gas], - validation::name, - existing_phases, - errors, - ConfigParseStatus::UnknownPhase, - object[validation::type].as()); - - auto particle_phase_opt = CheckPhaseExists( - object[validation::particle], - validation::phase, - existing_phases, - errors, - ConfigParseStatus::UnknownPhase, - object[validation::type].as()); - if (!gas_phase_opt || !particle_phase_opt) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - CheckSpeciesPresenceInPhase(object, gas_phase_opt->get(), gas_species_node_pairs, errors); - CheckSpeciesPresenceInPhase(object, particle_phase_opt->get(), particle_species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/lambda_rate_constant.cpp b/src/development/reactions/validators/lambda_rate_constant.cpp deleted file mode 100644 index ea8e82f6..00000000 --- a/src/development/reactions/validators/lambda_rate_constant.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Lambda Rate Constant reaction entry - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors LambdaRateConstantParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase, validation::lambda_function - }; - std::vector optional_keys = { validation::name }; - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/photolysis.cpp b/src/development/reactions/validators/photolysis.cpp deleted file mode 100644 index df45bfd0..00000000 --- a/src/development/reactions/validators/photolysis.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Photolysis reaction entry. - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors PhotolysisParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::scaling_factor }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Validates the number of reactants - // This must be done before collecting errors from the products - if (species_node_pairs.size() > 1) - { - const auto& node = object[validation::reactants]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: '{}' reaction requires one reactant, but {} were provided.", - error_location, - object[validation::type].as(), - species_node_pairs.size()); - - errors.push_back({ ConfigParseStatus::TooManyReactionComponents, message }); - } - - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/simpol_phase_transfer.cpp b/src/development/reactions/validators/simpol_phase_transfer.cpp deleted file mode 100644 index f4d8cc65..00000000 --- a/src/development/reactions/validators/simpol_phase_transfer.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Simpol Phase Transfer reaction entry. - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors SimpolPhaseTransferParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { validation::type, - validation::gas_phase, - validation::gas_phase_species, - validation::condensed_phase, - validation::condensed_phase_species, - validation::B }; - std::vector optional_keys = { validation::name }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - validation_errors = ValidateReactantsOrProducts(object[validation::gas_phase_species]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - validation_errors = ValidateReactantsOrProducts(object[validation::condensed_phase_species]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - // Validate parameter 'B' - constexpr double NUM_PARAMS = 4; - if (!object[validation::B].IsSequence() || object[validation::B].size() != NUM_PARAMS) - { - const auto& node = object[validation::B]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string issue; - if (!object[validation::B].IsSequence()) - { - issue = "value must be a sequence"; - } - else - { - issue = mc_fmt::format("requires {} parameters, but {} were provided", NUM_PARAMS, object[validation::B].size()); - } - - std::string message = mc_fmt::format( - "{} error: '{}' reaction parameter 'B' {}.", error_location, object[validation::type].as(), issue); - - errors.push_back({ ConfigParseStatus::InvalidParameterNumber, message }); - } - - // Validates the number of gas phase species - std::vector> gas_species_node_pairs; - - for (const auto& obj : object[validation::gas_phase_species]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - gas_species_node_pairs.emplace_back(component, obj); - } - - if (gas_species_node_pairs.size() > 1) - { - const auto& node = object[validation::gas_phase_species]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: '{}' reaction requires one gas phase, but {} were provided.", - error_location, - object[validation::type].as(), - gas_species_node_pairs.size()); - - errors.push_back({ ConfigParseStatus::TooManyReactionComponents, message }); - } - - // Check for unknown species in gas phase species - std::vector unknown_species = FindUnknownObjectsByName(existing_species, gas_species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Validates the number of condensed phase species - std::vector> condensed_species_node_pairs; - - for (const auto& obj : object[validation::condensed_phase_species]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - condensed_species_node_pairs.emplace_back(component, obj); - } - - if (condensed_species_node_pairs.size() > 1) - { - const auto& node = object[validation::condensed_phase_species]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: '{}' reaction requires one condensed phase, but {} were provided.", - error_location, - object[validation::type].as(), - condensed_species_node_pairs.size()); - - errors.push_back({ ConfigParseStatus::TooManyReactionComponents, message }); - } - - // Check for unknown species in condensed phase species - unknown_species = FindUnknownObjectsByName(existing_species, condensed_species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto gas_phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!gas_phase_optional) - { - return errors; - } - auto condensed_phase_optional = CheckPhaseExists(object, validation::condensed_phase, existing_phases, errors); - if (!condensed_phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& gas_phase = gas_phase_optional->get(); - CheckSpeciesPresenceInPhase(object, gas_phase, gas_species_node_pairs, errors); - - const auto& condensed_phase = condensed_phase_optional->get(); - CheckSpeciesPresenceInPhase(object, condensed_phase, condensed_species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/surface.cpp b/src/development/reactions/validators/surface.cpp deleted file mode 100644 index 1342133d..00000000 --- a/src/development/reactions/validators/surface.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Surface reaction entry. - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors SurfaceParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { validation::gas_phase_products, - validation::gas_phase_species, - validation::type, - validation::gas_phase, - validation::condensed_phase }; - std::vector optional_keys = { validation::name, validation::reaction_probability }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Gas phase species reactant - validation_errors = ValidateReactantsOrProducts(object[validation::gas_phase_species]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::gas_phase_products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::gas_phase_species]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Validates the number of reactants - // This must be done before collecting errors from the products - if (species_node_pairs.size() > 1) - { - const auto& node = object[validation::gas_phase_species]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: '{}' reaction requires one reactant, but {} were provided.", - error_location, - object[validation::type].as(), - species_node_pairs.size()); - - errors.push_back({ ConfigParseStatus::TooManyReactionComponents, message }); - } - - for (const auto& obj : object[validation::gas_phase_products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto gas_phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!gas_phase_optional) - { - return errors; - } - auto condensed_phase_optional = CheckPhaseExists(object, validation::condensed_phase, existing_phases, errors); - if (!condensed_phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& gas_phase = gas_phase_optional->get(); - CheckSpeciesPresenceInPhase(object, gas_phase, species_node_pairs, errors); - - return errors; - } - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/taylor_series.cpp b/src/development/reactions/validators/taylor_series.cpp deleted file mode 100644 index 76f3c5ec..00000000 --- a/src/development/reactions/validators/taylor_series.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Taylor Series reaction entry - /// Performs schema validation, checks for mutually exclusive parameters (`Ea` vs `C`), - /// ensures all referenced species and phases exist, and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors TaylorSeriesParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::A, validation::B, - validation::C, validation::D, - validation::E, validation::Ea, - validation::name, validation::taylor_coefficients }; - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (object[validation::Ea] && object[validation::C]) - { - const auto& node = object[validation::Ea]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: Mutually exclusive option of 'Ea' and 'C' found in '{}' reaction.", - error_location, - object[validation::type].as()); - - errors.push_back({ ConfigParseStatus::MutuallyExclusiveOption, message }); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/ternary_chemical_activation.cpp b/src/development/reactions/validators/ternary_chemical_activation.cpp deleted file mode 100644 index 2294425e..00000000 --- a/src/development/reactions/validators/ternary_chemical_activation.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Ternary ChemicalActivation reaction entry - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors TernaryChemicalActivationParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::k0_A, validation::k0_B, - validation::k0_C, validation::kinf_A, validation::kinf_B, - validation::kinf_C, validation::Fc, validation::N }; - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/troe.cpp b/src/development/reactions/validators/troe.cpp deleted file mode 100644 index 63cb588f..00000000 --- a/src/development/reactions/validators/troe.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Troe reaction entry - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors TroeParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::k0_A, validation::k0_B, - validation::k0_C, validation::kinf_A, validation::kinf_B, - validation::kinf_C, validation::Fc, validation::N }; - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/tunneling.cpp b/src/development/reactions/validators/tunneling.cpp deleted file mode 100644 index c15f6bb7..00000000 --- a/src/development/reactions/validators/tunneling.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Tunneling reaction entry - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors TunnelingParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::A, validation::B, validation::C }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/user_defined.cpp b/src/development/reactions/validators/user_defined.cpp deleted file mode 100644 index 622c9238..00000000 --- a/src/development/reactions/validators/user_defined.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined User-defined reaction entry - /// Performs schema validation, ensures all referenced species and phases exist, - /// and collects any errors found. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors UserDefinedParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::scaling_factor }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - bool is_valid = true; - - // Reactants - validation_errors = ValidateReactantsOrProducts(object[validation::reactants]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - // Products - validation_errors = ValidateReactantsOrProducts(object[validation::products]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - } - - if (!is_valid) - return errors; - - std::vector> species_node_pairs; - - for (const auto& obj : object[validation::reactants]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - for (const auto& obj : object[validation::products]) - { - types::ReactionComponent component; - component.name = obj[validation::name].as(); - species_node_pairs.emplace_back(component, obj); - } - - // Check for unknown species in reactants and products - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - ReportUnknownSpecies(object, unknown_species, errors, ConfigParseStatus::ReactionRequiresUnknownSpecies); - } - - // Check for phase existence and get phase reference - auto phase_optional = CheckPhaseExists(object, validation::gas_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - // Check if phase-specific species in reaction is found in phase - const auto& phase = phase_optional->get(); - CheckSpeciesPresenceInPhase(object, phase, species_node_pairs, errors); - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/reactions/validators/wet_deposition.cpp b/src/development/reactions/validators/wet_deposition.cpp deleted file mode 100644 index fce3a603..00000000 --- a/src/development/reactions/validators/wet_deposition.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - /// @brief Validates a YAML-defined Wet Deposition reaction entry. - /// Performs schema validation and ensures the referenced phase exists. - /// @param object The YAML node representing the reaction - /// @param existing_species The list of known species used for validation, not used - /// @param existing_phases The list of known phases used for validation - /// @return A list of validation errors, if any - Errors WetDepositionParser::Validate( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases) - { - std::vector required_keys = { validation::condensed_phase, validation::type }; - std::vector optional_keys = { validation::name, validation::scaling_factor }; - - Errors errors; - - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - return errors; - } - - // Check for phase existence - auto phase_optional = CheckPhaseExists(object, validation::condensed_phase, existing_phases, errors); - if (!phase_optional) - { - return errors; - } - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration \ No newline at end of file diff --git a/src/development/type_parsers.cpp b/src/development/type_parsers.cpp deleted file mode 100644 index 8da245df..00000000 --- a/src/development/type_parsers.cpp +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - std::vector ParseSpecies(const YAML::Node& objects) - { - std::vector all_species; - for (const auto& object : objects) - { - types::Species species; - - species.name = object[validation::name].as(); - - if (object[validation::tracer_type]) - species.tracer_type = object[validation::tracer_type].as(); - if (object[validation::absolute_tolerance]) - species.absolute_tolerance = object[validation::absolute_tolerance].as(); - if (object[validation::diffusion_coefficient]) - species.diffusion_coefficient = object[validation::diffusion_coefficient].as(); - if (object[validation::molecular_weight]) - species.molecular_weight = object[validation::molecular_weight].as(); - if (object[validation::henrys_law_constant_298]) - species.henrys_law_constant_298 = object[validation::henrys_law_constant_298].as(); - if (object[validation::henrys_law_constant_exponential_factor]) - species.henrys_law_constant_exponential_factor = - object[validation::henrys_law_constant_exponential_factor].as(); - if (object[validation::n_star]) - species.n_star = object[validation::n_star].as(); - if (object[validation::density]) - species.density = object[validation::density].as(); - if (object[validation::constant_concentration]) - species.constant_concentration = object[validation::constant_concentration].as(); - if (object[validation::constant_mixing_ratio]) - species.constant_mixing_ratio = object[validation::constant_mixing_ratio].as(); - if (object[validation::is_third_body]) - species.is_third_body = object[validation::is_third_body].as(); - - species.unknown_properties = GetComments(object); - - all_species.push_back(species); - } - return all_species; - } - - std::vector ParsePhases(const YAML::Node& objects) - { - std::vector all_phases; - for (const auto& object : objects) - { - types::Phase phase; - phase.name = object[validation::name].as(); - - std::vector species; - - for (const auto& spec : object[validation::species]) - { - types::PhaseSpecies phase_species; - - phase_species.name = spec[validation::name].as(); - if (spec[validation::diffusion_coefficient]) - { - phase_species.diffusion_coefficient = spec[validation::diffusion_coefficient].as(); - } - phase_species.unknown_properties = GetComments(spec); - - species.emplace_back(phase_species); - } - - phase.species = species; - phase.unknown_properties = GetComments(object); - all_phases.emplace_back(phase); - } - - return all_phases; - } - - std::vector ParseReactionComponents(const YAML::Node& object, const std::string& key) - { - std::vector component_list; - for (const auto& elem : AsSequence(object[key])) - { - types::ReactionComponent component; - component.name = elem[validation::name].as(); - component.unknown_properties = GetComments(elem); - - if (elem[validation::coefficient]) - { - component.coefficient = elem[validation::coefficient].as(); - } - - component_list.emplace_back(std::move(component)); - } - - return component_list; - }; - - types::ReactionComponent ParseReactionComponent(const YAML::Node& object, const std::string& key) - { - auto reaction_components = ParseReactionComponents(object, key); - - if (reaction_components.empty()) - { - return types::ReactionComponent(); - } - - return std::move(reaction_components.front()); - }; - - types::Reactions ParseReactions(const YAML::Node& objects) - { - auto& parsers = GetReactionParserMap(); - types::Reactions reactions; - - for (const auto& object : objects) - { - auto it = parsers.find(object[validation::type].as()); - if (it != parsers.end()) - { - it->second->Parse(object, reactions); - } - } - - return reactions; - } - - types::Models ParseModels(const YAML::Node& objects) - { - auto& parsers = GetModelParserMap(); - types::Models models; - - for (const auto& object : objects) - { - auto it = parsers.find(object[validation::type].as()); - if (it != parsers.end()) - { - it->second->Parse(object, models); - } - } - - return models; - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/development/type_validators.cpp b/src/development/type_validators.cpp deleted file mode 100644 index 47104142..00000000 --- a/src/development/type_validators.cpp +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - Errors ValidateSpecies(const YAML::Node& species_list) - { - const std::vector required_keys = { validation::name }; - const std::vector optional_keys = { validation::absolute_tolerance, - validation::diffusion_coefficient, - validation::molecular_weight, - validation::henrys_law_constant_298, - validation::henrys_law_constant_exponential_factor, - validation::n_star, - validation::density, - validation::tracer_type, - validation::constant_concentration, - validation::constant_mixing_ratio, - validation::is_third_body }; - Errors errors; - bool is_valid = true; - - std::vector> species_node_pairs; - - for (const auto& object : species_list) - { - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - is_valid = false; - continue; - } - - // Get the name to check duplicate species - types::Species species; - species.name = object[validation::name].as(); - - species_node_pairs.emplace_back(species, object); - } - - if (!is_valid) - return errors; - - std::vector duplicates = FindDuplicateObjectsByName(species_node_pairs); - if (!duplicates.empty()) - { - for (const auto& duplicate : duplicates) - { - size_t total = duplicate.nodes.size(); - - for (size_t i = 0; i < total; ++i) - { - const auto& object = duplicate.nodes[i]; - ErrorLocation error_location{ object.Mark().line, object.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: Duplicate species name '{}' found ({} of {}).", error_location, duplicate.name, i + 1, total); - - errors.push_back({ ConfigParseStatus::DuplicateSpeciesDetected, message }); - } - } - } - return errors; - } - - Errors ValidatePhases(const YAML::Node& phases_list, const std::vector& existing_species) - { - // Phase - const std::vector required_keys = { validation::name, validation::species }; - const std::vector optional_keys = {}; - // PhaseSpecies - const std::vector species_required_keys = { validation::name }; - const std::vector species_optional_keys = { validation::diffusion_coefficient }; - - Errors errors; - bool is_valid = true; - - std::vector> phase_node_pairs; - - for (const auto& object : AsSequence(phases_list)) - { - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - is_valid = false; - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - } - - for (const auto& spec : object[validation::species]) - { - auto species_validation_errors = ValidateSchema(spec, species_required_keys, species_optional_keys); - if (!species_validation_errors.empty()) - { - is_valid = false; - errors.insert(errors.end(), species_validation_errors.begin(), species_validation_errors.end()); - } - } - - if (!is_valid) - return errors; - - types::Phase phase; - phase.name = object[validation::name].as(); - - std::vector> species_node_pairs; - - for (const auto& spec : object[validation::species]) - { - types::PhaseSpecies phase_species; - phase_species.name = spec[validation::name].as(); - - if (spec[validation::diffusion_coefficient]) - phase_species.diffusion_coefficient = spec[validation::diffusion_coefficient].as(); - - species_node_pairs.emplace_back(phase_species, spec); - } - - // Check for duplicate species within this phase - std::vector duplicates = FindDuplicateObjectsByName(species_node_pairs); - if (!duplicates.empty()) - { - for (const auto& duplicate : duplicates) - { - size_t total = duplicate.nodes.size(); - - for (size_t i = 0; i < total; ++i) - { - const auto& duplicate_obj = duplicate.nodes[i]; - ErrorLocation error_location{ duplicate_obj.Mark().line, duplicate_obj.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: Duplicate species name '{}' found ({} of {}).", error_location, duplicate.name, i + 1, total); - - errors.push_back({ ConfigParseStatus::DuplicateSpeciesInPhaseDetected, message }); - } - } - } - - // Check for unknown species within this phase - std::vector unknown_species = FindUnknownObjectsByName(existing_species, species_node_pairs); - if (!unknown_species.empty()) - { - for (const auto& [name, node] : unknown_species) - { - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = - mc_fmt::format("{} error: Unknown species name '{}' found in '{}' phase.", error_location, name, phase.name); - - errors.push_back({ ConfigParseStatus::PhaseRequiresUnknownSpecies, message }); - } - } - phase_node_pairs.emplace_back(phase, object); - } - - // Check for duplicate phase names - std::vector duplicates = FindDuplicateObjectsByName(phase_node_pairs); - if (!duplicates.empty()) - { - for (const auto& duplicate : duplicates) - { - size_t total = duplicate.nodes.size(); - - for (size_t i = 0; i < total; ++i) - { - const auto& duplicate_object = duplicate.nodes[i]; - ErrorLocation error_location{ duplicate_object.Mark().line, duplicate_object.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: Duplicate phase name '{}' found ({} of {})", error_location, duplicate.name, i + 1, total); - - errors.push_back({ ConfigParseStatus::DuplicatePhasesDetected, message }); - } - } - } - return errors; - } - - Errors ValidateReactantsOrProducts(const YAML::Node& list) - { - const std::vector required_keys = { validation::name }; - const std::vector optional_keys = { validation::coefficient }; - - Errors errors; - - for (const auto& object : list) - { - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - } - } - - return errors; - } - - Errors ValidateParticles(const YAML::Node& list) - { - const std::vector required_keys = { validation::phase, validation::solutes, validation::solvent }; - const std::vector optional_keys = {}; - - Errors errors; - - for (const auto& object : AsSequence(list)) - { - auto validation_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - } - - // Solutes - validation_errors = ValidateReactantsOrProducts(object[validation::solutes]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - } - - // Solvent - validation_errors = ValidateReactantsOrProducts(object[validation::solvent]); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - } - } - - return errors; - } - - Errors ValidateReactions( - const YAML::Node& reactions_list, - const std::vector& existing_species, - const std::vector& existing_phases) - { - Errors errors; - bool is_valid = true; - - auto& parsers = GetReactionParserMap(); - - std::vector> valid_reactions; - - for (const auto& object : reactions_list) - { - if (!object[validation::type]) - { - ErrorLocation error_location{ object.Mark().line, object.Mark().column }; - std::string message = mc_fmt::format("{} error: Missing 'type' object in reaction.", error_location); - errors.push_back({ ConfigParseStatus::RequiredKeyNotFound, message }); - is_valid = false; - continue; - } - - std::string type = object[validation::type].as(); - - auto it = parsers.find(type); - if (it == parsers.end()) - { - const auto& node = object[validation::type]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format("{} error: Unknown reaction type '{}' found.", error_location, type); - - errors.push_back({ ConfigParseStatus::UnknownType, message }); - is_valid = false; - - continue; - } - valid_reactions.emplace_back(object, it->second.get()); - } - - if (!is_valid) - return errors; - - for (const auto& [reaction_node, parser] : valid_reactions) - { - auto validation_errors = parser->Validate(reaction_node, existing_species, existing_phases); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - } - } - - return errors; - } - - Errors ValidateModels(const YAML::Node& models_list, const std::vector& existing_phases) - { - Errors errors; - bool is_valid = true; - - auto& parsers = GetModelParserMap(); - - std::vector> valid_models; - - for (const auto& object : models_list) - { - if (!object[validation::type]) - { - ErrorLocation error_location{ object.Mark().line, object.Mark().column }; - std::string message = mc_fmt::format("{} error: Missing 'type' object in model.", error_location); - errors.push_back({ ConfigParseStatus::RequiredKeyNotFound, message }); - is_valid = false; - continue; - } - - std::string type = object[validation::type].as(); - - auto it = parsers.find(type); - if (it == parsers.end()) - { - const auto& node = object[validation::type]; - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format("{} error: Unknown model type '{}' found.", error_location, type); - - errors.push_back({ ConfigParseStatus::UnknownType, message }); - is_valid = false; - - continue; - } - valid_models.emplace_back(object, it->second.get()); - } - - if (!is_valid) - return errors; - - for (const auto& [model_node, parser] : valid_models) - { - auto validation_errors = parser->Validate(model_node, existing_phases); - if (!validation_errors.empty()) - { - errors.insert(errors.end(), validation_errors.begin(), validation_errors.end()); - } - } - - return errors; - } - - } // namespace development -} // namespace mechanism_configuration \ No newline at end of file diff --git a/src/development/utils.cpp b/src/development/utils.cpp deleted file mode 100644 index 82d077b4..00000000 --- a/src/development/utils.cpp +++ /dev/null @@ -1,191 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace mechanism_configuration -{ - namespace development - { - YAML::Node AsSequence(const YAML::Node& node) - { - if (node.IsSequence()) - return node; - - YAML::Node sequence; - sequence.push_back(node); - - return sequence; - } - - void AppendFilePath(const std::string& config_path, Errors& errors) - { - for (auto& error : errors) - { - error.second = config_path + ":" + error.second; - } - } - - std::unordered_map GetComments(const YAML::Node& object) - { - std::unordered_map unknown_properties; - const std::string comment_start = "__"; - - for (const auto& key : object) - { - std::string key_str = key.first.as(); - - // Check if the key starts with the comment prefix - if (key_str.compare(0, comment_start.size(), comment_start) == 0) - { - // Check if the value is a YAML node - if (key.second.IsScalar()) - { - unknown_properties[key_str] = key.second.as(); - } - else - { - std::stringstream ss; - ss << key.second; - unknown_properties[key_str] = ss.str(); - } - } - } - - // Return the map of extracted comments - return unknown_properties; - } - - std::vector GetSpeciesNames(const std::vector& phase_species) - { - std::vector names; - names.reserve(phase_species.size()); - for (const auto& species : phase_species) - { - names.push_back(species.name); - } - return names; - } - - void ReportUnknownSpecies( - const YAML::Node& object, - const std::vector& unknown_species, - Errors& errors, - const ConfigParseStatus& parser_status) - { - if (unknown_species.empty()) - return; - - for (const auto& [name, node] : unknown_species) - { - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: Unknown species name '{}' found in '{}'.", - error_location, - name, - object[validation::type].as()); - - errors.push_back({ parser_status, message }); - } - } - - std::optional> CheckPhaseExists( - const YAML::Node& object, - const std::string& phase_key, - const std::vector& existing_phases, - Errors& errors, - const ConfigParseStatus& parser_status, - std::string type) - { - if (type.empty()) - { - if (object[validation::type]) - { - type = object[validation::type].as(); - } - else - { - type = "unknown type"; - } - } - - if (!object[phase_key]) - { - ErrorLocation error_location{ object.Mark().line, object.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: Invalid phase key '{}'. This phase was not found in the object of type '{}'.", - error_location, - phase_key, - type); - - errors.push_back({ parser_status, message }); - return std::nullopt; - } - - const auto& phase_node = object[phase_key]; - std::string phase_name = phase_node.as(); - - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&phase_name](const auto& phase) { return phase.name == phase_name; }); - - if (it == existing_phases.end()) - { - ErrorLocation error_location{ phase_node.Mark().line, phase_node.Mark().column }; - - std::string message = - mc_fmt::format("{} error: Unknown phase name '{}' found in '{}'.", error_location, phase_name, type); - - errors.push_back({ parser_status, message }); - return std::nullopt; - } - - return std::cref(*it); - } - - void CheckSpeciesPresenceInPhase( - const YAML::Node& object, - const types::Phase& phase, - const std::vector>& species_node_pairs, - Errors& errors, - const ConfigParseStatus& parser_status) - { - std::unordered_set phase_species_set; - for (const auto& species : phase.species) - { - phase_species_set.insert(species.name); - } - - for (const auto& [component, node] : species_node_pairs) - { - if (phase_species_set.find(component.name) == phase_species_set.end()) - { - ErrorLocation error_location{ node.Mark().line, node.Mark().column }; - - std::string message = mc_fmt::format( - "{} error: {}-phase species '{}' is used in '{}' but is not defined in the '{}' phase.", - error_location, - phase.name, - component.name, - object[validation::type].as(), - phase.name); - - errors.push_back({ parser_status, message }); - } - } - } - - } // namespace development -} // namespace mechanism_configuration diff --git a/src/errors.cpp b/src/errors.cpp new file mode 100644 index 00000000..49875267 --- /dev/null +++ b/src/errors.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include + +namespace mechanism_configuration +{ + std::string ErrorCodeToString(const ErrorCode& status) + { + switch (status) + { + case ErrorCode::Success: return "Success"; + case ErrorCode::None: return "None"; + case ErrorCode::InvalidKey: return "InvalidKey"; + case ErrorCode::UnknownKey: return "UnknownKey"; + case ErrorCode::InvalidFilePath: return "InvalidFilePath"; + case ErrorCode::ObjectTypeNotFound: return "ObjectTypeNotFound"; + case ErrorCode::RequiredKeyNotFound: return "RequiredKeyNotFound"; + case ErrorCode::MutuallyExclusiveOption: return "MutuallyExclusiveOption"; + case ErrorCode::DuplicateSpeciesDetected: return "DuplicateSpeciesDetected"; + case ErrorCode::DuplicatePhasesDetected: return "DuplicatePhasesDetected"; + case ErrorCode::DuplicateSpeciesInPhaseDetected: return "DuplicateSpeciesInPhaseDetected"; + case ErrorCode::PhaseRequiresUnknownSpecies: return "PhaseRequiresUnknownSpecies"; + case ErrorCode::ReactionRequiresUnknownSpecies: return "ReactionRequiresUnknownSpecies"; + case ErrorCode::UnknownSpecies: return "UnknownSpecies"; + case ErrorCode::UnknownPhase: return "UnknownPhase"; + case ErrorCode::RequestedSpeciesNotRegisteredInPhase: return "RequestedSpeciesNotRegisteredInPhase"; + case ErrorCode::TooManyReactionComponents: return "TooManyReactionComponents"; + case ErrorCode::InvalidVersion: return "InvalidVersion"; + case ErrorCode::MissingVersionField: return "MissingVersionField"; + case ErrorCode::InvalidType: return "InvalidType"; + case ErrorCode::UnknownType: return "UnknownType"; + case ErrorCode::FileNotFound: return "FileNotFound"; + case ErrorCode::UnexpectedError: return "UnexpectedError"; + case ErrorCode::EmptyObject: return "EmptyObject"; + default: return "Unknown"; + } + } +} // namespace mechanism_configuration \ No newline at end of file diff --git a/src/parse.cpp b/src/parse.cpp new file mode 100644 index 00000000..1da95e6d --- /dev/null +++ b/src/parse.cpp @@ -0,0 +1,93 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include + +#include "detail/v0/parser.hpp" +#include "detail/v1/parser.hpp" + +#include + +#include +#include +#include + +namespace mechanism_configuration +{ + // The detected version plus the source location of the `version` field, when the document + // had one (a directory or version-less document has no location). + struct DetectedVersion + { + Version version; + std::optional location; + }; + + std::expected GetVersion(const std::filesystem::path& config_path) + { + if (!std::filesystem::exists(config_path)) + { + return std::unexpected( + Errors{ { ErrorCode::FileNotFound, mc_fmt::format("Configuration file '{}' does not exist.", config_path.string()) } }); + } + + if (std::filesystem::exists(config_path) && std::filesystem::is_directory(config_path)) { + return DetectedVersion{ Version(0, 0, 0), std::nullopt }; + } + + YAML::Node object; + try + { + object = YAML::LoadFile(config_path.string()); + } + catch (const YAML::Exception& e) + { + return std::unexpected( + Errors{ { ErrorCode::UnexpectedError, mc_fmt::format("Failed to parse '{}': {}", config_path.string(), e.what()) } }); + } + + // The version field is version-agnostic (it's how we dispatch), so read it literally + // rather than depending on any version's key vocabulary. + if (!object["version"]) + { + // assume it's a v0 config + return DetectedVersion{ Version(0, 0, 0), std::nullopt }; + } + + const YAML::Node version_node = object["version"]; + return DetectedVersion{ Version(version_node.as()), + ErrorLocation{ version_node.Mark().line, version_node.Mark().column } }; + } + + std::expected Parse(const std::filesystem::path& config_path) + { + auto version = GetVersion(config_path); + + if (!version) + { + return std::unexpected(std::move(version.error())); + } + + switch (version->version.major) + { + case 0: + return v0::Parser{}.Parse(config_path); + case 1: + return v1::Parser{}.Parse(config_path); + default: + { + // We only reach here after reading the version out of config_path, so it names a real + // file and the version field has a location; point the error at it (path:line:col). + const std::string body = version->location + ? mc_fmt::format("{} error: Unsupported version number '{}'.", + *version->location, version->version.to_string()) + : mc_fmt::format("error: Unsupported version number '{}'.", version->version.to_string()); + return std::unexpected(Errors{ { ErrorCode::InvalidVersion, config_path.string() + ":" + body } }); + } + } + } + +} // namespace mechanism_configuration diff --git a/src/parse_status.cpp b/src/parse_status.cpp deleted file mode 100644 index 987dc451..00000000 --- a/src/parse_status.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include - -namespace mechanism_configuration -{ - std::string configParseStatusToString(const ConfigParseStatus& status) - { - switch (status) - { - case ConfigParseStatus::Success: return "Success"; - case ConfigParseStatus::None: return "None"; - case ConfigParseStatus::InvalidKey: return "InvalidKey"; - case ConfigParseStatus::UnknownKey: return "UnknownKey"; - case ConfigParseStatus::InvalidFilePath: return "InvalidFilePath"; - case ConfigParseStatus::ObjectTypeNotFound: return "ObjectTypeNotFound"; - case ConfigParseStatus::RequiredKeyNotFound: return "RequiredKeyNotFound"; - case ConfigParseStatus::MutuallyExclusiveOption: return "MutuallyExclusiveOption"; - case ConfigParseStatus::DuplicateSpeciesDetected: return "DuplicateSpeciesDetected"; - case ConfigParseStatus::DuplicatePhasesDetected: return "DuplicatePhasesDetected"; - case ConfigParseStatus::DuplicateSpeciesInPhaseDetected: return "DuplicateSpeciesInPhaseDetected"; - case ConfigParseStatus::PhaseRequiresUnknownSpecies: return "PhaseRequiresUnknownSpecies"; - case ConfigParseStatus::ReactionRequiresUnknownSpecies: return "ReactionRequiresUnknownSpecies"; - case ConfigParseStatus::UnknownSpecies: return "UnknownSpecies"; - case ConfigParseStatus::UnknownPhase: return "UnknownPhase"; - case ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase: return "RequestedSpeciesNotRegisteredInPhase"; - case ConfigParseStatus::TooManyReactionComponents: return "TooManyReactionComponents"; - case ConfigParseStatus::InvalidIonPair: return "InvalidIonPair"; - case ConfigParseStatus::InvalidVersion: return "InvalidVersion"; - case ConfigParseStatus::MissingVersionField: return "MissingVersionField"; - case ConfigParseStatus::InvalidParameterNumber: return "InvalidParameterNumber"; - case ConfigParseStatus::InvalidType: return "InvalidType"; - case ConfigParseStatus::UnknownType: return "UnknownType"; - case ConfigParseStatus::FileNotFound: return "FileNotFound"; - case ConfigParseStatus::UnexpectedError: return "UnexpectedError"; - case ConfigParseStatus::EmptyObject: return "EmptyObject"; - default: return "Unknown"; - } - } -} // namespace mechanism_configuration \ No newline at end of file diff --git a/src/parser.cpp b/src/parser.cpp deleted file mode 100644 index e20f1bac..00000000 --- a/src/parser.cpp +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -namespace mechanism_configuration -{ - - VersionInfo UniversalParser::GetVersion(const std::filesystem::path& config_path) - { - VersionInfo info; - - if (!std::filesystem::exists(config_path)) - { - info.errors.push_back({ ConfigParseStatus::FileNotFound, - mc_fmt::format("Configuration file '{}' does not exist.", config_path.string()) }); - return info; - } - - YAML::Node object; - try - { - object = YAML::LoadFile(config_path.string()); - } - catch (const YAML::Exception& e) - { - info.errors.push_back({ ConfigParseStatus::UnexpectedError, - mc_fmt::format("Failed to parse '{}': {}", config_path.string(), e.what()) }); - return info; - } - - if (!object[development::validation::version]) - { - info.errors.push_back({ ConfigParseStatus::MissingVersionField, - mc_fmt::format("The version field was not found in '{}'.", config_path.string()) }); - return info; - } - - Version version = Version(object[development::validation::version].as()); - info.version = version.major; - - return info; - } - - ParserResult UniversalParser::Parse(const std::filesystem::path& config_path) - { - ParserResult result; - - // Check if the path is a directory - // If it's a directory, use the v0 parser without version checking - if (std::filesystem::exists(config_path) && std::filesystem::is_directory(config_path)) - { - v0::Parser v0_parser; - auto parser_result = v0_parser.Parse(config_path); - if (parser_result.errors.empty()) - { - result.mechanism = std::move(parser_result.mechanism); - } - else - { - result.errors.insert(result.errors.end(), parser_result.errors.begin(), parser_result.errors.end()); - } - return result; - } - - // For files, check the version - VersionInfo version_info = GetVersion(config_path); - if (!version_info.errors.empty()) - { - // If the version field is missing, the parser defaults to version 0. - // This approach is temporary and fragile, but is required to support - // the version 0 configurations. It can be removed once version 0 is fully - // deprecated or no longer supported. - for (auto& [status, message] : version_info.errors) - { - if (status == ConfigParseStatus::MissingVersionField) - { - v0::Parser v0_parser; - auto parser_result = v0_parser.Parse(config_path); - if (parser_result.errors.empty()) - { - result.mechanism = std::move(parser_result.mechanism); - } - else - { - result.errors.insert(result.errors.end(), parser_result.errors.begin(), parser_result.errors.end()); - } - return result; - } - } - result.errors.insert(result.errors.end(), version_info.errors.begin(), version_info.errors.end()); - - return result; - } - - constexpr unsigned int DEV_VERSION = 2; - constexpr unsigned int V1_VERSION = 1; - - if (version_info.version == DEV_VERSION) - { - development::Parser parser; - YAML::Node object = parser.FileToYaml(config_path); - auto validation_errors = parser.Validate(object); - if (validation_errors.empty()) - { - result.mechanism = std::make_unique(parser.Parse(object)); - } - else - { - result.errors.insert(result.errors.end(), validation_errors.begin(), validation_errors.end()); - } - return result; - } - else if (version_info.version == V1_VERSION) - { - v1::Parser v1_parser; - auto parser_result = v1_parser.Parse(config_path); - if (parser_result.errors.empty()) - { - result.mechanism = std::move(parser_result.mechanism); - } - else - { - result.errors.insert(result.errors.end(), parser_result.errors.begin(), parser_result.errors.end()); - } - return result; - } - else - { - std::string message = mc_fmt::format( - "error: The supported versions are '{}', '{}' but the invalid version number '{}' was found: '{}'.", - DEV_VERSION, - V1_VERSION, - version_info.version, - config_path.string()); - result.errors.push_back({ ConfigParseStatus::InvalidVersion, message }); - } - - return result; - } - -} // namespace mechanism_configuration \ No newline at end of file diff --git a/src/v0/arrhenius_parser.cpp b/src/v0/arrhenius_parser.cpp index 181dd09e..1cbc3528 100644 --- a/src/v0/arrhenius_parser.cpp +++ b/src/v0/arrhenius_parser.cpp @@ -1,84 +1,85 @@ -#include -#include -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 -namespace mechanism_configuration +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" + +namespace mechanism_configuration::v0 { - namespace v0 + Errors ArrheniusParser(Mechanism& mechanism, const YAML::Node& object) { - Errors ArrheniusParser(std::unique_ptr& mechanism, const YAML::Node& object) - { - Errors errors; + Errors errors; - std::vector required = { validation::TYPE, validation::REACTANTS, validation::PRODUCTS }; - std::vector optional = { validation::A, validation::B, validation::C, validation::D, - validation::E, validation::Ea, validation::MUSICA_NAME }; + std::vector required = { keys::TYPE, keys::REACTANTS, keys::PRODUCTS }; + std::vector optional = { keys::A, keys::B, keys::C, keys::D, + keys::E, keys::Ea, keys::MUSICA_NAME }; - auto validate = ValidateSchema(object, required, optional); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::vector reactants; - std::vector products; + auto validate = CheckSchema(object, required, optional); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) + { + std::vector reactants; + std::vector products; - auto parse_error = ParseReactants(object[validation::REACTANTS], reactants); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + auto parse_error = ParseReactants(object[keys::REACTANTS], reactants); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - parse_error = ParseProducts(object[validation::PRODUCTS], products); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + parse_error = ParseProducts(object[keys::PRODUCTS], products); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - types::Arrhenius parameters; - if (object[validation::A]) - { - parameters.A = object[validation::A].as(); - } - int total_moles = 0; - for (const auto& reactant : reactants) - { - total_moles += reactant.coefficient; - } - parameters.A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles - 1); - if (object[validation::B]) - { - parameters.B = object[validation::B].as(); - } - if (object[validation::C]) - { - parameters.C = object[validation::C].as(); - } - if (object[validation::D]) - { - parameters.D = object[validation::D].as(); - } - if (object[validation::E]) + types::Arrhenius parameters; + if (object[keys::A]) + { + parameters.A = object[keys::A].as(); + } + int total_moles = 0; + for (const auto& reactant : reactants) + { + total_moles += reactant.coefficient; + } + parameters.A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles - 1); + if (object[keys::B]) + { + parameters.B = object[keys::B].as(); + } + if (object[keys::C]) + { + parameters.C = object[keys::C].as(); + } + if (object[keys::D]) + { + parameters.D = object[keys::D].as(); + } + if (object[keys::E]) + { + parameters.E = object[keys::E].as(); + } + if (object[keys::Ea]) + { + if (parameters.C != 0) { - parameters.E = object[validation::E].as(); + std::string line = std::to_string(object[keys::Ea].Mark().line + 1); + std::string column = std::to_string(object[keys::Ea].Mark().column + 1); + errors.push_back( + { ErrorCode::MutuallyExclusiveOption, line + ":" + column + ": Cannot specify both 'C' and 'Ea'" }); } - if (object[validation::Ea]) + else { - if (parameters.C != 0) - { - std::string line = std::to_string(object[validation::Ea].Mark().line + 1); - std::string column = std::to_string(object[validation::Ea].Mark().column + 1); - errors.push_back( - { ConfigParseStatus::MutuallyExclusiveOption, line + ":" + column + ": Cannot specify both 'C' and 'Ea'" }); - } - else - { - // Calculate 'C' using 'Ea' - parameters.C = -1 * object[validation::Ea].as() / constants::boltzmann; - } + // Calculate 'C' using 'Ea' + parameters.C = -1 * object[keys::Ea].as() / constants::boltzmann; } - - parameters.reactants = reactants; - parameters.products = products; - - mechanism->reactions.arrhenius.push_back(parameters); } - return errors; + parameters.reactants = reactants; + parameters.products = products; + + mechanism.reactions.arrhenius.push_back(parameters); } - } // namespace v0 -} // namespace mechanism_configuration + + return errors; + } +} // namespace mechanism_configuration::v0 diff --git a/src/v0/branched_parser.cpp b/src/v0/branched_parser.cpp index 1a21061f..534dbca4 100644 --- a/src/v0/branched_parser.cpp +++ b/src/v0/branched_parser.cpp @@ -1,65 +1,66 @@ -#include -#include -#include -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 -namespace mechanism_configuration +#include "detail/constants.hpp" +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" + +namespace mechanism_configuration::v0 { - namespace v0 + Errors BranchedParser(Mechanism& mechanism, const YAML::Node& object) { - Errors BranchedParser(std::unique_ptr& mechanism, const YAML::Node& object) - { - Errors errors; - - std::vector required = { validation::TYPE, - validation::REACTANTS, - validation::ALKOXY_PRODUCTS, - validation::NITRATE_PRODUCTS, - validation::X, - validation::Y, - validation::A0, - validation::n }; - - auto validate = ValidateSchema(object, required, {}); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::vector reactants; - std::vector alkoxy_products; - std::vector nitrate_products; + Errors errors; - auto parse_error = ParseReactants(object[validation::REACTANTS], reactants); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + std::vector required = { keys::TYPE, + keys::REACTANTS, + keys::ALKOXY_PRODUCTS, + keys::NITRATE_PRODUCTS, + keys::X, + keys::Y, + keys::A0, + keys::n }; - parse_error = ParseProducts(object[validation::ALKOXY_PRODUCTS], alkoxy_products); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + auto validate = CheckSchema(object, required, {}); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) + { + std::vector reactants; + std::vector alkoxy_products; + std::vector nitrate_products; - parse_error = ParseProducts(object[validation::NITRATE_PRODUCTS], nitrate_products); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + auto parse_error = ParseReactants(object[keys::REACTANTS], reactants); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - types::Branched parameters; - parameters.X = object[validation::X].as(); - // Account for the conversion of reactant concentrations to molecules cm-3 - int total_moles = 0; - for (const auto& reactant : reactants) - { - total_moles += reactant.coefficient; - } - parameters.X *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles - 1); - parameters.Y = object[validation::Y].as(); - parameters.a0 = object[validation::A0].as(); - parameters.n = object[validation::n].as(); + parse_error = ParseProducts(object[keys::ALKOXY_PRODUCTS], alkoxy_products); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - parameters.reactants = reactants; - parameters.alkoxy_products = alkoxy_products; - parameters.nitrate_products = nitrate_products; + parse_error = ParseProducts(object[keys::NITRATE_PRODUCTS], nitrate_products); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - mechanism->reactions.branched.push_back(parameters); + types::Branched parameters; + parameters.X = object[keys::X].as(); + // Account for the conversion of reactant concentrations to molecules cm-3 + int total_moles = 0; + for (const auto& reactant : reactants) + { + total_moles += reactant.coefficient; } + parameters.X *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles - 1); + parameters.Y = object[keys::Y].as(); + parameters.a0 = object[keys::A0].as(); + parameters.n = object[keys::n].as(); - return errors; + parameters.reactants = reactants; + parameters.alkoxy_products = alkoxy_products; + parameters.nitrate_products = nitrate_products; + + mechanism.reactions.branched.push_back(parameters); } - } // namespace v0 -} // namespace mechanism_configuration + + return errors; + } +} // namespace mechanism_configuration::v0 diff --git a/src/v0/emission_parser.cpp b/src/v0/emission_parser.cpp index 9cd344a8..316aa304 100644 --- a/src/v0/emission_parser.cpp +++ b/src/v0/emission_parser.cpp @@ -1,39 +1,40 @@ -#include -#include -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 -namespace mechanism_configuration +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" + +namespace mechanism_configuration::v0 { - namespace v0 + Errors EmissionParser(Mechanism& mechanism, const YAML::Node& object) { - Errors EmissionParser(std::unique_ptr& mechanism, const YAML::Node& object) - { - Errors errors; - - std::vector required = { validation::TYPE, validation::SPECIES, validation::MUSICA_NAME }; - std::vector optional = { validation::SCALING_FACTOR, validation::PRODUCTS }; + Errors errors; - auto validate = ValidateSchema(object, required, optional); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::string species = object[validation::SPECIES].as(); - YAML::Node products_object{}; - std::vector reactants; - std::vector products; - products.push_back({ .species_name = species, .coefficient = 1.0 }); - double scaling_factor = object[validation::SCALING_FACTOR] ? object[validation::SCALING_FACTOR].as() : 1.0; + std::vector required = { keys::TYPE, keys::SPECIES, keys::MUSICA_NAME }; + std::vector optional = { keys::SCALING_FACTOR, keys::PRODUCTS }; - std::string name = "EMIS." + object[validation::MUSICA_NAME].as(); - types::UserDefined user_defined = { - .scaling_factor = scaling_factor, .reactants = reactants, .products = products, .name = name - }; - mechanism->reactions.user_defined.push_back(user_defined); - } + auto validate = CheckSchema(object, required, optional); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) + { + std::string species = object[keys::SPECIES].as(); + YAML::Node products_object{}; + std::vector reactants; + std::vector products; + products.push_back({ .name = species, .coefficient = 1.0 }); + double scaling_factor = object[keys::SCALING_FACTOR] ? object[keys::SCALING_FACTOR].as() : 1.0; - return errors; + std::string name = "EMIS." + object[keys::MUSICA_NAME].as(); + types::UserDefined user_defined = { + .scaling_factor = scaling_factor, .reactants = reactants, .products = products, .name = name + }; + mechanism.reactions.user_defined.push_back(user_defined); } - } // namespace v0 -} // namespace mechanism_configuration + + return errors; + } +} // namespace mechanism_configuration::v0 diff --git a/src/v0/first_order_loss_parser.cpp b/src/v0/first_order_loss_parser.cpp index 1bb55831..00afb0cd 100644 --- a/src/v0/first_order_loss_parser.cpp +++ b/src/v0/first_order_loss_parser.cpp @@ -1,40 +1,41 @@ -#include -#include -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 -namespace mechanism_configuration +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" + +namespace mechanism_configuration::v0 { - namespace v0 + Errors FirstOrderLossParser(Mechanism& mechanism, const YAML::Node& object) { - Errors FirstOrderLossParser(std::unique_ptr& mechanism, const YAML::Node& object) - { - Errors errors; - - std::vector required = { validation::TYPE, validation::SPECIES, validation::MUSICA_NAME }; - std::vector optional = { validation::SCALING_FACTOR }; + Errors errors; - auto validate = ValidateSchema(object, required, optional); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::string species = object[validation::SPECIES].as(); - YAML::Node products_object{}; - std::vector reactants; - std::vector products; + std::vector required = { keys::TYPE, keys::SPECIES, keys::MUSICA_NAME }; + std::vector optional = { keys::SCALING_FACTOR }; - reactants.push_back({ .species_name = species, .coefficient = 1.0 }); - double scaling_factor = object[validation::SCALING_FACTOR] ? object[validation::SCALING_FACTOR].as() : 1.0; + auto validate = CheckSchema(object, required, optional); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) + { + std::string species = object[keys::SPECIES].as(); + YAML::Node products_object{}; + std::vector reactants; + std::vector products; - std::string name = "LOSS." + object[validation::MUSICA_NAME].as(); - types::UserDefined user_defined = { - .scaling_factor = scaling_factor, .reactants = reactants, .products = products, .name = name - }; - mechanism->reactions.user_defined.push_back(user_defined); - } + reactants.push_back({ .name = species, .coefficient = 1.0 }); + double scaling_factor = object[keys::SCALING_FACTOR] ? object[keys::SCALING_FACTOR].as() : 1.0; - return errors; + std::string name = "LOSS." + object[keys::MUSICA_NAME].as(); + types::UserDefined user_defined = { + .scaling_factor = scaling_factor, .reactants = reactants, .products = products, .name = name + }; + mechanism.reactions.user_defined.push_back(user_defined); } - } // namespace v0 -} // namespace mechanism_configuration + + return errors; + } +} // namespace mechanism_configuration::v0 diff --git a/src/v0/parser.cpp b/src/v0/parser.cpp index 33e77c9c..659da655 100644 --- a/src/v0/parser.cpp +++ b/src/v0/parser.cpp @@ -1,141 +1,135 @@ -// Copyright (C) 2023-2024 National Center for Atmospheric Research, University of Illinois at Urbana-Champaign -// +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign // SPDX-License-Identifier: Apache-2.0 -#include -#include -#include -#include -#include -#include +#include "detail/constants.hpp" +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" #include #include -namespace mechanism_configuration +namespace mechanism_configuration::v0 { - namespace v0 - { - - using ParserMap = std::map&, const YAML::Node&)>>; + using ParserMap = std::map>; - Errors run_parsers(const ParserMap& parsers, std::unique_ptr& mechanism, const YAML::Node& object) + Errors run_parsers(const ParserMap& parsers, Mechanism& mechanism, const YAML::Node& object) + { + Errors errors; + for (const auto& element : object) { - Errors errors; - for (const auto& element : object) + std::string type = element[keys::TYPE].as(); + auto it = parsers.find(type); + if (it != parsers.end()) { - std::string type = element[validation::TYPE].as(); - auto it = parsers.find(type); - if (it != parsers.end()) - { - auto parse_errors = it->second(mechanism, element); - errors.insert(errors.end(), parse_errors.begin(), parse_errors.end()); - } - else - { - const std::string& msg = "Unknown type: " + type; - throw std::runtime_error(msg); - } + auto parse_errors = it->second(mechanism, element); + errors.insert(errors.end(), parse_errors.begin(), parse_errors.end()); + } + else + { + const std::string& msg = "Unknown type: " + type; + throw std::runtime_error(msg); } - return errors; } + return errors; + } + + Errors ParseMechanism(const ParserMap& parsers, Mechanism& mechanism, const YAML::Node& object) + { + std::vector required = { keys::NAME, keys::REACTIONS, keys::TYPE }; - Errors ParseMechanism(const ParserMap& parsers, std::unique_ptr& mechanism, const YAML::Node& object) + Errors errors; + auto validate = CheckSchema(object, required, {}); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) { - std::vector required = { validation::NAME, validation::REACTIONS, validation::TYPE }; + mechanism.name = object[keys::NAME].as(); + auto parse_errors = run_parsers(parsers, mechanism, object[keys::REACTIONS]); + errors.insert(errors.end(), parse_errors.begin(), parse_errors.end()); + } - Errors errors; - auto validate = ValidateSchema(object, required, {}); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - mechanism->name = object[validation::NAME].as(); - auto parse_errors = run_parsers(parsers, mechanism, object[validation::REACTIONS]); - errors.insert(errors.end(), parse_errors.begin(), parse_errors.end()); - } + return errors; + } + Errors Parser::GetCampFiles(const std::filesystem::path& config_path, std::vector& camp_files) + { + Errors errors; + // Look for CAMP config path + if (!std::filesystem::exists(config_path)) + { + errors.push_back({ ErrorCode::FileNotFound, "File not found" }); return errors; } - Errors Parser::GetCampFiles(const std::filesystem::path& config_path, std::vector& camp_files) - { - Errors errors; - // Look for CAMP config path - if (!std::filesystem::exists(config_path)) - { - errors.push_back({ ConfigParseStatus::FileNotFound, "File not found" }); - return errors; - } - - std::filesystem::path config_dir; - std::filesystem::path config_file; + std::filesystem::path config_dir; + std::filesystem::path config_file; - if (std::filesystem::is_directory(config_path)) + if (std::filesystem::is_directory(config_path)) + { + // If config path is a directory, use default config file name + config_dir = config_path; + if (std::filesystem::exists(config_dir / DEFAULT_CONFIG_FILE_YAML)) { - // If config path is a directory, use default config file name - config_dir = config_path; - if (std::filesystem::exists(config_dir / DEFAULT_CONFIG_FILE_YAML)) - { - config_file = config_dir / DEFAULT_CONFIG_FILE_YAML; - } - else - { - config_file = config_dir / DEFAULT_CONFIG_FILE_JSON; - } + config_file = config_dir / DEFAULT_CONFIG_FILE_YAML; } else { - // Extract configuration dir from configuration file path - config_dir = config_path.parent_path(); - config_file = config_path; + config_file = config_dir / DEFAULT_CONFIG_FILE_JSON; } + } + else + { + // Extract configuration dir from configuration file path + config_dir = config_path.parent_path(); + config_file = config_path; + } + + // Load the CAMP file list YAML + YAML::Node camp_data = YAML::LoadFile(config_file.string()); + if (!camp_data[CAMP_FILES]) + { + std::string msg = "Required key not found: " + CAMP_FILES; + errors.push_back({ ErrorCode::RequiredKeyNotFound, msg }); + return errors; + } - // Load the CAMP file list YAML - YAML::Node camp_data = YAML::LoadFile(config_file.string()); - if (!camp_data[CAMP_FILES]) + // Build a list of individual CAMP config files + for (const auto& element : camp_data[CAMP_FILES]) + { + std::filesystem::path camp_file = config_dir / element.as(); + if (!std::filesystem::exists(camp_file)) { - std::string msg = "Required key not found: " + CAMP_FILES; - errors.push_back({ ConfigParseStatus::RequiredKeyNotFound, msg }); - return errors; + errors.push_back({ ErrorCode::FileNotFound, "File not found: " + camp_file.string() }); } - - // Build a list of individual CAMP config files - for (const auto& element : camp_data[CAMP_FILES]) + else { - std::filesystem::path camp_file = config_dir / element.as(); - if (!std::filesystem::exists(camp_file)) - { - errors.push_back({ ConfigParseStatus::FileNotFound, "File not found: " + camp_file.string() }); - } - else - { - camp_files.push_back(camp_file); - } + camp_files.push_back(camp_file); } - - return errors; } - ParserResult Parser::Parse(const std::filesystem::path& config_path) - { - ParserResult result; - result.mechanism = std::make_unique(); + return errors; + } - std::vector camp_files; - auto errors = GetCampFiles(config_path, camp_files); + std::expected Parser::Parse(const std::filesystem::path& config_path) + { + Errors errors; + auto mechanism = Mechanism(); - if (!errors.empty()) - { - result.errors = errors; - return result; - } + std::vector camp_files; + auto file_errors = GetCampFiles(config_path, camp_files); + errors.insert(errors.end(), file_errors.begin(), file_errors.end()); + // Only attempt to parse the mechanism if we were able to gather the CAMP files. + if (errors.empty()) + { ParserMap parsers; - std::function&, const YAML::Node&)> ParseMechanismArray = - [&](std::unique_ptr& mechanism, const YAML::Node& object) - { return ParseMechanism(parsers, mechanism, object); }; + std::function ParseMechanismArray = + [&](Mechanism& mechanism, const YAML::Node& object) { return ParseMechanism(parsers, mechanism, object); }; parsers["CHEM_SPEC"] = ParseChemicalSpecies; parsers["RELATIVE_TOLERANCE"] = ParseRelativeTolerance; @@ -155,28 +149,48 @@ namespace mechanism_configuration for (const auto& camp_file : camp_files) { - YAML::Node config_subset = YAML::LoadFile(camp_file.string()); - - auto parse_errors = run_parsers(parsers, result.mechanism, config_subset[CAMP_DATA]); - // prepend the file name to the error messages - for (auto& error : parse_errors) + // Parse each file independently so one malformed file does not abort the rest. + try { - error.second = camp_file.string() + ":" + error.second; + YAML::Node config_subset = YAML::LoadFile(camp_file.string()); + + auto parse_errors = run_parsers(parsers, mechanism, config_subset[CAMP_DATA]); + // prepend the file name to the error messages + for (auto& error : parse_errors) + { + error.second = camp_file.string() + ":" + error.second; + } + errors.insert(errors.end(), parse_errors.begin(), parse_errors.end()); + } + catch (const std::exception& e) + { + errors.push_back({ ErrorCode::UnexpectedError, camp_file.string() + ":" + e.what() }); } - result.errors.insert(result.errors.end(), parse_errors.begin(), parse_errors.end()); } // all species in version 0 are in the gas phase types::Phase gas_phase; gas_phase.name = "GAS"; - for (auto& species : result.mechanism->species) + for (auto& species : mechanism.species) { - gas_phase.species.push_back(species.name); + types::PhaseSpecies phase_species; + phase_species.name = species.name; + gas_phase.species.push_back(phase_species); } + mechanism.phases.push_back(gas_phase); - result.mechanism->version = Version(0, 0, 0); + mechanism.version = Version(0, 0, 0); + } - return result; + std::expected result; + if (!errors.empty()) + { + result = std::unexpected(std::move(errors)); + } + else + { + result = mechanism; } - } // namespace v0 -} // namespace mechanism_configuration \ No newline at end of file + return result; + } +} // namespace mechanism_configuration::v0 \ No newline at end of file diff --git a/src/v0/photolysis_parser.cpp b/src/v0/photolysis_parser.cpp index ec8c0c44..25fa81b5 100644 --- a/src/v0/photolysis_parser.cpp +++ b/src/v0/photolysis_parser.cpp @@ -1,45 +1,46 @@ -#include -#include -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 -namespace mechanism_configuration +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" + +namespace mechanism_configuration::v0 { - namespace v0 + Errors PhotolysisParser(Mechanism& mechanism, const YAML::Node& object) { - Errors PhotolysisParser(std::unique_ptr& mechanism, const YAML::Node& object) + Errors errors; + + std::vector required = { + keys::TYPE, keys::REACTANTS, keys::PRODUCTS, keys::MUSICA_NAME + }; + std::vector optional = { keys::SCALING_FACTOR }; + + auto validate = CheckSchema(object, required, optional); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) { - Errors errors; + std::vector reactants; + std::vector products; + + auto parse_error = ParseReactants(object[keys::REACTANTS], reactants); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - std::vector required = { - validation::TYPE, validation::REACTANTS, validation::PRODUCTS, validation::MUSICA_NAME + parse_error = ParseProducts(object[keys::PRODUCTS], products); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + + double scaling_factor = object[keys::SCALING_FACTOR] ? object[keys::SCALING_FACTOR].as() : 1.0; + + std::string name = "PHOTO." + object[keys::MUSICA_NAME].as(); + types::UserDefined user_defined = { + .scaling_factor = scaling_factor, .reactants = reactants, .products = products, .name = name }; - std::vector optional = { validation::SCALING_FACTOR }; - - auto validate = ValidateSchema(object, required, optional); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::vector reactants; - std::vector products; - - auto parse_error = ParseReactants(object[validation::REACTANTS], reactants); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - - parse_error = ParseProducts(object[validation::PRODUCTS], products); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - - double scaling_factor = object[validation::SCALING_FACTOR] ? object[validation::SCALING_FACTOR].as() : 1.0; - - std::string name = "PHOTO." + object[validation::MUSICA_NAME].as(); - types::UserDefined user_defined = { - .scaling_factor = scaling_factor, .reactants = reactants, .products = products, .name = name - }; - mechanism->reactions.user_defined.push_back(user_defined); - } - - return errors; - } // namespace mechanism_configuration - } // namespace v0 -} // namespace mechanism_configuration + mechanism.reactions.user_defined.push_back(user_defined); + } + + return errors; + } +} // namespace mechanism_configuration::v0 diff --git a/src/v0/species_parser.cpp b/src/v0/species_parser.cpp index fcd37440..64069d6a 100644 --- a/src/v0/species_parser.cpp +++ b/src/v0/species_parser.cpp @@ -1,116 +1,117 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + #include -#include -#include -#include +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" -namespace mechanism_configuration +namespace mechanism_configuration::v0 { - namespace v0 + Errors ParseChemicalSpecies(Mechanism& mechanism, const YAML::Node& object) { - Errors ParseChemicalSpecies(std::unique_ptr& mechanism, const YAML::Node& object) + Errors errors; + std::vector required = { keys::NAME, keys::TYPE }; + std::vector optional = { + keys::TRACER_TYPE, keys::ABS_TOLERANCE, keys::DIFFUSION_COEFF, keys::MOL_WEIGHT + }; + + auto validate = CheckSchema(object, required, optional); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) { - Errors errors; - std::vector required = { validation::NAME, validation::TYPE }; - std::vector optional = { - validation::TRACER_TYPE, validation::ABS_TOLERANCE, validation::DIFFUSION_COEFF, validation::MOL_WEIGHT - }; + std::string name = object[keys::NAME].as(); + types::Species species; + species.name = name; - auto validate = ValidateSchema(object, required, optional); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::string name = object[validation::NAME].as(); - types::Species species; - species.name = name; + if (object[keys::MOL_WEIGHT]) + species.molecular_weight = object[keys::MOL_WEIGHT].as(); + if (object[keys::DIFFUSION_COEFF]) + species.diffusion_coefficient = object[keys::DIFFUSION_COEFF].as(); + if (object[keys::ABS_TOLERANCE]) + species.absolute_tolerance = object[keys::ABS_TOLERANCE].as(); + if (object[keys::TRACER_TYPE]) + species.tracer_type = object[keys::TRACER_TYPE].as(); - if (object[validation::MOL_WEIGHT]) - species.molecular_weight = object[validation::MOL_WEIGHT].as(); - if (object[validation::DIFFUSION_COEFF]) - species.diffusion_coefficient = object[validation::DIFFUSION_COEFF].as(); - if (object[validation::ABS_TOLERANCE]) - species.absolute_tolerance = object[validation::ABS_TOLERANCE].as(); - if (object[validation::TRACER_TYPE]) - species.tracer_type = object[validation::TRACER_TYPE].as(); + // Load remaining keys as unknown properties + for (auto it = object.begin(); it != object.end(); ++it) + { + auto key = it->first.as(); + auto value = it->second; - // Load remaining keys as unknown properties - for (auto it = object.begin(); it != object.end(); ++it) + if (std::find(required.begin(), required.end(), key) == required.end() && + std::find(optional.begin(), optional.end(), key) == optional.end()) { - auto key = it->first.as(); - auto value = it->second; - - if (std::find(required.begin(), required.end(), key) == required.end() && - std::find(optional.begin(), optional.end(), key) == optional.end()) - { - std::string stringValue = value.as(); - species.unknown_properties[key] = stringValue; - } + std::string stringValue = value.as(); + species.unknown_properties[key] = stringValue; } - mechanism->species.push_back(species); } + mechanism.species.push_back(species); + } + + return errors; + } - return errors; + Errors ParseRelativeTolerance(Mechanism& mechanism, const YAML::Node& object) + { + Errors errors; + std::vector required = { keys::VALUE, keys::TYPE }; + + auto validate = CheckSchema(object, required, {}); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) + { + mechanism.relative_tolerance = object[keys::VALUE].as(); } - Errors ParseRelativeTolerance(std::unique_ptr& mechanism, const YAML::Node& object) + return errors; + } + + Errors ParseReactants(const YAML::Node& object, std::vector& reactants) + { + Errors errors; + for (auto it = object.begin(); it != object.end(); ++it) { - Errors errors; - std::vector required = { validation::VALUE, validation::TYPE }; + auto key = it->first.as(); + auto value = it->second; - auto validate = ValidateSchema(object, required, {}); + auto validate = CheckSchema(value, {}, { keys::QTY }); errors.insert(errors.end(), validate.begin(), validate.end()); if (validate.empty()) { - mechanism->relative_tolerance = object[validation::VALUE].as(); + double qty = 1; + if (value[keys::QTY]) + qty = value[keys::QTY].as(); + types::ReactionComponent reactant = { .name = key, .coefficient = qty }; + reactants.push_back(reactant); } - - return errors; } - Errors ParseReactants(const YAML::Node& object, std::vector& reactants) - { - Errors errors; - for (auto it = object.begin(); it != object.end(); ++it) - { - auto key = it->first.as(); - auto value = it->second; - - auto validate = ValidateSchema(value, {}, { validation::QTY }); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - double qty = 1; - if (value[validation::QTY]) - qty = value[validation::QTY].as(); - types::ReactionComponent reactant = { .species_name = key, .coefficient = qty }; - reactants.push_back(reactant); - } - } - - return errors; - } + return errors; + } - Errors ParseProducts(const YAML::Node& object, std::vector& products) + Errors ParseProducts(const YAML::Node& object, std::vector& products) + { + Errors errors; + for (auto it = object.begin(); it != object.end(); ++it) { - Errors errors; - for (auto it = object.begin(); it != object.end(); ++it) - { - auto key = it->first.as(); - auto value = it->second; + auto key = it->first.as(); + auto value = it->second; - auto validate = ValidateSchema(value, {}, { validation::YIELD }); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) + auto validate = CheckSchema(value, {}, { keys::YIELD }); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) + { + types::ReactionComponent product = { .name = key, .coefficient = 1 }; + if (value[keys::YIELD]) { - types::ReactionComponent product = { .species_name = key, .coefficient = 1 }; - if (value[validation::YIELD]) - { - double yield = value[validation::YIELD].as(); - product.coefficient = yield; - } - products.push_back(product); + double yield = value[keys::YIELD].as(); + product.coefficient = yield; } + products.push_back(product); } - return errors; } - } // namespace v0 -} // namespace mechanism_configuration \ No newline at end of file + return errors; + } +} // namespace mechanism_configuration::v0 \ No newline at end of file diff --git a/src/v0/surface_parser.cpp b/src/v0/surface_parser.cpp index 9a48802b..9e849668 100644 --- a/src/v0/surface_parser.cpp +++ b/src/v0/surface_parser.cpp @@ -1,51 +1,52 @@ -#include -#include -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 -namespace mechanism_configuration +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" + +namespace mechanism_configuration::v0 { - namespace v0 + Errors SurfaceParser(Mechanism& mechanism, const YAML::Node& object) { - Errors SurfaceParser(std::unique_ptr& mechanism, const YAML::Node& object) + Errors errors; + std::vector required = { + keys::TYPE, keys::GAS_PHASE_PRODUCTS, keys::GAS_PHASE_REACTANT, keys::MUSICA_NAME + }; + std::vector optional = { keys::PROBABILITY }; + + auto validate = CheckSchema(object, required, optional); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) { - Errors errors; - std::vector required = { - validation::TYPE, validation::GAS_PHASE_PRODUCTS, validation::GAS_PHASE_REACTANT, validation::MUSICA_NAME - }; - std::vector optional = { validation::PROBABILITY }; - - auto validate = ValidateSchema(object, required, optional); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::vector reactants; - std::vector products; - - std::string species_name = object[validation::GAS_PHASE_REACTANT].as(); - reactants.push_back({ .species_name = species_name, .coefficient = 1.0 }); - - auto parse_error = ParseProducts(object[validation::GAS_PHASE_PRODUCTS], products); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + std::vector reactants; + std::vector products; - types::Surface parameters; + std::string species_name = object[keys::GAS_PHASE_REACTANT].as(); + reactants.push_back({ .name = species_name, .coefficient = 1.0 }); - parameters.gas_phase_species = reactants[0]; - parameters.gas_phase_products = products; + auto parse_error = ParseProducts(object[keys::GAS_PHASE_PRODUCTS], products); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - if (object[validation::PROBABILITY]) - { - parameters.reaction_probability = object[validation::PROBABILITY].as(); - } + types::Surface parameters; - std::string name = "SURF." + object[validation::MUSICA_NAME].as(); - parameters.name = name; + parameters.gas_phase_species = reactants[0]; + parameters.gas_phase_products = products; - mechanism->reactions.surface.push_back(parameters); + if (object[keys::PROBABILITY]) + { + parameters.reaction_probability = object[keys::PROBABILITY].as(); } - return errors; + std::string name = "SURF." + object[keys::MUSICA_NAME].as(); + parameters.name = name; + + mechanism.reactions.surface.push_back(parameters); } - } // namespace v0 -} // namespace mechanism_configuration + + return errors; + } +} // namespace mechanism_configuration::v0 diff --git a/src/v0/ternary_chemical_activation_parser.cpp b/src/v0/ternary_chemical_activation_parser.cpp index 92666ad3..08e68765 100644 --- a/src/v0/ternary_chemical_activation_parser.cpp +++ b/src/v0/ternary_chemical_activation_parser.cpp @@ -1,84 +1,85 @@ -#include -#include -#include -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 -namespace mechanism_configuration +#include "detail/constants.hpp" +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" + +namespace mechanism_configuration::v0 { - namespace v0 + Errors TernaryChemicalActivationParser(Mechanism& mechanism, const YAML::Node& object) { - Errors TernaryChemicalActivationParser(std::unique_ptr& mechanism, const YAML::Node& object) - { - Errors errors; - - std::vector required = { validation::TYPE, validation::REACTANTS, validation::PRODUCTS }; - std::vector optional = { validation::K0_A, validation::K0_B, validation::K0_C, validation::KINF_A, - validation::KINF_B, validation::KINF_C, validation::FC, validation::N }; + Errors errors; - auto validate = ValidateSchema(object, required, optional); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::vector reactants; - std::vector products; + std::vector required = { keys::TYPE, keys::REACTANTS, keys::PRODUCTS }; + std::vector optional = { keys::K0_A, keys::K0_B, keys::K0_C, keys::KINF_A, + keys::KINF_B, keys::KINF_C, keys::FC, keys::N }; - auto parse_error = ParseReactants(object[validation::REACTANTS], reactants); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + auto validate = CheckSchema(object, required, optional); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) + { + std::vector reactants; + std::vector products; - parse_error = ParseProducts(object[validation::PRODUCTS], products); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + auto parse_error = ParseReactants(object[keys::REACTANTS], reactants); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - types::TernaryChemicalActivation parameters; - if (object[validation::K0_A]) - { - parameters.k0_A = object[validation::K0_A].as(); - } - // Account for the conversion of reactant concentrations (including M) to molecules cm-3 - int total_moles = 0; - for (const auto& reactant : reactants) - { - total_moles += reactant.coefficient; - } - parameters.k0_A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles); - if (object[validation::K0_B]) - { - parameters.k0_B = object[validation::K0_B].as(); - } - if (object[validation::K0_C]) - { - parameters.k0_C = object[validation::K0_C].as(); - } - if (object[validation::KINF_A]) - { - parameters.kinf_A = object[validation::KINF_A].as(); - } - // Account for terms in denominator and exponent that include [M] but not other reactants - parameters.kinf_A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles - 1); - if (object[validation::KINF_B]) - { - parameters.kinf_B = object[validation::KINF_B].as(); - } - if (object[validation::KINF_C]) - { - parameters.kinf_C = object[validation::KINF_C].as(); - } - if (object[validation::FC]) - { - parameters.Fc = object[validation::FC].as(); - } - if (object[validation::N]) - { - parameters.N = object[validation::N].as(); - } + parse_error = ParseProducts(object[keys::PRODUCTS], products); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - parameters.reactants = reactants; - parameters.products = products; - mechanism->reactions.ternary_chemical_activation.push_back(parameters); + types::TernaryChemicalActivation parameters; + if (object[keys::K0_A]) + { + parameters.k0_A = object[keys::K0_A].as(); + } + // Account for the conversion of reactant concentrations (including M) to molecules cm-3 + int total_moles = 0; + for (const auto& reactant : reactants) + { + total_moles += reactant.coefficient; + } + parameters.k0_A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles); + if (object[keys::K0_B]) + { + parameters.k0_B = object[keys::K0_B].as(); + } + if (object[keys::K0_C]) + { + parameters.k0_C = object[keys::K0_C].as(); + } + if (object[keys::KINF_A]) + { + parameters.kinf_A = object[keys::KINF_A].as(); + } + // Account for terms in denominator and exponent that include [M] but not other reactants + parameters.kinf_A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles - 1); + if (object[keys::KINF_B]) + { + parameters.kinf_B = object[keys::KINF_B].as(); + } + if (object[keys::KINF_C]) + { + parameters.kinf_C = object[keys::KINF_C].as(); + } + if (object[keys::FC]) + { + parameters.Fc = object[keys::FC].as(); + } + if (object[keys::N]) + { + parameters.N = object[keys::N].as(); } - return errors; + parameters.reactants = reactants; + parameters.products = products; + mechanism.reactions.ternary_chemical_activation.push_back(parameters); } - } // namespace v0 -} // namespace mechanism_configuration + + return errors; + } +} // namespace mechanism_configuration::v0 diff --git a/src/v0/troe_parser.cpp b/src/v0/troe_parser.cpp index b5f90747..01111a73 100644 --- a/src/v0/troe_parser.cpp +++ b/src/v0/troe_parser.cpp @@ -1,84 +1,85 @@ -#include -#include -#include -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 -namespace mechanism_configuration +#include "detail/constants.hpp" +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" + +namespace mechanism_configuration::v0 { - namespace v0 + Errors TroeParser(Mechanism& mechanism, const YAML::Node& object) { - Errors TroeParser(std::unique_ptr& mechanism, const YAML::Node& object) - { - Errors errors; - - std::vector required = { validation::TYPE, validation::REACTANTS, validation::PRODUCTS }; - std::vector optional = { validation::K0_A, validation::K0_B, validation::K0_C, validation::KINF_A, - validation::KINF_B, validation::KINF_C, validation::FC, validation::N }; + Errors errors; - auto validate = ValidateSchema(object, required, optional); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::vector reactants; - std::vector products; + std::vector required = { keys::TYPE, keys::REACTANTS, keys::PRODUCTS }; + std::vector optional = { keys::K0_A, keys::K0_B, keys::K0_C, keys::KINF_A, + keys::KINF_B, keys::KINF_C, keys::FC, keys::N }; - auto parse_error = ParseReactants(object[validation::REACTANTS], reactants); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + auto validate = CheckSchema(object, required, optional); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) + { + std::vector reactants; + std::vector products; - parse_error = ParseProducts(object[validation::PRODUCTS], products); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + auto parse_error = ParseReactants(object[keys::REACTANTS], reactants); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - types::Troe parameters; - if (object[validation::K0_A]) - { - parameters.k0_A = object[validation::K0_A].as(); - } - // Account for the conversion of reactant concentrations (including M) to molecules cm-3 - int total_moles = 0; - for (const auto& reactant : reactants) - { - total_moles += reactant.coefficient; - } - parameters.k0_A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles); - if (object[validation::K0_B]) - { - parameters.k0_B = object[validation::K0_B].as(); - } - if (object[validation::K0_C]) - { - parameters.k0_C = object[validation::K0_C].as(); - } - if (object[validation::KINF_A]) - { - parameters.kinf_A = object[validation::KINF_A].as(); - } - // Account for terms in denominator and exponent that include [M] but not other reactants - parameters.kinf_A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles - 1); - if (object[validation::KINF_B]) - { - parameters.kinf_B = object[validation::KINF_B].as(); - } - if (object[validation::KINF_C]) - { - parameters.kinf_C = object[validation::KINF_C].as(); - } - if (object[validation::FC]) - { - parameters.Fc = object[validation::FC].as(); - } - if (object[validation::N]) - { - parameters.N = object[validation::N].as(); - } + parse_error = ParseProducts(object[keys::PRODUCTS], products); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - parameters.reactants = reactants; - parameters.products = products; - mechanism->reactions.troe.push_back(parameters); + types::Troe parameters; + if (object[keys::K0_A]) + { + parameters.k0_A = object[keys::K0_A].as(); + } + // Account for the conversion of reactant concentrations (including M) to molecules cm-3 + int total_moles = 0; + for (const auto& reactant : reactants) + { + total_moles += reactant.coefficient; + } + parameters.k0_A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles); + if (object[keys::K0_B]) + { + parameters.k0_B = object[keys::K0_B].as(); + } + if (object[keys::K0_C]) + { + parameters.k0_C = object[keys::K0_C].as(); + } + if (object[keys::KINF_A]) + { + parameters.kinf_A = object[keys::KINF_A].as(); + } + // Account for terms in denominator and exponent that include [M] but not other reactants + parameters.kinf_A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles - 1); + if (object[keys::KINF_B]) + { + parameters.kinf_B = object[keys::KINF_B].as(); + } + if (object[keys::KINF_C]) + { + parameters.kinf_C = object[keys::KINF_C].as(); + } + if (object[keys::FC]) + { + parameters.Fc = object[keys::FC].as(); + } + if (object[keys::N]) + { + parameters.N = object[keys::N].as(); } - return errors; + parameters.reactants = reactants; + parameters.products = products; + mechanism.reactions.troe.push_back(parameters); } - } // namespace v0 -} // namespace mechanism_configuration + + return errors; + } +} // namespace mechanism_configuration::v0 diff --git a/src/v0/tunneling_parser.cpp b/src/v0/tunneling_parser.cpp index af463fb8..04b5182f 100644 --- a/src/v0/tunneling_parser.cpp +++ b/src/v0/tunneling_parser.cpp @@ -1,60 +1,61 @@ -#include -#include -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 -namespace mechanism_configuration +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" + +namespace mechanism_configuration::v0 { - namespace v0 + Errors TunnelingParser(Mechanism& mechanism, const YAML::Node& object) { - Errors TunnelingParser(std::unique_ptr& mechanism, const YAML::Node& object) + Errors errors; + + std::vector required = { keys::TYPE, keys::REACTANTS, keys::PRODUCTS }; + std::vector optional = { keys::A, keys::B, keys::C }; + + auto validate = CheckSchema(object, required, optional); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) { - Errors errors; + std::vector reactants; + std::vector products; - std::vector required = { validation::TYPE, validation::REACTANTS, validation::PRODUCTS }; - std::vector optional = { validation::A, validation::B, validation::C }; + auto parse_error = ParseReactants(object[keys::REACTANTS], reactants); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - auto validate = ValidateSchema(object, required, optional); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) + parse_error = ParseProducts(object[keys::PRODUCTS], products); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + + types::Tunneling parameters; + if (object[keys::A]) + { + parameters.A = object[keys::A].as(); + } + // Account for the conversion of reactant concentrations to molecules cm-3 + int total_moles = 0; + for (auto& reactant : reactants) { - std::vector reactants; - std::vector products; - - auto parse_error = ParseReactants(object[validation::REACTANTS], reactants); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - - parse_error = ParseProducts(object[validation::PRODUCTS], products); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - - types::Tunneling parameters; - if (object[validation::A]) - { - parameters.A = object[validation::A].as(); - } - // Account for the conversion of reactant concentrations to molecules cm-3 - int total_moles = 0; - for (auto& reactant : reactants) - { - total_moles += reactant.coefficient; - } - parameters.A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles - 1); - if (object[validation::B]) - { - parameters.B = object[validation::B].as(); - } - if (object[validation::C]) - { - parameters.C = object[validation::C].as(); - } - - parameters.reactants = reactants; - parameters.products = products; - mechanism->reactions.tunneling.push_back(parameters); + total_moles += reactant.coefficient; + } + parameters.A *= std::pow(conversions::MolesM3ToMoleculesCm3, total_moles - 1); + if (object[keys::B]) + { + parameters.B = object[keys::B].as(); + } + if (object[keys::C]) + { + parameters.C = object[keys::C].as(); } - return errors; + parameters.reactants = reactants; + parameters.products = products; + mechanism.reactions.tunneling.push_back(parameters); } - } // namespace v0 -} // namespace mechanism_configuration + + return errors; + } +} // namespace mechanism_configuration::v0 diff --git a/src/v0/user_defined_reaction_parser.cpp b/src/v0/user_defined_reaction_parser.cpp index 31316c28..f99654d8 100644 --- a/src/v0/user_defined_reaction_parser.cpp +++ b/src/v0/user_defined_reaction_parser.cpp @@ -1,46 +1,47 @@ -#include -#include -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 -namespace mechanism_configuration +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" +#include "detail/v0/parser_types.hpp" +#include "detail/v0/keys.hpp" +#include "detail/check_schema.hpp" + +namespace mechanism_configuration::v0 { - namespace v0 + Errors UserDefinedParser(Mechanism& mechanism, const YAML::Node& object) { - Errors UserDefinedParser(std::unique_ptr& mechanism, const YAML::Node& object) - { - Errors errors; - - std::vector required = { - validation::TYPE, validation::REACTANTS, validation::PRODUCTS, validation::MUSICA_NAME - }; - std::vector optional = { validation::SCALING_FACTOR }; + Errors errors; - auto validate = ValidateSchema(object, required, optional); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::vector reactants; - std::vector products; + std::vector required = { + keys::TYPE, keys::REACTANTS, keys::PRODUCTS, keys::MUSICA_NAME + }; + std::vector optional = { keys::SCALING_FACTOR }; - auto parse_error = ParseReactants(object[validation::REACTANTS], reactants); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + auto validate = CheckSchema(object, required, optional); + errors.insert(errors.end(), validate.begin(), validate.end()); + if (validate.empty()) + { + std::vector reactants; + std::vector products; - parse_error = ParseProducts(object[validation::PRODUCTS], products); - errors.insert(errors.end(), parse_error.begin(), parse_error.end()); + auto parse_error = ParseReactants(object[keys::REACTANTS], reactants); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - double scaling_factor = object[validation::SCALING_FACTOR] ? object[validation::SCALING_FACTOR].as() : 1.0; + parse_error = ParseProducts(object[keys::PRODUCTS], products); + errors.insert(errors.end(), parse_error.begin(), parse_error.end()); - std::string name = "USER." + object[validation::MUSICA_NAME].as(); + double scaling_factor = object[keys::SCALING_FACTOR] ? object[keys::SCALING_FACTOR].as() : 1.0; - types::UserDefined user_defined = { - .scaling_factor = scaling_factor, .reactants = reactants, .products = products, .name = name - }; - mechanism->reactions.user_defined.push_back(user_defined); - } + std::string name = "USER." + object[keys::MUSICA_NAME].as(); - return errors; + types::UserDefined user_defined = { + .scaling_factor = scaling_factor, .reactants = reactants, .products = products, .name = name + }; + mechanism.reactions.user_defined.push_back(user_defined); } - } // namespace v0 -} // namespace mechanism_configuration + + return errors; + } +} // namespace mechanism_configuration::v0 diff --git a/src/v1/CMakeLists.txt b/src/v1/CMakeLists.txt index ab40316b..d752c785 100644 --- a/src/v1/CMakeLists.txt +++ b/src/v1/CMakeLists.txt @@ -1,7 +1,8 @@ target_sources(mechanism_configuration PRIVATE parser.cpp - mechanism_parsers.cpp + type_parsers.cpp + type_schema.cpp utils.cpp ) diff --git a/src/v1/mechanism_parsers.cpp b/src/v1/mechanism_parsers.cpp deleted file mode 100644 index d04b22ee..00000000 --- a/src/v1/mechanism_parsers.cpp +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include - -#include - -namespace -{ - std::string FormatYamlError(const YAML::Node& node, const std::string& message) - { - std::string line = std::to_string(node.Mark().line + 1); - std::string column = std::to_string(node.Mark().column + 1); - std::ostringstream oss; - oss << line << ":" << column << message; - return oss.str(); - } -} // namespace - -namespace mechanism_configuration -{ - namespace v1 - { - std::pair> ParseSpecies(const YAML::Node& objects) - - { - Errors errors; - std::vector all_species; - std::vector> species_node_pairs; - - for (const auto& object : objects) - { - types::Species species; - std::vector required_keys = { validation::name }; - std::vector optional_keys = { validation::molecular_weight, - validation::constant_concentration, - validation::constant_mixing_ratio, - validation::is_third_body }; - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::string name = object[validation::name].as(); - species.name = name; - - if (object[validation::molecular_weight]) - species.molecular_weight = object[validation::molecular_weight].as(); - if (object[validation::constant_concentration]) - species.constant_concentration = object[validation::constant_concentration].as(); - if (object[validation::constant_mixing_ratio]) - species.constant_mixing_ratio = object[validation::constant_mixing_ratio].as(); - if (object[validation::is_third_body]) - species.is_third_body = object[validation::is_third_body].as(); - - species.unknown_properties = GetComments(object); - - all_species.push_back(species); - species_node_pairs.push_back({ species, object }); - } - } - - std::vector duplicates = FindDuplicateObjectsByName(species_node_pairs); - if (!duplicates.empty()) - { - for (const auto& duplicate : duplicates) - { - size_t total = duplicate.nodes.size(); - - for (size_t i = 0; i < total; ++i) - { - const auto& object = duplicate.nodes[i]; - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - - std::ostringstream oss; - oss << line << ":" << column << " error: Duplicate species name '" << duplicate.name << "' found (" << (i + 1) - << " of " << total << ")"; - - errors.push_back({ ConfigParseStatus::DuplicateSpeciesDetected, oss.str() }); - } - } - } - - return { errors, all_species }; - } - - std::pair> ParsePhases( - const YAML::Node& objects, - const std::vector existing_species) - { - Errors errors; - std::vector all_phases; - std::vector> phase_node_pairs; - - const std::vector phase_required_keys = { validation::name, validation::species }; - const std::vector phase_optional_keys = {}; - - for (const auto& object : objects) - { - types::Phase phase; - auto validate = ValidateSchema(object, phase_required_keys, phase_optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::string name = object[validation::name].as(); - - std::vector species{}; - for (const auto& spec : object[validation::species]) - { - types::PhaseSpecies phase_species; - if (spec.IsScalar()) - { - // Simple string species name - phase_species.name = spec.as(); - } - else if (spec.IsMap()) - { - // Complex species with properties - if (!spec[validation::name]) - { - errors.push_back({ ConfigParseStatus::RequiredKeyNotFound, - FormatYamlError(spec, "Species object missing required 'name' field") }); - continue; - } - - phase_species.name = spec[validation::name].as(); - - // Parse standard properties - if (spec[validation::diffusion_coefficient]) - phase_species.diffusion_coefficient = spec[validation::diffusion_coefficient].as(); - - // Parse custom properties (those starting with __) - phase_species.unknown_properties = GetComments(spec); - } - else - { - errors.push_back( - { ConfigParseStatus::InvalidKey, - FormatYamlError(spec, "Species must be either a string name or an object with properties") }); - continue; - } - species.push_back(phase_species); - } - - phase.name = name; - phase.species = species; - phase.unknown_properties = GetComments(object); - - // Check for duplicate species within this phase - for (size_t i = 0; i < species.size(); ++i) - { - for (size_t j = i + 1; j < species.size(); ++j) - { - if (species[i].name == species[j].name) - { - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - std::ostringstream oss; - oss << line << ":" << column << " error: Duplicate species '" << species[i].name << "' found in '" << name - << "' phase"; - errors.push_back({ ConfigParseStatus::DuplicateSpeciesInPhaseDetected, oss.str() }); - } - } - } - - std::vector species_names; - for (const auto& spec : species) - { - species_names.push_back(spec.name); - } - std::vector unknown_species = FindUnknownSpecies(species_names, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - oss << " error: Phase '" << phase.name << "' requires unknown species: "; - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - errors.push_back({ ConfigParseStatus::PhaseRequiresUnknownSpecies, oss.str() }); - } - - all_phases.push_back(phase); - phase_node_pairs.push_back({ phase, object }); - } - } - - std::vector duplicates = FindDuplicateObjectsByName(phase_node_pairs); - if (!duplicates.empty()) - { - for (const auto& duplicate : duplicates) - { - size_t total = duplicate.nodes.size(); - - for (size_t i = 0; i < total; ++i) - { - const auto& object = duplicate.nodes[i]; - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - - std::ostringstream oss; - oss << line << ":" << column << " error: Duplicate phase name '" << duplicate.name << "' found (" << (i + 1) - << " of " << total << ")"; - - errors.push_back({ ConfigParseStatus::DuplicatePhasesDetected, oss.str() }); - } - } - } - - return { errors, all_phases }; - } - - std::pair ParseReactionComponent(const YAML::Node& object) - { - Errors errors; - ConfigParseStatus status = ConfigParseStatus::Success; - types::ReactionComponent component; - const std::vector reaction_component_required_keys = { validation::species_name }; - const std::vector reaction_component_optional_keys = { validation::coefficient }; - - auto validate = ValidateSchema(object, reaction_component_required_keys, reaction_component_optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - if (status == ConfigParseStatus::Success) - { - std::string species_name = object[validation::species_name].as(); - double coefficient = 1; - if (object[validation::coefficient]) - { - coefficient = object[validation::coefficient].as(); - } - - component.species_name = species_name; - component.coefficient = coefficient; - component.unknown_properties = GetComments(object); - } - - return { errors, component }; - } - - std::pair> ParseReactantsOrProducts( - const std::string& key, - const YAML::Node& object) - { - Errors errors; - std::vector result{}; - for (const auto& product : object[key]) - { - auto component_parse = ParseReactionComponent(product); - errors.insert(errors.end(), component_parse.first.begin(), component_parse.first.end()); - if (component_parse.first.empty()) - { - result.push_back(component_parse.second); - } - } - return { errors, result }; - } - - std::pair ParseReactions( - const YAML::Node& objects, - const std::vector& existing_species, - const std::vector& existing_phases) - { - Errors errors; - types::Reactions reactions; - - std::map> parsers; - parsers[validation::Arrhenius_key] = std::make_unique(); - parsers[validation::FirstOrderLoss_key] = std::make_unique(); - parsers[validation::Emission_key] = std::make_unique(); - parsers[validation::Photolysis_key] = std::make_unique(); - parsers[validation::Surface_key] = std::make_unique(); - parsers[validation::TaylorSeries_key] = std::make_unique(); - parsers[validation::Tunneling_key] = std::make_unique(); - parsers[validation::Branched_key] = std::make_unique(); - parsers[validation::Troe_key] = std::make_unique(); - parsers[validation::TernaryChemicalActivation_key] = std::make_unique(); - parsers[validation::UserDefined_key] = std::make_unique(); - parsers[validation::LambdaRateConstant_key] = std::make_unique(); - - for (const auto& object : objects) - { - std::string type = object[validation::type].as(); - auto it = parsers.find(type); - if (it != parsers.end()) - { - auto parse_errors = it->second->parse(object, existing_species, existing_phases, reactions); - errors.insert(errors.end(), parse_errors.begin(), parse_errors.end()); - } - else - { - std::string line = std::to_string(object[validation::type].Mark().line + 1); - std::string column = std::to_string(object[validation::type].Mark().column + 1); - errors.push_back( - { ConfigParseStatus::UnknownType, "Unknown type: " + type + " at line " + line + " column " + column }); - } - } - - return { errors, reactions }; - } - - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/parser.cpp b/src/v1/parser.cpp index d836db8f..02f8c61e 100644 --- a/src/v1/parser.cpp +++ b/src/v1/parser.cpp @@ -2,19 +2,34 @@ // University of Illinois at Urbana-Champaign // SPDX-License-Identifier: Apache-2.0 -#include -#include -#include -#include -#include +#include "detail/v1/parser.hpp" +#include "detail/v1/type_parsers.hpp" +#include "detail/v1/type_schema.hpp" +#include "detail/v1/utils.hpp" +#include "detail/check_schema.hpp" +#include "detail/v1/keys.hpp" +#include +#include +#include #include -namespace mechanism_configuration +#include +#include + +namespace mechanism_configuration::v1 { - namespace v1 + namespace { - Parser::EntityFormat Parser::GetEntityFormat(const YAML::Node& node) + // How a top-level section (species / phases / reactions) is expressed. + enum class EntityFormat + { + FileList, // { "files": [...] } — split across other files (v1.1+) + Inline, // [ ... ] — listed directly + Invalid, // present but neither of the above + }; + + EntityFormat GetEntityFormat(const YAML::Node& node) { if (node.IsMap() && node["files"]) return EntityFormat::FileList; @@ -23,226 +38,318 @@ namespace mechanism_configuration return EntityFormat::Invalid; } - ParserResult Parser::ParseFromString(const std::string& content) + ErrorLocation LocationOf(const YAML::Node& node) { - ParserResult result; - try - { - YAML::Node object = YAML::Load(content); + return ErrorLocation{ node.Mark().line, node.Mark().column }; + } - std::vector required_keys = { - validation::version, validation::species, validation::phases, validation::reactions - }; - std::vector optional_keys = { validation::name }; + // Appends each component under `key` (reactant- or product-like) as a located reference. + void CollectComponents(const YAML::Node& reaction, std::string_view key, std::vector& out) + { + const std::string k(key); + if (!reaction[k]) + return; + for (const auto& item : AsSequence(reaction[k])) + out.push_back({ GetReactionComponentName(item), LocationOf(item) }); + } + } // namespace - auto validate_errors = ValidateSchema(object, required_keys, optional_keys); - if (!validate_errors.empty()) - { - result.errors = validate_errors; - return result; - } + semantics::Input BuildSemanticInput(const YAML::Node& object) + { + semantics::Input input; + + if (object[std::string(keys::species)]) + for (const auto& s : object[std::string(keys::species)]) + input.species.push_back({ GetReactionComponentName(s), LocationOf(s) }); - return ParseFromNode(object); + if (object[std::string(keys::phases)]) + for (const auto& phase : object[std::string(keys::phases)]) + { + semantics::PhaseRef pr; + pr.name = phase[std::string(keys::name)].as(); + pr.location = LocationOf(phase); + if (phase[std::string(keys::species)]) + for (const auto& ps : phase[std::string(keys::species)]) + pr.species.push_back({ GetReactionComponentName(ps), LocationOf(ps) }); + input.phases.push_back(std::move(pr)); } - catch (const std::exception& e) + + if (object[std::string(keys::reactions)]) + for (const auto& reaction : object[std::string(keys::reactions)]) { - std::string msg = "Failed to parse content as YAML: " + std::string(e.what()); - msg += "\nContent:\n" + content; - result.errors.push_back({ ConfigParseStatus::UnexpectedError, msg }); + semantics::ReactionRef rr; + if (reaction[std::string(keys::type)]) + rr.type = reaction[std::string(keys::type)].as(); + if (reaction[std::string(keys::gas_phase)]) + { + rr.phase = reaction[std::string(keys::gas_phase)].as(); + rr.location = LocationOf(reaction[std::string(keys::gas_phase)]); + } + // Reactant-like keys (must be in the reaction's phase). + CollectComponents(reaction, keys::reactants, rr.reactants); + CollectComponents(reaction, keys::gas_phase_species, rr.reactants); + // Product-like keys (may reference any phase). + CollectComponents(reaction, keys::products, rr.products); + CollectComponents(reaction, keys::alkoxy_products, rr.products); + CollectComponents(reaction, keys::nitrate_products, rr.products); + CollectComponents(reaction, keys::gas_phase_products, rr.products); + input.reactions.push_back(std::move(rr)); } - return result; - } + return input; + } - ParserResult Parser::Parse(const std::filesystem::path& config_path) + std::expected Parser::ResolveFileConfig(const std::filesystem::path& config_path) + { + if (!std::filesystem::exists(config_path) || !std::filesystem::is_regular_file(config_path)) { - ParserResult result; + return std::unexpected( + Errors{ { ErrorCode::FileNotFound, + mc_fmt::format( + "Configuration file '{}' does not exist or is not a regular file.", config_path.string()) } }); + } - if (!std::filesystem::exists(config_path) || !std::filesystem::is_regular_file(config_path)) - { - result.errors.push_back({ ConfigParseStatus::FileNotFound, "File not found or is a directory" }); - return result; - } + SetConfigPath(config_path.string()); - auto prepend_path = [&](Errors& errors) - { - const std::string prefix = config_path.string() + ":"; - for (auto& error : errors) - error.second = prefix + error.second; - }; - - try - { - YAML::Node object = YAML::LoadFile(config_path.string()); + YAML::Node object; + try + { + object = YAML::LoadFile(config_path.string()); + } + catch (const std::exception& e) + { + return std::unexpected( + Errors{ + { ErrorCode::UnexpectedError, mc_fmt::format("Failed to parse '{}': {}", config_path.string(), e.what()) } }); + } - std::vector mechanism_required_keys = { - validation::version, validation::species, validation::phases, validation::reactions - }; - std::vector mechanism_optional_keys = { validation::name }; + Errors errors; + const std::filesystem::path base_dir = config_path.parent_path(); + const Version version = object[keys::version] ? Version(object[keys::version].as()) : Version(); - auto validate_errors = ValidateSchema(object, mechanism_required_keys, mechanism_optional_keys); + YAML::Node combined; + if (object[keys::version]) + combined[std::string(keys::version)] = object[keys::version]; + if (object[keys::name]) + combined[std::string(keys::name)] = object[keys::name]; - if (!validate_errors.empty()) + // Loads and concatenates every file referenced under `.files`. + auto load_files = [&](std::string_view entity) -> YAML::Node + { + YAML::Node merged(YAML::NodeType::Sequence); + for (const auto& file_node : object[std::string(entity)]["files"]) + { + const std::filesystem::path file_path = base_dir / file_node.as(); + if (!std::filesystem::exists(file_path)) { - result.errors = validate_errors; - prepend_path(result.errors); - return result; + errors.push_back({ ErrorCode::FileNotFound, "File not found: " + file_path.string() }); + continue; } - - Version version = Version(object[validation::version].as()); - if (version.major != 1) + try { - result.errors.push_back( - { ConfigParseStatus::InvalidVersion, - "Unsupported version '" + object[validation::version].as() + "'. Expected major version 1." }); - prepend_path(result.errors); - return result; + YAML::Node loaded = YAML::LoadFile(file_path.string()); + for (const auto& item : loaded) + merged.push_back(item); } - - EntityFormat spc_format = GetEntityFormat(object[validation::species]); - EntityFormat phs_format = GetEntityFormat(object[validation::phases]); - EntityFormat rxn_format = GetEntityFormat(object[validation::reactions]); - - auto check_invalid = [&](const std::string& entity, EntityFormat fmt) - { - if (fmt == EntityFormat::Invalid) - { - if (object[entity] && object[entity].IsMap()) - result.errors.push_back( - { ConfigParseStatus::RequiredKeyNotFound, "Missing 'files' key in '" + entity + "' section." }); - else - result.errors.push_back( - { ConfigParseStatus::InvalidType, "'" + entity + "' must be a file-list object or an inline array." }); - } - }; - check_invalid(validation::species, spc_format); - check_invalid(validation::phases, phs_format); - check_invalid(validation::reactions, rxn_format); - - if (result.errors.empty()) + catch (const std::exception& e) { - bool any_filelist = spc_format == EntityFormat::FileList || phs_format == EntityFormat::FileList || - rxn_format == EntityFormat::FileList; - if (any_filelist && version.minor < 1) - { - result.errors.push_back( - { ConfigParseStatus::InvalidVersion, - "File-list format requires minor version >= 1, got " + std::to_string(version.minor) + "." }); - } - else - { - result = ParseFromFileConfig(object, config_path, spc_format, phs_format, rxn_format); - } + errors.push_back({ ErrorCode::UnexpectedError, "Failed to parse file: " + file_path.string() + ": " + e.what() }); } } - catch (const std::exception& e) - { - result.errors.push_back({ ConfigParseStatus::UnexpectedError, - "Failed to parse '" + config_path.string() + "': " + std::string(e.what()) }); - return result; - } + return merged; + }; - if (!result.errors.empty()) + // Resolves one section into the combined node. Missing sections are left out so the + // normal schema validation reports them; malformed sections are flagged here. + auto resolve_section = [&](std::string_view entity) + { + const std::string key(entity); + if (!object[key]) + return; + + switch (GetEntityFormat(object[key])) { - prepend_path(result.errors); + case EntityFormat::Inline: combined[key] = object[key]; break; + case EntityFormat::FileList: combined[key] = load_files(entity); break; + case EntityFormat::Invalid: + if (object[key].IsMap()) + errors.push_back({ ErrorCode::RequiredKeyNotFound, "Missing 'files' key in '" + key + "' section." }); + else + errors.push_back({ ErrorCode::InvalidType, "'" + key + "' must be a file-list object or an inline array." }); + break; } + }; + // A file-list layout requires minor version >= 1; check before loading any files. + const bool uses_filelist = (object[std::string(keys::species)] && + GetEntityFormat(object[std::string(keys::species)]) == EntityFormat::FileList) || + (object[std::string(keys::phases)] && + GetEntityFormat(object[std::string(keys::phases)]) == EntityFormat::FileList) || + (object[std::string(keys::reactions)] && + GetEntityFormat(object[std::string(keys::reactions)]) == EntityFormat::FileList); + if (uses_filelist && version.minor < 1) + { + errors.push_back( + { ErrorCode::InvalidVersion, + "File-list format requires minor version >= 1, got " + std::to_string(version.minor) + "." }); + AppendFilePath(config_path_, errors); + return std::unexpected(std::move(errors)); + } - return result; + resolve_section(keys::species); + resolve_section(keys::phases); + resolve_section(keys::reactions); + + if (!errors.empty()) + { + AppendFilePath(config_path_, errors); + return std::unexpected(std::move(errors)); } - ParserResult Parser::ParseFromNode(const YAML::Node& object) + return combined; + } + + Errors Parser::CheckSchema(const YAML::Node& object) + { + Errors errors; + + std::vector required_keys = { + keys::version, keys::species, keys::phases, keys::reactions + }; + std::vector optional_keys = { keys::name }; + + // Return early if the required keys are not found + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) { - ParserResult result; - std::unique_ptr mechanism = std::make_unique(); + AppendFilePath(config_path_, schema_errors); + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } - mechanism->version = Version(object[validation::version].as()); + constexpr unsigned int MAJOR_VERSION = 1; + Version version = Version(object[keys::version].as()); + if (version.major != MAJOR_VERSION) + { + ErrorLocation error_location{ object[keys::version].Mark().line, object[keys::version].Mark().column }; + + std::string message = mc_fmt::format( + "{} error: The version must be '{}' but the invalid version number '{}' found.", + error_location, + MAJOR_VERSION, + version.major); + errors.push_back({ ErrorCode::InvalidVersion, config_path_ + ":" + message }); + } - if (object[validation::name]) - { - std::string name = object[validation::name].as(); - mechanism->name = name; - } + schema_errors = CheckSpeciesSchema(object[keys::species]); + if (!schema_errors.empty()) + { + AppendFilePath(config_path_, schema_errors); + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } - auto species_parsing = ParseSpecies(object[validation::species]); - result.errors.insert(result.errors.end(), species_parsing.first.begin(), species_parsing.first.end()); - mechanism->species = species_parsing.second; + auto parsed_species = ParseSpecies(object[keys::species]); - auto phases_parsing = ParsePhases(object[validation::phases], species_parsing.second); - result.errors.insert(result.errors.end(), phases_parsing.first.begin(), phases_parsing.first.end()); - mechanism->phases = phases_parsing.second; + schema_errors = CheckPhasesSchema(object[keys::phases], parsed_species); + if (!schema_errors.empty()) + { + AppendFilePath(config_path_, schema_errors); + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } - auto reactions_parsing = ParseReactions(object[validation::reactions], species_parsing.second, phases_parsing.second); - result.errors.insert(result.errors.end(), reactions_parsing.first.begin(), reactions_parsing.first.end()); - mechanism->reactions = reactions_parsing.second; + auto parsed_phases = ParsePhases(object[keys::phases]); - result.mechanism = std::move(mechanism); - return result; + schema_errors = CheckReactionsSchema(object[keys::reactions], parsed_species, parsed_phases); + if (!schema_errors.empty()) + { + AppendFilePath(config_path_, schema_errors); + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; } - ParserResult Parser::ParseFromFileConfig( - const YAML::Node& object, - const std::filesystem::path& config_path, - EntityFormat spc_format, - EntityFormat phs_format, - EntityFormat rxn_format) + return errors; + } + + std::expected Parser::Parse(const std::filesystem::path& config_path) + { + // ResolveFileConfig sets config_path_ so errors carry the file path. + auto object = ResolveFileConfig(config_path); + if (!object) { - ParserResult result; + return std::unexpected(std::move(object.error())); + } + return ValidateAndBuild(*object); + } - std::filesystem::path base_dir = config_path.parent_path(); + std::expected Parser::Parse(const std::string& content) + { + SetDefaultConfigPath(); // no file backing this document + YAML::Node object; + try + { + object = YAML::Load(content); + } + catch (const std::exception& e) + { + return std::unexpected(Errors{ { ErrorCode::UnexpectedError, mc_fmt::format("Failed to parse document: {}", e.what()) } }); + } + return ValidateAndBuild(object); + } - auto load_files = [&](const std::string& entity) -> std::pair - { - Errors errors; - YAML::Node merged = YAML::Node(YAML::NodeType::Sequence); + std::expected Parser::Parse(const YAML::Node& object) + { + SetDefaultConfigPath(); // no file backing this node + return ValidateAndBuild(object); + } - for (const auto& file_node : object[entity]["files"]) - { - std::filesystem::path file_path = base_dir / file_node.as(); - if (!std::filesystem::exists(file_path)) - { - errors.push_back({ ConfigParseStatus::FileNotFound, "File not found: " + file_path.string() }); - continue; - } - try - { - YAML::Node loaded = YAML::LoadFile(file_path.string()); - for (const auto& item : loaded) - merged.push_back(item); - } - catch (const std::exception& e) - { - errors.push_back( - { ConfigParseStatus::UnexpectedError, "Failed to parse file: " + file_path.string() + ": " + e.what() }); - } - } - return { errors, merged }; - }; + std::expected Parser::ValidateAndBuild(const YAML::Node& object) + { + try + { + // 1) Structural (schema) validation. + Errors errors = CheckSchema(object); - auto resolve_section = [&](const std::string& entity, EntityFormat fmt) -> std::pair + // 2) Semantic validation — needs a structurally-valid document, so only run it when + // the structure is clean. Located via BuildSemanticInput so errors carry line:col. + if (errors.empty()) { - if (fmt == EntityFormat::Inline) - return { {}, object[entity] }; - return load_files(entity); - }; + auto semantic_errors = ValidateSemantics(BuildSemanticInput(object)); + AppendFilePath(config_path_, semantic_errors); + errors.insert(errors.end(), semantic_errors.begin(), semantic_errors.end()); + } - YAML::Node combined; - combined[validation::version] = object[validation::version]; - if (object[validation::name]) - combined[validation::name] = object[validation::name]; + if (!errors.empty()) + { + return std::unexpected(std::move(errors)); + } - auto [species_errors, species_node] = resolve_section(validation::species, spc_format); - result.errors.insert(result.errors.end(), species_errors.begin(), species_errors.end()); - combined[validation::species] = species_node; + // 3) Build the Mechanism (only reached when fully valid). + return Build(object); + } + catch (const std::exception& e) + { + const std::string where = config_path_.empty() ? "document" : "'" + config_path_ + "'"; + return std::unexpected( + Errors{ { ErrorCode::UnexpectedError, mc_fmt::format("Failed to parse {}: {}", where, e.what()) } }); + } + } - auto [phases_errors, phases_node] = resolve_section(validation::phases, phs_format); - result.errors.insert(result.errors.end(), phases_errors.begin(), phases_errors.end()); - combined[validation::phases] = phases_node; + Mechanism Parser::Build(const YAML::Node& object) + { + Mechanism mechanism; - auto [reactions_errors, reactions_node] = resolve_section(validation::reactions, rxn_format); - result.errors.insert(result.errors.end(), reactions_errors.begin(), reactions_errors.end()); - combined[validation::reactions] = reactions_node; + mechanism.version = Version(object[keys::version].as()); + mechanism.species = ParseSpecies(object[keys::species]); + mechanism.phases = ParsePhases(object[keys::phases]); + mechanism.reactions = ParseReactions(object[keys::reactions]); - return ParseFromNode(combined); + if (object[keys::name]) + { + mechanism.name = object[keys::name].as(); } - } // namespace v1 -} // namespace mechanism_configuration \ No newline at end of file + + return mechanism; + } + +} // namespace mechanism_configuration::v1 diff --git a/src/v1/reactions/CMakeLists.txt b/src/v1/reactions/CMakeLists.txt index 1a49b905..23f955b9 100644 --- a/src/v1/reactions/CMakeLists.txt +++ b/src/v1/reactions/CMakeLists.txt @@ -1,15 +1,15 @@ target_sources(mechanism_configuration PRIVATE - arrhenius_parser.cpp - branched_parser.cpp - emission_parser.cpp - first_order_loss_parser.cpp - lambda_parser.cpp - photolysis_parser.cpp - surface_parser.cpp - taylor_series_parser.cpp - troe_parser.cpp - ternary_chemical_activation_parser.cpp - tunneling_parser.cpp - user_defined_parser.cpp + arrhenius.cpp + branched.cpp + emission.cpp + first_order_loss.cpp + photolysis.cpp + surface.cpp + taylor_series.cpp + ternary_chemical_activation.cpp + troe.cpp + tunneling.cpp + user_defined.cpp + lambda_rate_constant.cpp ) diff --git a/src/v1/reactions/arrhenius.cpp b/src/v1/reactions/arrhenius.cpp new file mode 100644 index 00000000..498f6ace --- /dev/null +++ b/src/v1/reactions/arrhenius.cpp @@ -0,0 +1,124 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined Arrhenius reaction entry + /// Performs schema validation, checks for mutually exclusive parameters (`Ea` vs `C`), + /// and collects any structural errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors ArrheniusParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { + keys::reactants, keys::products, keys::type, keys::gas_phase + }; + std::vector optional_keys = { keys::A, keys::B, keys::C, keys::D, + keys::E, keys::Ea, keys::name }; + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Reactants + schema_errors = CheckReactantsOrProductsSchema(object[keys::reactants]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Products + schema_errors = CheckReactantsOrProductsSchema(object[keys::products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + if (object[keys::Ea] && object[keys::C]) + { + const auto& node = object[keys::Ea]; + ErrorLocation error_location{ node.Mark().line, node.Mark().column }; + + std::string message = mc_fmt::format( + "{} error: Mutually exclusive option of 'Ea' and 'C' found in '{}' reaction.", + error_location, + object[keys::type].as()); + + errors.push_back({ ErrorCode::MutuallyExclusiveOption, message }); + } + + // Semantic checks (species existence, phase membership) are performed by the + // version-neutral ValidateSemantics over the canonical Mechanism. + return errors; + } + + /// @brief Parses a YAML-defined Arrhenius reaction and appends it to the reaction list. + /// Extracts reactants, products, kinetic parameters (A–E, Ea), gas phase, + /// optional metadata (name, comments), and constructs a `types::Arrhenius` object. + /// @param object The YAML node representing the reaction + /// @param reactions The reactions container to append the parsed reaction to + void ArrheniusParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::Arrhenius arrhenius; + + arrhenius.gas_phase = object[keys::gas_phase].as(); + arrhenius.reactants = ParseReactionComponents(object, keys::reactants); + arrhenius.products = ParseReactionComponents(object, keys::products); + arrhenius.unknown_properties = GetComments(object); + + if (object[keys::A]) + { + arrhenius.A = object[keys::A].as(); + } + if (object[keys::B]) + { + arrhenius.B = object[keys::B].as(); + } + if (object[keys::C]) + { + arrhenius.C = object[keys::C].as(); + } + if (object[keys::D]) + { + arrhenius.D = object[keys::D].as(); + } + if (object[keys::E]) + { + arrhenius.E = object[keys::E].as(); + } + if (object[keys::Ea]) + { + arrhenius.C = -1 * object[keys::Ea].as() / constants::boltzmann; + } + if (object[keys::name]) + { + arrhenius.name = object[keys::name].as(); + } + + reactions.arrhenius.emplace_back(std::move(arrhenius)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/arrhenius_parser.cpp b/src/v1/reactions/arrhenius_parser.cpp deleted file mode 100644 index e8220e51..00000000 --- a/src/v1/reactions/arrhenius_parser.cpp +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors ArrheniusParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::Arrhenius arrhenius; - - std::vector required_keys = { - validation::products, validation::reactants, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::A, validation::B, validation::C, validation::D, - validation::E, validation::Ea, validation::name }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto products = ParseReactantsOrProducts(validation::products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - auto reactants = ParseReactantsOrProducts(validation::reactants, object); - errors.insert(errors.end(), reactants.first.begin(), reactants.first.end()); - - if (object[validation::A]) - { - arrhenius.A = object[validation::A].as(); - } - if (object[validation::B]) - { - arrhenius.B = object[validation::B].as(); - } - if (object[validation::C]) - { - arrhenius.C = object[validation::C].as(); - } - if (object[validation::D]) - { - arrhenius.D = object[validation::D].as(); - } - if (object[validation::E]) - { - arrhenius.E = object[validation::E].as(); - } - if (object[validation::Ea]) - { - if (arrhenius.C != 0) - { - std::string line = std::to_string(object[validation::Ea].Mark().line + 1); - std::string column = std::to_string(object[validation::Ea].Mark().column + 1); - errors.push_back({ ConfigParseStatus::MutuallyExclusiveOption, - line + ":" + column + ": Mutually exclusive option: Ea and C" }); - } - arrhenius.C = -1 * object[validation::Ea].as() / constants::boltzmann; - } - - if (object[validation::name]) - { - arrhenius.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : products.second) - { - requested_species.push_back(spec.species_name); - } - for (const auto& spec : reactants.second) - { - requested_species.push_back(spec.species_name); - } - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - arrhenius.gas_phase = gas_phase; - arrhenius.products = products.second; - arrhenius.reactants = reactants.second; - arrhenius.unknown_properties = GetComments(object); - reactions.arrhenius.push_back(arrhenius); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/branched.cpp b/src/v1/reactions/branched.cpp new file mode 100644 index 00000000..34e117dd --- /dev/null +++ b/src/v1/reactions/branched.cpp @@ -0,0 +1,109 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined Branched reaction entry + /// Performs structural (schema) validation only; + /// and collects any errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors BranchedParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { keys::type, + keys::gas_phase, + keys::reactants, + keys::alkoxy_products, + keys::nitrate_products }; + std::vector optional_keys = { + keys::name, keys::X, keys::Y, keys::a0, keys::n + }; + + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Reactants + schema_errors = CheckReactantsOrProductsSchema(object[keys::reactants]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Alkoxy products + schema_errors = CheckReactantsOrProductsSchema(object[keys::alkoxy_products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Nitrate products + schema_errors = CheckReactantsOrProductsSchema(object[keys::nitrate_products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Semantic checks (species existence, phase membership) are performed by the + // version-neutral ValidateSemantics over the canonical Mechanism. + return errors; + } + + void BranchedParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::Branched branched; + + branched.gas_phase = object[keys::gas_phase].as(); + branched.reactants = ParseReactionComponents(object, keys::reactants); + branched.alkoxy_products = ParseReactionComponents(object, keys::alkoxy_products); + branched.nitrate_products = ParseReactionComponents(object, keys::nitrate_products); + branched.unknown_properties = GetComments(object); + + if (object[keys::X]) + { + branched.X = object[keys::X].as(); + } + if (object[keys::Y]) + { + branched.Y = object[keys::Y].as(); + } + if (object[keys::a0]) + { + branched.a0 = object[keys::a0].as(); + } + if (object[keys::n]) + { + branched.n = object[keys::n].as(); + } + if (object[keys::name]) + { + branched.name = object[keys::name].as(); + } + + reactions.branched.emplace_back(std::move(branched)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/branched_parser.cpp b/src/v1/reactions/branched_parser.cpp deleted file mode 100644 index 6d7c8a3e..00000000 --- a/src/v1/reactions/branched_parser.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors BranchedParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::Branched branched; - - std::vector required_keys = { validation::nitrate_products, - validation::alkoxy_products, - validation::reactants, - validation::type, - validation::gas_phase }; - std::vector optional_keys = { - validation::name, validation::X, validation::Y, validation::a0, validation::n - }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto alkoxy_products = ParseReactantsOrProducts(validation::alkoxy_products, object); - errors.insert(errors.end(), alkoxy_products.first.begin(), alkoxy_products.first.end()); - auto nitrate_products = ParseReactantsOrProducts(validation::nitrate_products, object); - errors.insert(errors.end(), nitrate_products.first.begin(), nitrate_products.first.end()); - auto reactants = ParseReactantsOrProducts(validation::reactants, object); - errors.insert(errors.end(), reactants.first.begin(), reactants.first.end()); - - branched.X = object[validation::X].as(); - branched.Y = object[validation::Y].as(); - branched.a0 = object[validation::a0].as(); - branched.n = object[validation::n].as(); - - if (object[validation::name]) - { - branched.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : nitrate_products.second) - { - requested_species.push_back(spec.species_name); - } - for (const auto& spec : alkoxy_products.second) - { - requested_species.push_back(spec.species_name); - } - for (const auto& spec : reactants.second) - { - requested_species.push_back(spec.species_name); - } - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - branched.gas_phase = gas_phase; - branched.nitrate_products = nitrate_products.second; - branched.alkoxy_products = alkoxy_products.second; - branched.reactants = reactants.second; - branched.unknown_properties = GetComments(object); - reactions.branched.push_back(branched); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/emission.cpp b/src/v1/reactions/emission.cpp new file mode 100644 index 00000000..2aecde92 --- /dev/null +++ b/src/v1/reactions/emission.cpp @@ -0,0 +1,75 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined Emission reaction entry. + /// Performs structural (schema) validation only; + /// and collects any errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors EmissionParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { keys::products, keys::type, keys::gas_phase }; + std::vector optional_keys = { keys::name, keys::scaling_factor }; + + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Products + schema_errors = CheckReactantsOrProductsSchema(object[keys::products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Semantic checks (species existence, phase membership) are performed by the + // version-neutral ValidateSemantics over the canonical Mechanism. + return errors; + } + + void EmissionParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::Emission emission; + + emission.gas_phase = object[keys::gas_phase].as(); + emission.products = ParseReactionComponents(object, keys::products); + emission.unknown_properties = GetComments(object); + + if (object[keys::scaling_factor]) + { + emission.scaling_factor = object[keys::scaling_factor].as(); + } + if (object[keys::name]) + { + emission.name = object[keys::name].as(); + } + + reactions.emission.emplace_back(std::move(emission)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/emission_parser.cpp b/src/v1/reactions/emission_parser.cpp deleted file mode 100644 index 3500fdc2..00000000 --- a/src/v1/reactions/emission_parser.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors EmissionParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::Emission emission; - - std::vector required_keys = { validation::products, validation::type, validation::gas_phase }; - std::vector optional_keys = { validation::name, validation::scaling_factor }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto products = ParseReactantsOrProducts(validation::products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - - if (object[validation::scaling_factor]) - { - emission.scaling_factor = object[validation::scaling_factor].as(); - } - - if (object[validation::name]) - { - emission.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : products.second) - { - requested_species.push_back(spec.species_name); - } - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - emission.gas_phase = gas_phase; - emission.products = products.second; - emission.unknown_properties = GetComments(object); - reactions.emission.push_back(emission); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/first_order_loss.cpp b/src/v1/reactions/first_order_loss.cpp new file mode 100644 index 00000000..95e92716 --- /dev/null +++ b/src/v1/reactions/first_order_loss.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined First order loss reaction entry. + /// Performs structural (schema) validation only; + /// and collects any errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors FirstOrderLossParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { keys::reactants, keys::type, keys::gas_phase }; + std::vector optional_keys = { keys::name, keys::scaling_factor, keys::products }; + + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Reactants + schema_errors = CheckReactantsOrProductsSchema(object[keys::reactants]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + if (!errors.empty()) + return errors; + + std::vector> species_node_pairs; + + for (const auto& obj : object[keys::reactants]) + { + types::ReactionComponent component; + component.name = GetReactionComponentName(obj); + species_node_pairs.emplace_back(component, obj); + } + + if (species_node_pairs.size() > 1) + { + const auto& node = object[keys::reactants]; + ErrorLocation error_location{ node.Mark().line, node.Mark().column }; + + std::string message = mc_fmt::format( + "{} error: '{}' reaction requires one reactant, but {} were provided.", + error_location, + object[keys::type].as(), + species_node_pairs.size()); + + errors.push_back({ ErrorCode::TooManyReactionComponents, message }); + } + + // Semantic checks (species existence, phase membership) are performed by the + // version-neutral ValidateSemantics over the canonical Mechanism. + return errors; + } + + void FirstOrderLossParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::FirstOrderLoss first_order_loss; + + first_order_loss.gas_phase = object[keys::gas_phase].as(); + first_order_loss.reactants = ParseReactionComponent(object, keys::reactants); + if (object[keys::products]) + { + first_order_loss.products = ParseReactionComponents(object, keys::products); + } + first_order_loss.unknown_properties = GetComments(object); + + if (object[keys::scaling_factor]) + { + first_order_loss.scaling_factor = object[keys::scaling_factor].as(); + } + if (object[keys::name]) + { + first_order_loss.name = object[keys::name].as(); + } + + reactions.first_order_loss.emplace_back(std::move(first_order_loss)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/first_order_loss_parser.cpp b/src/v1/reactions/first_order_loss_parser.cpp deleted file mode 100644 index 5440c3ab..00000000 --- a/src/v1/reactions/first_order_loss_parser.cpp +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors FirstOrderLossParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::FirstOrderLoss first_order_loss; - - std::vector required_keys = { validation::reactants, validation::type, validation::gas_phase }; - std::vector optional_keys = { validation::name, validation::scaling_factor, validation::products }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto products = ParseReactantsOrProducts(validation::products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - auto reactants = ParseReactantsOrProducts(validation::reactants, object); - errors.insert(errors.end(), reactants.first.begin(), reactants.first.end()); - - if (object[validation::scaling_factor]) - { - first_order_loss.scaling_factor = object[validation::scaling_factor].as(); - } - - if (object[validation::name]) - { - first_order_loss.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : products.second) - { - requested_species.push_back(spec.species_name); - } - for (const auto& spec : reactants.second) - { - requested_species.push_back(spec.species_name); - } - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - if (reactants.second.size() > 1) - { - std::string line = std::to_string(object[validation::reactants].Mark().line + 1); - std::string column = std::to_string(object[validation::reactants].Mark().column + 1); - errors.push_back( - { ConfigParseStatus::TooManyReactionComponents, line + ":" + column + ": Too many reaction components" }); - } - - first_order_loss.gas_phase = gas_phase; - first_order_loss.reactants = reactants.second; - first_order_loss.products = products.second; - first_order_loss.unknown_properties = GetComments(object); - reactions.first_order_loss.push_back(first_order_loss); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/lambda_parser.cpp b/src/v1/reactions/lambda_parser.cpp deleted file mode 100644 index d962be12..00000000 --- a/src/v1/reactions/lambda_parser.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors LambdaRateConstantParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::LambdaRateConstant lambda_rate_constant; - - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase, validation::lambda_function - }; - std::vector optional_keys = { validation::name }; - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto products = ParseReactantsOrProducts(validation::products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - auto reactants = ParseReactantsOrProducts(validation::reactants, object); - errors.insert(errors.end(), reactants.first.begin(), reactants.first.end()); - - lambda_rate_constant.lambda_function = object[validation::lambda_function].as(); - - if (object[validation::name]) - { - lambda_rate_constant.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : products.second) - { - requested_species.push_back(spec.species_name); - } - for (const auto& spec : reactants.second) - { - requested_species.push_back(spec.species_name); - } - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - lambda_rate_constant.gas_phase = gas_phase; - lambda_rate_constant.products = products.second; - lambda_rate_constant.reactants = reactants.second; - lambda_rate_constant.unknown_properties = GetComments(object); - reactions.lambda_rate_constant.push_back(lambda_rate_constant); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/lambda_rate_constant.cpp b/src/v1/reactions/lambda_rate_constant.cpp new file mode 100644 index 00000000..692d1b6e --- /dev/null +++ b/src/v1/reactions/lambda_rate_constant.cpp @@ -0,0 +1,81 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined Lambda Rate Constant reaction entry + /// Performs structural (schema) validation only; + /// and collects any errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors LambdaRateConstantParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { + keys::reactants, keys::products, keys::type, keys::gas_phase, keys::lambda_function + }; + std::vector optional_keys = { keys::name }; + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Reactants + schema_errors = CheckReactantsOrProductsSchema(object[keys::reactants]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Products + schema_errors = CheckReactantsOrProductsSchema(object[keys::products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Semantic checks are performed by the version-neutral ValidateSemantics. + + return errors; + } + + void LambdaRateConstantParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::LambdaRateConstant lambda_rate_constant; + + lambda_rate_constant.reactants = ParseReactionComponents(object, keys::reactants); + lambda_rate_constant.products = ParseReactionComponents(object, keys::products); + lambda_rate_constant.gas_phase = object[keys::gas_phase].as(); + lambda_rate_constant.lambda_function = object[keys::lambda_function].as(); + lambda_rate_constant.unknown_properties = GetComments(object); + + if (object[keys::name]) + { + lambda_rate_constant.name = object[keys::name].as(); + } + + reactions.lambda_rate_constant.emplace_back(std::move(lambda_rate_constant)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/photolysis.cpp b/src/v1/reactions/photolysis.cpp new file mode 100644 index 00000000..7722473d --- /dev/null +++ b/src/v1/reactions/photolysis.cpp @@ -0,0 +1,114 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined Photolysis reaction entry. + /// Performs structural (schema) validation only; + /// and collects any errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors PhotolysisParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { + keys::reactants, keys::products, keys::type, keys::gas_phase + }; + std::vector optional_keys = { keys::name, keys::scaling_factor }; + + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Reactants + schema_errors = CheckReactantsOrProductsSchema(object[keys::reactants]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Products + schema_errors = CheckReactantsOrProductsSchema(object[keys::products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + if (!errors.empty()) + return errors; + + // Reactants must belong to the reaction's phase; products may reference any phase. + std::vector> reactant_node_pairs; + for (const auto& obj : object[keys::reactants]) + { + types::ReactionComponent component; + component.name = GetReactionComponentName(obj); + reactant_node_pairs.emplace_back(component, obj); + } + std::vector> species_node_pairs = reactant_node_pairs; + + // Checks the number of reactants + // This must be done before collecting errors from the products + if (species_node_pairs.size() > 1) + { + const auto& node = object[keys::reactants]; + ErrorLocation error_location{ node.Mark().line, node.Mark().column }; + + std::string message = mc_fmt::format( + "{} error: '{}' reaction requires one reactant, but {} were provided.", + error_location, + object[keys::type].as(), + species_node_pairs.size()); + + errors.push_back({ ErrorCode::TooManyReactionComponents, message }); + } + + // Semantic checks (species existence, phase membership) are performed by the + // version-neutral ValidateSemantics over the canonical Mechanism. + return errors; + } + + void PhotolysisParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::Photolysis photolysis; + + photolysis.gas_phase = object[keys::gas_phase].as(); + photolysis.reactants = ParseReactionComponent(object, keys::reactants); + photolysis.products = ParseReactionComponents(object, keys::products); + photolysis.unknown_properties = GetComments(object); + + if (object[keys::scaling_factor]) + { + photolysis.scaling_factor = object[keys::scaling_factor].as(); + } + if (object[keys::name]) + { + photolysis.name = object[keys::name].as(); + } + + reactions.photolysis.emplace_back(std::move(photolysis)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/photolysis_parser.cpp b/src/v1/reactions/photolysis_parser.cpp deleted file mode 100644 index 077b2c87..00000000 --- a/src/v1/reactions/photolysis_parser.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors PhotolysisParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::Photolysis photolysis; - - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::scaling_factor }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto products = ParseReactantsOrProducts(validation::products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - auto reactants = ParseReactantsOrProducts(validation::reactants, object); - errors.insert(errors.end(), reactants.first.begin(), reactants.first.end()); - - if (object[validation::scaling_factor]) - { - photolysis.scaling_factor = object[validation::scaling_factor].as(); - } - - if (object[validation::name]) - { - photolysis.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : products.second) - { - requested_species.push_back(spec.species_name); - } - for (const auto& spec : reactants.second) - { - requested_species.push_back(spec.species_name); - } - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - if (reactants.second.size() > 1) - { - std::string line = std::to_string(object[validation::reactants].Mark().line + 1); - std::string column = std::to_string(object[validation::reactants].Mark().column + 1); - errors.push_back({ ConfigParseStatus::TooManyReactionComponents, line + ":" + column + ": Too many reactants" }); - } - - photolysis.gas_phase = gas_phase; - photolysis.products = products.second; - photolysis.reactants = reactants.second; - photolysis.unknown_properties = GetComments(object); - reactions.photolysis.push_back(photolysis); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/surface.cpp b/src/v1/reactions/surface.cpp new file mode 100644 index 00000000..e0a12afa --- /dev/null +++ b/src/v1/reactions/surface.cpp @@ -0,0 +1,120 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined Surface reaction entry. + /// Performs structural (schema) validation only; + /// and collects any errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors SurfaceParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { keys::gas_phase_products, + keys::gas_phase_species, + keys::type, + keys::gas_phase }; + std::vector optional_keys = { keys::name, + keys::reaction_probability, + keys::condensed_phase }; + + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Gas phase species reactant + schema_errors = CheckReactantsOrProductsSchema(object[keys::gas_phase_species]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Products + schema_errors = CheckReactantsOrProductsSchema(object[keys::gas_phase_products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + if (!errors.empty()) + return errors; + + // The gas-phase species (reactant) must belong to the reaction's phase; gas-phase + // products may reference any phase, so only the reactant is phase-checked below. + std::vector> reactant_node_pairs; + for (const auto& obj : object[keys::gas_phase_species]) + { + types::ReactionComponent component; + component.name = GetReactionComponentName(obj); + reactant_node_pairs.emplace_back(component, obj); + } + + // Checks the number of reactants + // This must be done before collecting errors from the products + if (reactant_node_pairs.size() > 1) + { + const auto& node = object[keys::gas_phase_species]; + ErrorLocation error_location{ node.Mark().line, node.Mark().column }; + + std::string message = mc_fmt::format( + "{} error: '{}' reaction requires one reactant, but {} were provided.", + error_location, + object[keys::type].as(), + reactant_node_pairs.size()); + + errors.push_back({ ErrorCode::TooManyReactionComponents, message }); + } + + // Semantic checks (species existence, phase membership) are performed by the + // version-neutral ValidateSemantics over the canonical Mechanism. + return errors; + } + void SurfaceParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::Surface surface; + + surface.gas_phase = object[keys::gas_phase].as(); + if (object[keys::condensed_phase]) + { + surface.condensed_phase = object[keys::condensed_phase].as(); + } + surface.gas_phase_species = ParseReactionComponent(object, keys::gas_phase_species); + surface.gas_phase_products = ParseReactionComponents(object, keys::gas_phase_products); + surface.unknown_properties = GetComments(object); + + if (object[keys::reaction_probability]) + { + surface.reaction_probability = object[keys::reaction_probability].as(); + } + if (object[keys::name]) + { + surface.name = object[keys::name].as(); + } + + reactions.surface.emplace_back(std::move(surface)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/surface_parser.cpp b/src/v1/reactions/surface_parser.cpp deleted file mode 100644 index 07603fb2..00000000 --- a/src/v1/reactions/surface_parser.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors SurfaceParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::Surface surface; - - std::vector required_keys = { - validation::gas_phase_products, validation::gas_phase_species, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::reaction_probability }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - std::string gas_phase_species = object[validation::gas_phase_species].as(); - - auto products = ParseReactantsOrProducts(validation::gas_phase_products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - - if (object[validation::reaction_probability]) - { - surface.reaction_probability = object[validation::reaction_probability].as(); - } - - if (object[validation::name]) - { - surface.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : products.second) - { - requested_species.push_back(spec.species_name); - } - requested_species.push_back(gas_phase_species); - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - surface.gas_phase = gas_phase; - surface.gas_phase_products = products.second; - types::ReactionComponent component; - component.species_name = gas_phase_species; - surface.gas_phase_species = component; - surface.unknown_properties = GetComments(object); - reactions.surface.push_back(surface); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/taylor_series.cpp b/src/v1/reactions/taylor_series.cpp new file mode 100644 index 00000000..df8e2867 --- /dev/null +++ b/src/v1/reactions/taylor_series.cpp @@ -0,0 +1,130 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined Taylor Series reaction entry + /// Performs schema validation, checks for mutually exclusive parameters (`Ea` vs `C`), + /// and collects any structural errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors TaylorSeriesParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { + keys::reactants, keys::products, keys::type, keys::gas_phase + }; + std::vector optional_keys = { keys::A, keys::B, + keys::C, keys::D, + keys::E, keys::Ea, + keys::name, keys::taylor_coefficients }; + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Reactants + schema_errors = CheckReactantsOrProductsSchema(object[keys::reactants]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Products + schema_errors = CheckReactantsOrProductsSchema(object[keys::products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + if (object[keys::Ea] && object[keys::C]) + { + const auto& node = object[keys::Ea]; + ErrorLocation error_location{ node.Mark().line, node.Mark().column }; + + std::string message = mc_fmt::format( + "{} error: Mutually exclusive option of 'Ea' and 'C' found in '{}' reaction.", + error_location, + object[keys::type].as()); + + errors.push_back({ ErrorCode::MutuallyExclusiveOption, message }); + } + + // Semantic checks are performed by the version-neutral ValidateSemantics. + + return errors; + } + + /// @brief Parses a YAML-defined Taylor Series reaction and appends it to the reaction list. + /// Extracts reactants, products, kinetic parameters (A–E, Ea), gas phase, + /// optional metadata (name, comments), and constructs a `types::TaylorSeries` object. + /// @param object The YAML node representing the reaction + /// @param reactions The reactions container to append the parsed reaction to + void TaylorSeriesParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::TaylorSeries taylor_series; + + taylor_series.gas_phase = object[keys::gas_phase].as(); + taylor_series.reactants = ParseReactionComponents(object, keys::reactants); + taylor_series.products = ParseReactionComponents(object, keys::products); + taylor_series.unknown_properties = GetComments(object); + + if (object[keys::A]) + { + taylor_series.A = object[keys::A].as(); + } + if (object[keys::B]) + { + taylor_series.B = object[keys::B].as(); + } + if (object[keys::C]) + { + taylor_series.C = object[keys::C].as(); + } + if (object[keys::D]) + { + taylor_series.D = object[keys::D].as(); + } + if (object[keys::E]) + { + taylor_series.E = object[keys::E].as(); + } + if (object[keys::Ea]) + { + taylor_series.C = -1 * object[keys::Ea].as() / constants::boltzmann; + } + if (object[keys::taylor_coefficients]) + { + taylor_series.taylor_coefficients = object[keys::taylor_coefficients].as>(); + } + if (object[keys::name]) + { + taylor_series.name = object[keys::name].as(); + } + + reactions.taylor_series.emplace_back(std::move(taylor_series)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/taylor_series_parser.cpp b/src/v1/reactions/taylor_series_parser.cpp deleted file mode 100644 index 1261d244..00000000 --- a/src/v1/reactions/taylor_series_parser.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors TaylorSeriesParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::TaylorSeries taylor_series; - - std::vector required_keys = { - validation::products, validation::reactants, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::A, - validation::B, - validation::C, - validation::D, - validation::E, - validation::Ea, - validation::taylor_coefficients, - validation::name }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto products = ParseReactantsOrProducts(validation::products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - auto reactants = ParseReactantsOrProducts(validation::reactants, object); - errors.insert(errors.end(), reactants.first.begin(), reactants.first.end()); - - if (object[validation::A]) - { - taylor_series.A = object[validation::A].as(); - } - if (object[validation::B]) - { - taylor_series.B = object[validation::B].as(); - } - if (object[validation::C]) - { - taylor_series.C = object[validation::C].as(); - } - if (object[validation::D]) - { - taylor_series.D = object[validation::D].as(); - } - if (object[validation::E]) - { - taylor_series.E = object[validation::E].as(); - } - if (object[validation::Ea]) - { - if (taylor_series.C != 0) - { - std::string line = std::to_string(object[validation::Ea].Mark().line + 1); - std::string column = std::to_string(object[validation::Ea].Mark().column + 1); - errors.push_back({ ConfigParseStatus::MutuallyExclusiveOption, - line + ":" + column + ": Mutually exclusive option: Ea and C" }); - } - taylor_series.C = -1 * object[validation::Ea].as() / constants::boltzmann; - } - if (object[validation::taylor_coefficients]) - { - taylor_series.taylor_coefficients = object[validation::taylor_coefficients].as>(); - } - - if (object[validation::name]) - { - taylor_series.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : products.second) - { - requested_species.push_back(spec.species_name); - } - for (const auto& spec : reactants.second) - { - requested_species.push_back(spec.species_name); - } - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - taylor_series.gas_phase = gas_phase; - taylor_series.products = products.second; - taylor_series.reactants = reactants.second; - taylor_series.unknown_properties = GetComments(object); - reactions.taylor_series.push_back(taylor_series); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/ternary_chemical_activation.cpp b/src/v1/reactions/ternary_chemical_activation.cpp new file mode 100644 index 00000000..938bb663 --- /dev/null +++ b/src/v1/reactions/ternary_chemical_activation.cpp @@ -0,0 +1,113 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined Ternary ChemicalActivation reaction entry + /// Performs structural (schema) validation only; + /// and collects any errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors TernaryChemicalActivationParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { + keys::reactants, keys::products, keys::type, keys::gas_phase + }; + std::vector optional_keys = { keys::name, keys::k0_A, keys::k0_B, + keys::k0_C, keys::kinf_A, keys::kinf_B, + keys::kinf_C, keys::Fc, keys::N }; + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Reactants + schema_errors = CheckReactantsOrProductsSchema(object[keys::reactants]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Products + schema_errors = CheckReactantsOrProductsSchema(object[keys::products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Semantic checks are performed by the version-neutral ValidateSemantics. + + return errors; + } + + void TernaryChemicalActivationParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::TernaryChemicalActivation ternary; + + ternary.gas_phase = object[keys::gas_phase].as(); + ternary.reactants = ParseReactionComponents(object, keys::reactants); + ternary.products = ParseReactionComponents(object, keys::products); + ternary.unknown_properties = GetComments(object); + + if (object[keys::k0_A]) + { + ternary.k0_A = object[keys::k0_A].as(); + } + if (object[keys::k0_B]) + { + ternary.k0_B = object[keys::k0_B].as(); + } + if (object[keys::k0_C]) + { + ternary.k0_C = object[keys::k0_C].as(); + } + if (object[keys::kinf_A]) + { + ternary.kinf_A = object[keys::kinf_A].as(); + } + if (object[keys::kinf_B]) + { + ternary.kinf_B = object[keys::kinf_B].as(); + } + if (object[keys::kinf_C]) + { + ternary.kinf_C = object[keys::kinf_C].as(); + } + if (object[keys::Fc]) + { + ternary.Fc = object[keys::Fc].as(); + } + if (object[keys::N]) + { + ternary.N = object[keys::N].as(); + } + if (object[keys::name]) + { + ternary.name = object[keys::name].as(); + } + + reactions.ternary_chemical_activation.emplace_back(std::move(ternary)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/ternary_chemical_activation_parser.cpp b/src/v1/reactions/ternary_chemical_activation_parser.cpp deleted file mode 100644 index 218aa2ee..00000000 --- a/src/v1/reactions/ternary_chemical_activation_parser.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors TernaryChemicalActivationParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - - std::vector required_keys = { - validation::products, validation::reactants, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::k0_A, validation::k0_B, - validation::k0_C, validation::kinf_A, validation::kinf_B, - validation::kinf_C, validation::Fc, validation::N }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto products = ParseReactantsOrProducts(validation::products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - auto reactants = ParseReactantsOrProducts(validation::reactants, object); - errors.insert(errors.end(), reactants.first.begin(), reactants.first.end()); - - types::TernaryChemicalActivation parameters; - if (object[validation::k0_A]) - { - parameters.k0_A = object[validation::k0_A].as(); - } - if (object[validation::k0_B]) - { - parameters.k0_B = object[validation::k0_B].as(); - } - if (object[validation::k0_C]) - { - parameters.k0_C = object[validation::k0_C].as(); - } - if (object[validation::kinf_A]) - { - parameters.kinf_A = object[validation::kinf_A].as(); - } - if (object[validation::kinf_B]) - { - parameters.kinf_B = object[validation::kinf_B].as(); - } - if (object[validation::kinf_C]) - { - parameters.kinf_C = object[validation::kinf_C].as(); - } - if (object[validation::Fc]) - { - parameters.Fc = object[validation::Fc].as(); - } - if (object[validation::N]) - { - parameters.N = object[validation::N].as(); - } - - if (object[validation::name]) - { - parameters.name = object[validation::name].as(); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - parameters.gas_phase = gas_phase; - parameters.reactants = reactants.second; - parameters.products = products.second; - parameters.unknown_properties = GetComments(object); - reactions.ternary_chemical_activation.push_back(parameters); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/troe.cpp b/src/v1/reactions/troe.cpp new file mode 100644 index 00000000..bbe59213 --- /dev/null +++ b/src/v1/reactions/troe.cpp @@ -0,0 +1,113 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined Troe reaction entry + /// Performs structural (schema) validation only; + /// and collects any errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors TroeParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { + keys::reactants, keys::products, keys::type, keys::gas_phase + }; + std::vector optional_keys = { keys::name, keys::k0_A, keys::k0_B, + keys::k0_C, keys::kinf_A, keys::kinf_B, + keys::kinf_C, keys::Fc, keys::N }; + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Reactants + schema_errors = CheckReactantsOrProductsSchema(object[keys::reactants]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Products + schema_errors = CheckReactantsOrProductsSchema(object[keys::products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Semantic checks are performed by the version-neutral ValidateSemantics. + + return errors; + } + + void TroeParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::Troe troe; + + troe.gas_phase = object[keys::gas_phase].as(); + troe.reactants = ParseReactionComponents(object, keys::reactants); + troe.products = ParseReactionComponents(object, keys::products); + troe.unknown_properties = GetComments(object); + + if (object[keys::k0_A]) + { + troe.k0_A = object[keys::k0_A].as(); + } + if (object[keys::k0_B]) + { + troe.k0_B = object[keys::k0_B].as(); + } + if (object[keys::k0_C]) + { + troe.k0_C = object[keys::k0_C].as(); + } + if (object[keys::kinf_A]) + { + troe.kinf_A = object[keys::kinf_A].as(); + } + if (object[keys::kinf_B]) + { + troe.kinf_B = object[keys::kinf_B].as(); + } + if (object[keys::kinf_C]) + { + troe.kinf_C = object[keys::kinf_C].as(); + } + if (object[keys::Fc]) + { + troe.Fc = object[keys::Fc].as(); + } + if (object[keys::N]) + { + troe.N = object[keys::N].as(); + } + if (object[keys::name]) + { + troe.name = object[keys::name].as(); + } + + reactions.troe.emplace_back(std::move(troe)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/troe_parser.cpp b/src/v1/reactions/troe_parser.cpp deleted file mode 100644 index 6ebc5df2..00000000 --- a/src/v1/reactions/troe_parser.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors TroeParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::Troe troe; - - std::vector required_keys = { - validation::products, validation::reactants, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::k0_A, validation::k0_B, - validation::k0_C, validation::kinf_A, validation::kinf_B, - validation::kinf_C, validation::Fc, validation::N }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto products = ParseReactantsOrProducts(validation::products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - auto reactants = ParseReactantsOrProducts(validation::reactants, object); - errors.insert(errors.end(), reactants.first.begin(), reactants.first.end()); - - if (object[validation::k0_A]) - { - troe.k0_A = object[validation::k0_A].as(); - } - if (object[validation::k0_B]) - { - troe.k0_B = object[validation::k0_B].as(); - } - if (object[validation::k0_C]) - { - troe.k0_C = object[validation::k0_C].as(); - } - if (object[validation::kinf_A]) - { - troe.kinf_A = object[validation::kinf_A].as(); - } - if (object[validation::kinf_B]) - { - troe.kinf_B = object[validation::kinf_B].as(); - } - if (object[validation::kinf_C]) - { - troe.kinf_C = object[validation::kinf_C].as(); - } - if (object[validation::Fc]) - { - troe.Fc = object[validation::Fc].as(); - } - if (object[validation::N]) - { - troe.N = object[validation::N].as(); - } - - if (object[validation::name]) - { - troe.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : products.second) - { - requested_species.push_back(spec.species_name); - } - for (const auto& spec : reactants.second) - { - requested_species.push_back(spec.species_name); - } - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - troe.gas_phase = gas_phase; - troe.products = products.second; - troe.reactants = reactants.second; - troe.unknown_properties = GetComments(object); - reactions.troe.push_back(troe); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/tunneling.cpp b/src/v1/reactions/tunneling.cpp new file mode 100644 index 00000000..a0608852 --- /dev/null +++ b/src/v1/reactions/tunneling.cpp @@ -0,0 +1,92 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined Tunneling reaction entry + /// Performs structural (schema) validation only; + /// and collects any errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors TunnelingParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { + keys::reactants, keys::products, keys::type, keys::gas_phase + }; + std::vector optional_keys = { keys::name, keys::A, keys::B, keys::C }; + + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Reactants + schema_errors = CheckReactantsOrProductsSchema(object[keys::reactants]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Products + schema_errors = CheckReactantsOrProductsSchema(object[keys::products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Semantic checks are performed by the version-neutral ValidateSemantics. + + return errors; + } + + void TunnelingParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::Tunneling tunneling; + + tunneling.gas_phase = object[keys::gas_phase].as(); + tunneling.reactants = ParseReactionComponents(object, keys::reactants); + tunneling.products = ParseReactionComponents(object, keys::products); + tunneling.unknown_properties = GetComments(object); + + if (object[keys::A]) + { + tunneling.A = object[keys::A].as(); + } + if (object[keys::B]) + { + tunneling.B = object[keys::B].as(); + } + if (object[keys::C]) + { + tunneling.C = object[keys::C].as(); + } + if (object[keys::name]) + { + tunneling.name = object[keys::name].as(); + } + + reactions.tunneling.emplace_back(std::move(tunneling)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/tunneling_parser.cpp b/src/v1/reactions/tunneling_parser.cpp deleted file mode 100644 index 06b2a7ed..00000000 --- a/src/v1/reactions/tunneling_parser.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors TunnelingParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::Tunneling tunneling; - - std::vector required_keys = { - validation::products, validation::reactants, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::A, validation::B, validation::C }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto products = ParseReactantsOrProducts(validation::products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - auto reactants = ParseReactantsOrProducts(validation::reactants, object); - errors.insert(errors.end(), reactants.first.begin(), reactants.first.end()); - - if (object[validation::A]) - { - tunneling.A = object[validation::A].as(); - } - if (object[validation::B]) - { - tunneling.B = object[validation::B].as(); - } - if (object[validation::C]) - { - tunneling.C = object[validation::C].as(); - } - - if (object[validation::name]) - { - tunneling.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : products.second) - { - requested_species.push_back(spec.species_name); - } - for (const auto& spec : reactants.second) - { - requested_species.push_back(spec.species_name); - } - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - tunneling.gas_phase = gas_phase; - tunneling.products = products.second; - tunneling.reactants = reactants.second; - tunneling.unknown_properties = GetComments(object); - reactions.tunneling.push_back(tunneling); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/reactions/user_defined.cpp b/src/v1/reactions/user_defined.cpp new file mode 100644 index 00000000..9418f4d0 --- /dev/null +++ b/src/v1/reactions/user_defined.cpp @@ -0,0 +1,86 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + /// @brief Checks the structural schema of a YAML-defined User-defined reaction entry + /// Performs structural (schema) validation only; + /// and collects any errors found. + /// @param object The YAML node representing the reaction + /// @param existing_species Unused; semantic checks live in ValidateSemantics + /// @param existing_phases Unused; semantic checks live in ValidateSemantics + /// @return A list of validation errors, if any + Errors UserDefinedParser::CheckSchema( + const YAML::Node& object, + const std::vector& existing_species, + const std::vector& existing_phases) + { + std::vector required_keys = { + keys::reactants, keys::products, keys::type, keys::gas_phase + }; + std::vector optional_keys = { keys::name, keys::scaling_factor }; + + Errors errors; + + auto schema_errors = mechanism_configuration::CheckSchema(object, required_keys, optional_keys); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + return errors; + } + + // Reactants + schema_errors = CheckReactantsOrProductsSchema(object[keys::reactants]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Products + schema_errors = CheckReactantsOrProductsSchema(object[keys::products]); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + + // Semantic checks are performed by the version-neutral ValidateSemantics. + + return errors; + } + + void UserDefinedParser::Parse(const YAML::Node& object, types::Reactions& reactions) + { + types::UserDefined user_defined; + + user_defined.reactants = ParseReactionComponents(object, keys::reactants); + user_defined.products = ParseReactionComponents(object, keys::products); + user_defined.gas_phase = object[keys::gas_phase].as(); + user_defined.unknown_properties = GetComments(object); + + if (object[keys::scaling_factor]) + { + user_defined.scaling_factor = object[keys::scaling_factor].as(); + } + + if (object[keys::name]) + { + user_defined.name = object[keys::name].as(); + } + + reactions.user_defined.emplace_back(std::move(user_defined)); + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/reactions/user_defined_parser.cpp b/src/v1/reactions/user_defined_parser.cpp deleted file mode 100644 index 4a6286b9..00000000 --- a/src/v1/reactions/user_defined_parser.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (C) 2023–2026 University Corporation for Atmospheric Research -// University of Illinois at Urbana-Champaign -// SPDX-License-Identifier: Apache-2.0 - -#include -#include -#include -#include -#include -#include - -namespace mechanism_configuration -{ - namespace v1 - { - Errors UserDefinedParser::parse( - const YAML::Node& object, - const std::vector& existing_species, - const std::vector& existing_phases, - types::Reactions& reactions) - { - Errors errors; - types::UserDefined user_defined; - - std::vector required_keys = { - validation::reactants, validation::products, validation::type, validation::gas_phase - }; - std::vector optional_keys = { validation::name, validation::scaling_factor }; - - auto validate = ValidateSchema(object, required_keys, optional_keys); - errors.insert(errors.end(), validate.begin(), validate.end()); - if (validate.empty()) - { - auto products = ParseReactantsOrProducts(validation::products, object); - errors.insert(errors.end(), products.first.begin(), products.first.end()); - auto reactants = ParseReactantsOrProducts(validation::reactants, object); - errors.insert(errors.end(), reactants.first.begin(), reactants.first.end()); - - if (object[validation::scaling_factor]) - { - user_defined.scaling_factor = object[validation::scaling_factor].as(); - } - - if (object[validation::name]) - { - user_defined.name = object[validation::name].as(); - } - - std::vector requested_species; - for (const auto& spec : products.second) - { - requested_species.push_back(spec.species_name); - } - for (const auto& spec : reactants.second) - { - requested_species.push_back(spec.species_name); - } - - std::vector unknown_species = FindUnknownSpecies(requested_species, existing_species); - if (!unknown_species.empty()) - { - std::ostringstream oss; - - std::string line = std::to_string(object.Mark().line + 1); - std::string column = std::to_string(object.Mark().column + 1); - oss << line << ":" << column; - - if (object[validation::name]) - { - oss << " error: Reaction '" << object[validation::name].as() << "' requires unknown species: "; - } - else - { - oss << " error: Reaction requires unknown species: "; - } - - for (size_t i = 0; i < unknown_species.size(); i++) - { - oss << "'" << unknown_species[i] << "'"; - if (i != unknown_species.size() - 1) - { - oss << ", "; - } - } - - errors.push_back({ ConfigParseStatus::ReactionRequiresUnknownSpecies, oss.str() }); - } - - std::string gas_phase = object[validation::gas_phase].as(); - auto it = std::find_if( - existing_phases.begin(), - existing_phases.end(), - [&gas_phase](const auto& phase) { return phase.name == gas_phase; }); - if (it == existing_phases.end()) - { - std::string line = std::to_string(object[validation::gas_phase].Mark().line + 1); - std::string column = std::to_string(object[validation::gas_phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + gas_phase }); - } - - user_defined.gas_phase = gas_phase; - user_defined.products = products.second; - user_defined.reactants = reactants.second; - user_defined.unknown_properties = GetComments(object); - reactions.user_defined.push_back(user_defined); - } - - return errors; - } - } // namespace v1 -} // namespace mechanism_configuration diff --git a/src/v1/type_parsers.cpp b/src/v1/type_parsers.cpp new file mode 100644 index 00000000..19c6e155 --- /dev/null +++ b/src/v1/type_parsers.cpp @@ -0,0 +1,151 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/v1/reaction_parsers.hpp" +#include "detail/v1/type_parsers.hpp" +#include "detail/v1/utils.hpp" +#include "detail/v1/keys.hpp" +#include + +namespace mechanism_configuration +{ + namespace v1 + { + std::vector ParseSpecies(const YAML::Node& objects) + { + std::vector all_species; + for (const auto& object : objects) + { + types::Species species; + + species.name = object[keys::name].as(); + + if (object[keys::tracer_type]) + species.tracer_type = object[keys::tracer_type].as(); + if (object[keys::absolute_tolerance]) + species.absolute_tolerance = object[keys::absolute_tolerance].as(); + if (object[keys::diffusion_coefficient]) + species.diffusion_coefficient = object[keys::diffusion_coefficient].as(); + if (object[keys::molecular_weight]) + species.molecular_weight = object[keys::molecular_weight].as(); + if (object[keys::henrys_law_constant_298]) + species.henrys_law_constant_298 = object[keys::henrys_law_constant_298].as(); + if (object[keys::henrys_law_constant_exponential_factor]) + species.henrys_law_constant_exponential_factor = + object[keys::henrys_law_constant_exponential_factor].as(); + if (object[keys::n_star]) + species.n_star = object[keys::n_star].as(); + if (object[keys::density]) + species.density = object[keys::density].as(); + if (object[keys::constant_concentration]) + species.constant_concentration = object[keys::constant_concentration].as(); + if (object[keys::constant_mixing_ratio]) + species.constant_mixing_ratio = object[keys::constant_mixing_ratio].as(); + if (object[keys::is_third_body]) + species.is_third_body = object[keys::is_third_body].as(); + + species.unknown_properties = GetComments(object); + + all_species.push_back(species); + } + return all_species; + } + + std::vector ParsePhases(const YAML::Node& objects) + { + std::vector all_phases; + for (const auto& object : objects) + { + types::Phase phase; + phase.name = object[keys::name].as(); + + std::vector species; + + for (const auto& spec : object[keys::species]) + { + types::PhaseSpecies phase_species; + + if (spec.IsScalar()) + { + // Shorthand: a bare string is the species name. + phase_species.name = spec.as(); + } + else + { + // Object form: a name plus optional properties. + phase_species.name = spec[keys::name].as(); + if (spec[keys::diffusion_coefficient]) + { + phase_species.diffusion_coefficient = spec[keys::diffusion_coefficient].as(); + } + phase_species.unknown_properties = GetComments(spec); + } + + species.emplace_back(phase_species); + } + + phase.species = species; + phase.unknown_properties = GetComments(object); + all_phases.emplace_back(phase); + } + + return all_phases; + } + + std::vector ParseReactionComponents(const YAML::Node& object, std::string_view key) + { + std::vector component_list; + for (const auto& elem : AsSequence(object[key])) + { + types::ReactionComponent component; + component.name = GetReactionComponentName(elem); + + // A bare-string component carries only its name; coefficients/comments + // are only present on the object form. + if (!elem.IsScalar()) + { + component.unknown_properties = GetComments(elem); + if (elem[keys::coefficient]) + { + component.coefficient = elem[keys::coefficient].as(); + } + } + + component_list.emplace_back(std::move(component)); + } + + return component_list; + }; + + types::ReactionComponent ParseReactionComponent(const YAML::Node& object, std::string_view key) + { + auto reaction_components = ParseReactionComponents(object, key); + + if (reaction_components.empty()) + { + return types::ReactionComponent(); + } + + return std::move(reaction_components.front()); + }; + + types::Reactions ParseReactions(const YAML::Node& objects) + { + auto& parsers = GetReactionParserMap(); + types::Reactions reactions; + + for (const auto& object : objects) + { + auto it = parsers.find(object[keys::type].as()); + if (it != parsers.end()) + { + it->second->Parse(object, reactions); + } + } + + return reactions; + } + + } // namespace v1 +} // namespace mechanism_configuration diff --git a/src/v1/type_schema.cpp b/src/v1/type_schema.cpp new file mode 100644 index 00000000..23d53312 --- /dev/null +++ b/src/v1/type_schema.cpp @@ -0,0 +1,156 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include +#include + +#include "detail/v1/reaction_parsers.hpp" +#include "detail/v1/type_schema.hpp" +#include "detail/v1/utils.hpp" +#include "detail/v1/keys.hpp" +#include "detail/check_schema.hpp" + +#include +#include + +namespace mechanism_configuration +{ + namespace v1 + { + Errors CheckSpeciesSchema(const YAML::Node& species_list) + { + const std::vector required_keys = { keys::name }; + const std::vector optional_keys = { keys::absolute_tolerance, + keys::diffusion_coefficient, + keys::molecular_weight, + keys::henrys_law_constant_298, + keys::henrys_law_constant_exponential_factor, + keys::n_star, + keys::density, + keys::tracer_type, + keys::constant_concentration, + keys::constant_mixing_ratio, + keys::is_third_body }; + // Structural validation only. Duplicate-species detection (a semantic check) is performed + // by the version-neutral ValidateSemantics. + Errors errors; + for (const auto& object : species_list) + { + auto schema_errors = CheckSchema(object, required_keys, optional_keys); + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + return errors; + } + + Errors CheckPhasesSchema(const YAML::Node& phases_list, const std::vector& existing_species) + { + // Phase + const std::vector required_keys = { keys::name, keys::species }; + const std::vector optional_keys = {}; + // PhaseSpecies + const std::vector species_required_keys = { keys::name }; + const std::vector species_optional_keys = { keys::diffusion_coefficient }; + + // Structural validation only. Duplicate detection, phase-species existence, and + // phase-membership (semantic checks) are performed by the version-neutral + // ValidateSemantics. existing_species is intentionally unused here. + (void)existing_species; + Errors errors; + for (const auto& object : AsSequence(phases_list)) + { + auto schema_errors = CheckSchema(object, required_keys, optional_keys); + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + + for (const auto& spec : object[keys::species]) + { + // A bare string is shorthand for a species name and needs no schema validation. + if (spec.IsScalar()) + continue; + auto species_schema_errors = CheckSchema(spec, species_required_keys, species_optional_keys); + errors.insert(errors.end(), species_schema_errors.begin(), species_schema_errors.end()); + } + } + return errors; + } + + Errors CheckReactantsOrProductsSchema(const YAML::Node& list) + { + const std::vector required_keys = {}; + const std::vector optional_keys = { keys::coefficient }; + // A component's species reference may use the canonical `name` or the legacy + // `species name` alias, but exactly one of them. + const std::vector> exactly_one_of = { + { keys::name, keys::species_name } + }; + + Errors errors; + + for (const auto& object : list) + { + auto schema_errors = CheckSchema(object, required_keys, optional_keys, exactly_one_of); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + } + + return errors; + } + + Errors CheckReactionsSchema( + const YAML::Node& reactions_list, + const std::vector& existing_species, + const std::vector& existing_phases) + { + Errors errors; + + auto& parsers = GetReactionParserMap(); + + std::vector> valid_reactions; + + for (const auto& object : reactions_list) + { + if (!object[keys::type]) + { + ErrorLocation error_location{ object.Mark().line, object.Mark().column }; + std::string message = mc_fmt::format("{} error: Missing 'type' object in reaction.", error_location); + errors.push_back({ ErrorCode::RequiredKeyNotFound, message }); + continue; + } + + std::string type = object[keys::type].as(); + + auto it = parsers.find(type); + if (it == parsers.end()) + { + const auto& node = object[keys::type]; + ErrorLocation error_location{ node.Mark().line, node.Mark().column }; + + std::string message = mc_fmt::format("{} error: Unknown reaction type '{}' found.", error_location, type); + + errors.push_back({ ErrorCode::UnknownType, message }); + + continue; + } + valid_reactions.emplace_back(object, it->second.get()); + } + + if (!errors.empty()) + return errors; + + for (const auto& [reaction_node, parser] : valid_reactions) + { + auto schema_errors = parser->CheckSchema(reaction_node, existing_species, existing_phases); + if (!schema_errors.empty()) + { + errors.insert(errors.end(), schema_errors.begin(), schema_errors.end()); + } + } + + return errors; + } + + } // namespace v1 +} // namespace mechanism_configuration \ No newline at end of file diff --git a/src/v1/utils.cpp b/src/v1/utils.cpp index 08ad0cdf..de3f94c0 100644 --- a/src/v1/utils.cpp +++ b/src/v1/utils.cpp @@ -2,14 +2,51 @@ // University of Illinois at Urbana-Champaign // SPDX-License-Identifier: Apache-2.0 -#include -#include -#include +#include +#include + +#include "detail/v1/utils.hpp" +#include "detail/v1/keys.hpp" +#include "detail/check_schema.hpp" + +#include +#include +#include namespace mechanism_configuration { namespace v1 { + YAML::Node AsSequence(const YAML::Node& node) + { + if (node.IsSequence()) + return node; + + YAML::Node sequence; + sequence.push_back(node); + + return sequence; + } + + std::string GetReactionComponentName(const YAML::Node& component) + { + // A component may be given as a bare string (shorthand for its name), + // or as an object keyed by the canonical `name` or the legacy `species name`. + if (component.IsScalar()) + return component.as(); + if (component[keys::name]) + return component[keys::name].as(); + return component[keys::species_name].as(); + } + + void AppendFilePath(const std::string& config_path, Errors& errors) + { + for (auto& error : errors) + { + error.second = config_path + ":" + error.second; + } + } + std::unordered_map GetComments(const YAML::Node& object) { std::unordered_map unknown_properties; @@ -40,16 +77,5 @@ namespace mechanism_configuration return unknown_properties; } - std::vector GetSpeciesNames(const std::vector& phase_species) - { - std::vector names; - names.reserve(phase_species.size()); - for (const auto& species : phase_species) - { - names.push_back(species.name); - } - return names; - } - } // namespace v1 } // namespace mechanism_configuration diff --git a/src/validate.cpp b/src/validate.cpp new file mode 100644 index 00000000..e94572a2 --- /dev/null +++ b/src/validate.cpp @@ -0,0 +1,181 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace mechanism_configuration +{ + namespace + { + // Formats a message, prefixing "line:col error:" when a source location is known. + std::string Message(const std::optional& location, const std::string& body) + { + if (location) + return mc_fmt::format("{} error: {}", *location, body); + return "error: " + body; + } + + // Emits one error per occurrence of each name that appears more than once. + void ReportDuplicates( + const std::vector& refs, + ErrorCode code, + std::string_view what, + Errors& errors) + { + std::unordered_map counts; + for (const auto& ref : refs) + ++counts[ref.name]; + for (const auto& ref : refs) + { + if (counts[ref.name] > 1) + errors.push_back({ code, Message(ref.location, mc_fmt::format("Duplicate {} name '{}' found.", what, ref.name)) }); + } + } + } // namespace + + Errors ValidateSemantics(const semantics::Input& input) + { + Errors errors; + + // ---- Species ---------------------------------------------------------------------------- + std::unordered_set species_names; + for (const auto& s : input.species) + species_names.insert(s.name); + ReportDuplicates(input.species, ErrorCode::DuplicateSpeciesDetected, "species", errors); + + // ---- Phases ----------------------------------------------------------------------------- + std::unordered_map> phase_species; + std::vector phase_names; + for (const auto& phase : input.phases) + { + phase_names.push_back({ phase.name, phase.location }); + auto& registered = phase_species[phase.name]; + for (const auto& ps : phase.species) + { + registered.insert(ps.name); + if (!species_names.contains(ps.name)) + errors.push_back({ ErrorCode::PhaseRequiresUnknownSpecies, + Message(ps.location, mc_fmt::format("Unknown species name '{}' found in '{}' phase.", + ps.name, phase.name)) }); + } + ReportDuplicates(phase.species, ErrorCode::DuplicateSpeciesInPhaseDetected, "species", errors); + } + ReportDuplicates(phase_names, ErrorCode::DuplicatePhasesDetected, "phase", errors); + + // ---- Reactions -------------------------------------------------------------------------- + for (const auto& reaction : input.reactions) + { + const auto phase_it = phase_species.find(reaction.phase); + const bool phase_exists = phase_it != phase_species.end(); + if (!phase_exists) + errors.push_back({ ErrorCode::UnknownPhase, + Message(reaction.location, + mc_fmt::format("Unknown phase '{}' in '{}' reaction.", reaction.phase, reaction.type)) }); + + for (const auto& reactant : reaction.reactants) + { + if (!species_names.contains(reactant.name)) + errors.push_back({ ErrorCode::ReactionRequiresUnknownSpecies, + Message(reactant.location, mc_fmt::format("Unknown species '{}' used in '{}' reaction.", + reactant.name, reaction.type)) }); + else if (phase_exists && !phase_it->second.contains(reactant.name)) + errors.push_back({ ErrorCode::RequestedSpeciesNotRegisteredInPhase, + Message(reactant.location, + mc_fmt::format("Species '{}' used in '{}' is not defined in the '{}' phase.", + reactant.name, reaction.type, reaction.phase)) }); + } + for (const auto& product : reaction.products) + { + if (!species_names.contains(product.name)) + errors.push_back({ ErrorCode::ReactionRequiresUnknownSpecies, + Message(product.location, mc_fmt::format("Unknown species '{}' used in '{}' reaction.", + product.name, reaction.type)) }); + } + } + + return errors; + } + + namespace + { + // Builds a location-free list of component references from a struct component list. + std::vector Refs(const std::vector& components) + { + std::vector refs; + refs.reserve(components.size()); + for (const auto& c : components) + refs.push_back({ c.name, std::nullopt }); + return refs; + } + + semantics::ReactionRef ReactionRefOf( + std::string_view type, + const std::string& phase, + std::vector reactants, + std::vector products) + { + return semantics::ReactionRef{ std::string(type), phase, std::move(reactants), std::move(products), std::nullopt }; + } + } // namespace + + Errors Validate(const Mechanism& mechanism) + { + semantics::Input input; + + for (const auto& s : mechanism.species) + input.species.push_back({ s.name, std::nullopt }); + + for (const auto& phase : mechanism.phases) + { + semantics::PhaseRef pr{ phase.name, {}, std::nullopt }; + for (const auto& ps : phase.species) + pr.species.push_back({ ps.name, std::nullopt }); + input.phases.push_back(std::move(pr)); + } + + const auto& r = mechanism.reactions; + auto add = [&](std::string_view type, const std::string& phase, + std::vector reactants, std::vector products) + { input.reactions.push_back(ReactionRefOf(type, phase, std::move(reactants), std::move(products))); }; + + for (const auto& x : r.arrhenius) + add("ARRHENIUS", x.gas_phase, Refs(x.reactants), Refs(x.products)); + for (const auto& x : r.troe) + add("TROE", x.gas_phase, Refs(x.reactants), Refs(x.products)); + for (const auto& x : r.ternary_chemical_activation) + add("TERNARY_CHEMICAL_ACTIVATION", x.gas_phase, Refs(x.reactants), Refs(x.products)); + for (const auto& x : r.tunneling) + add("TUNNELING", x.gas_phase, Refs(x.reactants), Refs(x.products)); + for (const auto& x : r.taylor_series) + add("TAYLOR_SERIES", x.gas_phase, Refs(x.reactants), Refs(x.products)); + for (const auto& x : r.user_defined) + add("USER_DEFINED", x.gas_phase, Refs(x.reactants), Refs(x.products)); + for (const auto& x : r.lambda_rate_constant) + add("LAMBDA_RATE_CONSTANT", x.gas_phase, Refs(x.reactants), Refs(x.products)); + for (const auto& x : r.emission) + add("EMISSION", x.gas_phase, {}, Refs(x.products)); + for (const auto& x : r.first_order_loss) + add("FIRST_ORDER_LOSS", x.gas_phase, Refs({ x.reactants }), Refs(x.products)); + for (const auto& x : r.photolysis) + add("PHOTOLYSIS", x.gas_phase, Refs({ x.reactants }), Refs(x.products)); + for (const auto& x : r.surface) + add("SURFACE", x.gas_phase, Refs({ x.gas_phase_species }), Refs(x.gas_phase_products)); + for (const auto& x : r.branched) + { + std::vector products = x.alkoxy_products; + products.insert(products.end(), x.nitrate_products.begin(), x.nitrate_products.end()); + add("BRANCHED", x.gas_phase, Refs(x.reactants), Refs(products)); + } + + return ValidateSemantics(input); + } +} // namespace mechanism_configuration diff --git a/src/version.hpp.in b/src/version.hpp.in index 9dcea9fe..5b77108d 100644 --- a/src/version.hpp.in +++ b/src/version.hpp.in @@ -1,3 +1,7 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + // clang-format off #pragma once diff --git a/test/integration/CMakeLists.txt b/test/integration/CMakeLists.txt index f07095ca..a5f00da1 100644 --- a/test/integration/CMakeLists.txt +++ b/test/integration/CMakeLists.txt @@ -10,4 +10,32 @@ create_standard_test(NAME parser SOURCES test_parser.cpp) create_standard_test(NAME v0_parser SOURCES test_v0_parser.cpp) create_standard_test(NAME v1_parser SOURCES test_v1_parser.cpp) create_standard_test(NAME v1_read_from_file_configs SOURCES test_v1_read_from_file_configs.cpp) -create_standard_test(NAME development_parser SOURCES test_development_parser.cpp) + +################################################################################ +# README integration test +# Extract the first ```cpp ... ``` code block from README.md at configure time +# and compile it as a standalone integration test. + +file(READ "${PROJECT_SOURCE_DIR}/README.md" _readme_content) + +string(FIND "${_readme_content}" "```cpp\n" _fence_start) +if(_fence_start EQUAL -1) + message(FATAL_ERROR "README integration test: could not find opening ```cpp fence in README.md") +endif() +math(EXPR _code_start "${_fence_start} + 7") # skip "```cpp\n" (7 chars) +string(SUBSTRING "${_readme_content}" ${_code_start} -1 _after_fence) + +string(FIND "${_after_fence}" "\n```" _fence_end) +if(_fence_end EQUAL -1) + message(FATAL_ERROR "README integration test: could not find closing ``` fence in README.md") +endif() +string(SUBSTRING "${_after_fence}" 0 ${_fence_end} _readme_example_code) + +set(_readme_example_dir "${CMAKE_BINARY_DIR}/readme_example") +set(_readme_example_src "${_readme_example_dir}/main.cpp") +file(MAKE_DIRECTORY "${_readme_example_dir}") +file(WRITE "${_readme_example_src}" "${_readme_example_code}") + +add_executable(test_readme_example "${_readme_example_src}") +target_link_libraries(test_readme_example PUBLIC musica::mechanism_configuration) +add_mech_config_test(readme_example test_readme_example "" "${CMAKE_BINARY_DIR}") diff --git a/test/integration/test_development_parser.cpp b/test/integration/test_development_parser.cpp deleted file mode 100644 index 9e1aae9a..00000000 --- a/test/integration/test_development_parser.cpp +++ /dev/null @@ -1,100 +0,0 @@ -#include -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseDevFullConfig, ParseValidConfig) -{ - development::Parser parser; - - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - std::string path = "examples/development/full_configuration" + extension; - YAML::Node object = parser.FileToYaml(path); - - auto errors = parser.Validate(object); - EXPECT_EQ(errors.size(), 0) << "Validation errors were: " << errors.size(); - - auto mechanism = parser.Parse(object); - - EXPECT_EQ(mechanism.name, "Full Configuration"); - EXPECT_EQ(mechanism.species.size(), 11); - EXPECT_EQ(mechanism.phases.size(), 4); - - EXPECT_EQ(mechanism.models.gas_model.type, "GAS_PHASE"); - EXPECT_EQ(mechanism.models.modal_model.modes.size(), 2); - - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius.size(), 2); - EXPECT_EQ(mechanism.reactions.branched.size(), 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius.size(), 2); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis.size(), 1); - EXPECT_EQ(mechanism.reactions.emission.size(), 1); - EXPECT_EQ(mechanism.reactions.first_order_loss.size(), 1); - EXPECT_EQ(mechanism.reactions.henrys_law.size(), 1); - EXPECT_EQ(mechanism.reactions.photolysis.size(), 1); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer.size(), 1); - EXPECT_EQ(mechanism.reactions.surface.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series.size(), 1); - EXPECT_EQ(mechanism.reactions.ternary_chemical_activation.size(), 1); - EXPECT_EQ(mechanism.reactions.troe.size(), 1); - EXPECT_EQ(mechanism.reactions.tunneling.size(), 1); - EXPECT_EQ(mechanism.reactions.user_defined.size(), 1); - EXPECT_EQ(mechanism.reactions.wet_deposition.size(), 1); - - EXPECT_EQ(mechanism.species[1].constant_concentration.has_value(), true); - EXPECT_EQ(mechanism.species[1].constant_concentration.value(), 1.0e19); - EXPECT_EQ(mechanism.species[2].is_third_body.has_value(), true); - EXPECT_EQ(mechanism.species[2].is_third_body.value(), true); - EXPECT_EQ(mechanism.species[4].constant_mixing_ratio.has_value(), true); - EXPECT_EQ(mechanism.species[4].constant_mixing_ratio.value(), 1.0e-6); - - EXPECT_EQ(mechanism.version.major, 2); - EXPECT_EQ(mechanism.version.minor, 0); - EXPECT_EQ(mechanism.version.patch, 0); - } -} - -TEST(ParseDevFullConfig, ReportsBadFiles) -{ - development::Parser parser; - std::string path = "bad_path.yaml"; - - try - { - YAML::Node object = parser.FileToYaml(path); - FAIL() << "Expected std::runtime_error"; - } - catch (const std::runtime_error& e) - { - std::string error_msg(e.what()); - EXPECT_NE(error_msg.find("does not exist or is not a regular file"), std::string::npos) - << "Error message was: " << error_msg; - - std::cout << error_msg << std::endl; - } -} - -TEST(ParseDevFullConfig, ReportsDirectory) -{ - development::Parser parser; - std::string path = "examples/"; - - try - { - YAML::Node object = parser.FileToYaml(path); - FAIL() << "Expected std::runtime_error"; - } - catch (const std::runtime_error& e) - { - std::string error_msg(e.what()); - EXPECT_NE(error_msg.find("does not exist or is not a regular file"), std::string::npos) - << "Error message was: " << error_msg; - - std::cout << error_msg << std::endl; - } -} diff --git a/test/integration/test_parser.cpp b/test/integration/test_parser.cpp index 9daf78ef..a6cb717e 100644 --- a/test/integration/test_parser.cpp +++ b/test/integration/test_parser.cpp @@ -1,124 +1,73 @@ -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include -TEST(UniversalParser, ConfigurationWithoutVersionFallsbackToV0) -{ - mechanism_configuration::UniversalParser parser; - std::vector extensions = { ".yaml", ".json" }; - for (auto& extension : extensions) - { - std::string path = "examples/v0/config" + extension; - auto parsed = parser.Parse(path); - EXPECT_TRUE(parsed); +#include +#include +#include - EXPECT_EQ(parsed.mechanism->version.major, 0); - EXPECT_EQ(parsed.mechanism->version.minor, 0); - EXPECT_EQ(parsed.mechanism->version.patch, 0); - } -} +using namespace mechanism_configuration; -TEST(UniversalParser, ParsesFullV1Configuration) +TEST(Parse, ConfigurationWithoutVersionFallsBackToV0) { - mechanism_configuration::UniversalParser parser; - std::vector extensions = { ".json", ".yaml" }; - for (auto& extension : extensions) + for (const auto& extension : { std::string(".yaml"), std::string(".json") }) { - std::string path = "examples/v1/full_configuration" + extension; - auto parsed = parser.Parse(path); - if (!parsed) - { - std::cout << "Errors: " << std::endl; - for (const auto& error : parsed.errors) - { - std::cout << error.second << std::endl; - } - } + auto parsed = Parse("examples/v0/config" + extension); EXPECT_TRUE(parsed); - - EXPECT_EQ(parsed.mechanism->version.major, 1); - EXPECT_EQ(parsed.mechanism->version.minor, 0); - EXPECT_EQ(parsed.mechanism->version.patch, 0); + if (parsed) + EXPECT_EQ(parsed->version.major, 0); } } -TEST(UniversalParser, ParsesFullDevConfiguration) +TEST(Parse, ParsesFullV1Configuration) { - mechanism_configuration::UniversalParser parser; - std::vector extensions = { ".json", ".yaml" }; - for (auto& extension : extensions) + for (const auto& extension : { std::string(".json"), std::string(".yaml") }) { - std::string path = "examples/development/full_configuration" + extension; - auto parsed = parser.Parse(path); + auto parsed = Parse("examples/v1/full_configuration" + extension); if (!parsed) - { - std::cout << "Errors: " << std::endl; - for (const auto& error : parsed.errors) - { - std::cout << error.second << std::endl; - } - } + for (const auto& [code, message] : parsed.error()) + std::cout << message << std::endl; EXPECT_TRUE(parsed); - - EXPECT_EQ(parsed.mechanism->version.major, 2); - EXPECT_EQ(parsed.mechanism->version.minor, 0); - EXPECT_EQ(parsed.mechanism->version.patch, 0); + if (parsed) + EXPECT_EQ(parsed->version.major, 1); } } -TEST(UniversalParser, ParserReportsBadFiles) +TEST(Parse, ReportsMissingFile) { - mechanism_configuration::UniversalParser parser; - std::vector extensions = { ".yaml", ".json" }; - for (auto& extension : extensions) + for (const auto& extension : { std::string(".yaml"), std::string(".json") }) { - std::string path = "examples/_missing_configuration" + extension; - auto parsed = parser.Parse(path); + auto parsed = Parse("examples/_missing_configuration" + extension); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, mechanism_configuration::ConfigParseStatus::FileNotFound); + ASSERT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::FileNotFound); } } -TEST(UniversalParser, ParseUnsupportedVersion) +TEST(Parse, ReportsUnsupportedVersion) { - using namespace mechanism_configuration; + auto parsed = Parse("integration_configs/invalid_version.yaml"); + EXPECT_FALSE(parsed); - UniversalParser parser; - auto parsed = parser.Parse("integration_configs/invalid_version.yaml"); - EXPECT_EQ(parsed.errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::InvalidVersion }; - std::multiset actual; - for (const auto& [status, message] : parsed.errors) + bool found_invalid_version = false; + for (const auto& [code, message] : parsed.error()) { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; + if (code == ErrorCode::InvalidVersion) + found_invalid_version = true; + std::cout << message << " " << ErrorCodeToString(code) << std::endl; } - EXPECT_EQ(actual, expected); + EXPECT_TRUE(found_invalid_version); } -TEST(UniversalParser, ParsesV0DirectoryConfiguration) +TEST(Parse, ParsesV0DirectoryConfiguration) { - // Test that v0 parser can handle directory-based configurations - mechanism_configuration::UniversalParser parser; - - std::string directory_path = "examples/v0/"; - auto parsed = parser.Parse(directory_path); + // A directory is treated as a version-0 (CAMP) configuration. + auto parsed = Parse(std::filesystem::path("examples/v0/")); EXPECT_TRUE(parsed); - EXPECT_EQ(parsed.mechanism->version.major, 0); - EXPECT_EQ(parsed.mechanism->version.minor, 0); - EXPECT_EQ(parsed.mechanism->version.patch, 0); + if (parsed) + EXPECT_EQ(parsed->version.major, 0); } - -TEST(UniversalParser, RejectsDirectoryForV1Configuration) -{ - // Test v1 and upper version parsers do not accept directories - // V0 parser will attempt to parse a directory, but if the directory - // contains higher version files, it should throw an exception - mechanism_configuration::UniversalParser parser; - - std::string directory_path = "examples/v1"; - EXPECT_THROW({ auto parsed = parser.Parse(directory_path); }, std::exception); -} \ No newline at end of file diff --git a/test/integration/test_v0_parser.cpp b/test/integration/test_v0_parser.cpp index 1e709e1b..9ff1b36f 100644 --- a/test/integration/test_v0_parser.cpp +++ b/test/integration/test_v0_parser.cpp @@ -1,21 +1,25 @@ -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/v0/parser.hpp" #include +#include +#include + using namespace mechanism_configuration; -TEST(ParserBase, ParsesFullv0Configuration) +TEST(V0Parser, ParsesFullV0Configuration) { v0::Parser parser; - std::vector extensions = { ".yaml", ".json" }; - for (auto& extension : extensions) + for (const auto& extension : { std::string(".yaml"), std::string(".json") }) { - std::string path = "examples/v0/config" + extension; - auto parsed = parser.Parse(path); - EXPECT_TRUE(parsed); + auto parsed = parser.Parse("examples/v0/config" + extension); + ASSERT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.user_defined.size(), 4); EXPECT_EQ(mechanism.reactions.arrhenius.size(), 1); EXPECT_EQ(mechanism.reactions.troe.size(), 1); @@ -25,23 +29,17 @@ TEST(ParserBase, ParsesFullv0Configuration) EXPECT_EQ(mechanism.reactions.surface.size(), 1); EXPECT_EQ(mechanism.version.major, 0); - EXPECT_EQ(mechanism.version.minor, 0); - EXPECT_EQ(mechanism.version.patch, 0); } } -TEST(ParserBase, ConfigPathIsDirectory) +TEST(V0Parser, ConfigPathIsDirectory) { v0::Parser parser; - std::string path = "examples/v0"; - auto parsed = parser.Parse(path); - EXPECT_TRUE(parsed); + auto parsed = parser.Parse(std::filesystem::path("examples/v0")); + ASSERT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.version.major, 0); - EXPECT_EQ(mechanism.version.minor, 0); - EXPECT_EQ(mechanism.version.patch, 0); - EXPECT_EQ(mechanism.reactions.user_defined.size(), 4); EXPECT_EQ(mechanism.reactions.arrhenius.size(), 1); EXPECT_EQ(mechanism.reactions.troe.size(), 1); @@ -51,16 +49,14 @@ TEST(ParserBase, ConfigPathIsDirectory) EXPECT_EQ(mechanism.reactions.surface.size(), 1); } -TEST(ParserBase, ParserReportsBadFiles) +TEST(V0Parser, ReportsMissingFile) { v0::Parser parser; - std::vector extensions = { ".yaml", ".json" }; - for (auto& extension : extensions) + for (const auto& extension : { std::string(".yaml"), std::string(".json") }) { - std::string path = "examples/_missing_configuration" + extension; - auto parsed = parser.Parse(path); + auto parsed = parser.Parse("examples/_missing_configuration" + extension); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::FileNotFound); + ASSERT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::FileNotFound); } } diff --git a/test/integration/test_v1_parser.cpp b/test/integration/test_v1_parser.cpp index 1e16d985..fe7658aa 100644 --- a/test/integration/test_v1_parser.cpp +++ b/test/integration/test_v1_parser.cpp @@ -1,78 +1,27 @@ -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include +#include "detail/v1/parser.hpp" #include #include -using namespace mechanism_configuration; - -TEST(ParserBase, ParsesFullV1Configuration) -{ - v1::Parser parser; - std::vector extensions = { ".json" }; - for (auto& extension : extensions) - { - std::string path = "examples/v1/full_configuration" + extension; - auto parsed = parser.Parse(path); - EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; - EXPECT_EQ(mechanism.name, "Full Configuration"); - EXPECT_EQ(mechanism.species.size(), 7); - EXPECT_EQ(mechanism.phases.size(), 1); +#include +#include - EXPECT_EQ(mechanism.reactions.arrhenius.size(), 2); - EXPECT_EQ(mechanism.reactions.branched.size(), 1); - EXPECT_EQ(mechanism.reactions.emission.size(), 1); - EXPECT_EQ(mechanism.reactions.first_order_loss.size(), 1); - EXPECT_EQ(mechanism.reactions.photolysis.size(), 1); - EXPECT_EQ(mechanism.reactions.surface.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series.size(), 1); - EXPECT_EQ(mechanism.reactions.troe.size(), 1); - EXPECT_EQ(mechanism.reactions.ternary_chemical_activation.size(), 1); - EXPECT_EQ(mechanism.reactions.tunneling.size(), 1); - EXPECT_EQ(mechanism.reactions.user_defined.size(), 1); - - EXPECT_EQ(mechanism.species[1].constant_concentration.has_value(), true); - EXPECT_EQ(mechanism.species[1].constant_concentration.value(), 1.0e19); - EXPECT_EQ(mechanism.species[2].constant_mixing_ratio.has_value(), true); - EXPECT_EQ(mechanism.species[2].constant_mixing_ratio.value(), 1.0e-20); - EXPECT_EQ(mechanism.species[3].is_third_body.has_value(), true); - EXPECT_EQ(mechanism.species[3].is_third_body.value(), true); - - EXPECT_EQ(mechanism.version.major, 1); - EXPECT_EQ(mechanism.version.minor, 0); - EXPECT_EQ(mechanism.version.patch, 0); - } -} +using namespace mechanism_configuration; -TEST(ParserBase, ParserReportsBadFiles) +namespace { - v1::Parser parser; - std::vector extensions = { ".yaml", ".json" }; - for (auto& extension : extensions) + // Parses an in-memory v1 document through the engine (validate, then build). + std::expected ParseString(const std::string& content) { - std::string path = "examples/_missing_configuration" + extension; - auto parsed = parser.Parse(path); - EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::FileNotFound); + return v1::Parser{}.Parse(content); } -} -TEST(ParserBase, ParserReportsDirectory) -{ - v1::Parser parser; - std::string path = "examples/"; - auto parsed = parser.Parse(path); - EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::FileNotFound); -} - -TEST(ParserBase, CanParseFromYamlString) -{ - v1::Parser parser; - std::string content = R"( + const std::string kYamlConfig = R"( version: 1.0.0 name: Simple Configuration species: @@ -87,11 +36,6 @@ name: Simple Configuration - type: ARRHENIUS name: my arrhenius gas phase: gas - A: 32.1 - B: -2.3 - C: 102.3 - D: 63.4 - E: -1.3 reactants: - species name: A coefficient: 1 @@ -99,128 +43,79 @@ name: Simple Configuration - species name: B coefficient: 1 )"; +} // namespace - auto parsed = parser.ParseFromString(content); - EXPECT_TRUE(parsed); +TEST(V1Parser, ParsesFullV1Configuration) +{ + auto parsed = Parse("examples/v1/full_configuration.json"); if (!parsed) - { - for (const auto& error : parsed.errors) - { - std::cerr << "Error: " << configParseStatusToString(error.first) << " - " << error.second << std::endl; - } - } - v1::types::Mechanism mechanism = *parsed; - EXPECT_EQ(mechanism.name, "Simple Configuration"); - EXPECT_EQ(mechanism.species.size(), 2); + for (const auto& [code, message] : parsed.error()) + std::cout << message << std::endl; + ASSERT_TRUE(parsed); + + const Mechanism& mechanism = *parsed; + EXPECT_EQ(mechanism.name, "Full Configuration"); + EXPECT_EQ(mechanism.species.size(), 7); EXPECT_EQ(mechanism.phases.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius.size(), 1); + + EXPECT_EQ(mechanism.reactions.arrhenius.size(), 2); + EXPECT_EQ(mechanism.reactions.branched.size(), 1); + EXPECT_EQ(mechanism.reactions.emission.size(), 1); + EXPECT_EQ(mechanism.reactions.first_order_loss.size(), 1); + EXPECT_EQ(mechanism.reactions.photolysis.size(), 1); + EXPECT_EQ(mechanism.reactions.surface.size(), 1); + EXPECT_EQ(mechanism.reactions.taylor_series.size(), 1); + EXPECT_EQ(mechanism.reactions.troe.size(), 1); + EXPECT_EQ(mechanism.reactions.ternary_chemical_activation.size(), 1); + EXPECT_EQ(mechanism.reactions.tunneling.size(), 1); + EXPECT_EQ(mechanism.reactions.user_defined.size(), 1); + EXPECT_EQ(mechanism.version.major, 1); - EXPECT_EQ(mechanism.version.minor, 0); - EXPECT_EQ(mechanism.version.patch, 0); } -TEST(ParserBase, CanParseFromJsonString) +TEST(V1Parser, ReportsMissingFile) { - v1::Parser parser; - std::string content = R"({ + for (const auto& extension : { std::string(".yaml"), std::string(".json") }) + { + auto parsed = Parse("examples/_missing_configuration" + extension); + EXPECT_FALSE(parsed); + ASSERT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::FileNotFound); + } +} + +TEST(V1Parser, CanParseFromYamlString) +{ + auto parsed = ParseString(kYamlConfig); + ASSERT_TRUE(parsed); + EXPECT_EQ(parsed->name, "Simple Configuration"); + EXPECT_EQ(parsed->species.size(), 2); + EXPECT_EQ(parsed->phases.size(), 1); + EXPECT_EQ(parsed->reactions.arrhenius.size(), 1); + EXPECT_EQ(parsed->version.major, 1); +} + +TEST(V1Parser, CanParseFromJsonString) +{ + const std::string content = R"({ "version": "1.0.0", "name": "Simple Configuration", - "species": [ - { "name": "A" }, - { "name": "B" } - ], - "phases": [ - { - "name": "gas", - "species": [ {"name": "A"}, {"name": "B"} ] - } - ], + "species": [ { "name": "A" }, { "name": "B" } ], + "phases": [ { "name": "gas", "species": [ {"name": "A"}, {"name": "B"} ] } ], "reactions": [ { "type": "ARRHENIUS", "name": "my arrhenius", "gas phase": "gas", - "A": 32.1, - "B": -2.3, - "C": 102.3, - "D": 63.4, - "E": -1.3, - "reactants": [ - { - "species name": "A", - "coefficient": 1 - } - ], - "products": [ - { - "species name": "B", - "coefficient": 1 - } - ] + "reactants": [ { "species name": "A", "coefficient": 1 } ], + "products": [ { "species name": "B", "coefficient": 1 } ] } ] })"; - - auto parsed = parser.ParseFromString(content); - EXPECT_TRUE(parsed); - if (!parsed) - { - for (const auto& error : parsed.errors) - { - std::cerr << "Error: " << configParseStatusToString(error.first) << " - " << error.second << std::endl; - } - } - v1::types::Mechanism mechanism = *parsed; - EXPECT_EQ(mechanism.name, "Simple Configuration"); - EXPECT_EQ(mechanism.species.size(), 2); - EXPECT_EQ(mechanism.phases.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius.size(), 1); - EXPECT_EQ(mechanism.version.major, 1); - EXPECT_EQ(mechanism.version.minor, 0); - EXPECT_EQ(mechanism.version.patch, 0); + auto parsed = ParseString(content); + ASSERT_TRUE(parsed); + EXPECT_EQ(parsed->name, "Simple Configuration"); + EXPECT_EQ(parsed->species.size(), 2); + EXPECT_EQ(parsed->reactions.arrhenius.size(), 1); + EXPECT_EQ(parsed->version.major, 1); } - -TEST(ParserBase, CanParseFromYamlNode) -{ - v1::Parser parser; - std::string content = R"( -version: 1.0.0 -name: Simple Configuration -species: - - name: A - - name: B -phases: - - name: gas - species: - - A - - B -reactions: - - type: ARRHENIUS - name: my arrhenius - gas phase: gas - A: 32.1 - B: -2.3 - C: 102.3 - D: 63.4 - E: -1.3 - reactants: - - species name: A - coefficient: 1 - products: - - species name: B - coefficient: 1 -)"; - - YAML::Node node = YAML::Load(content); - - auto parsed = parser.ParseFromNode(node); - EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; - EXPECT_EQ(mechanism.name, "Simple Configuration"); - EXPECT_EQ(mechanism.species.size(), 2); - EXPECT_EQ(mechanism.phases.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius.size(), 1); - EXPECT_EQ(mechanism.version.major, 1); - EXPECT_EQ(mechanism.version.minor, 0); - EXPECT_EQ(mechanism.version.patch, 0); -} \ No newline at end of file diff --git a/test/integration/test_v1_read_from_file_configs.cpp b/test/integration/test_v1_read_from_file_configs.cpp index 3a5a854d..2fca069e 100644 --- a/test/integration/test_v1_read_from_file_configs.cpp +++ b/test/integration/test_v1_read_from_file_configs.cpp @@ -1,44 +1,41 @@ -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include -#include #include #include -#include using namespace mechanism_configuration; -TEST(ParserBase, ParsesFullV1Configuration) +// A v1.1+ configuration may be split across multiple files via `{ files: [...] }`; +// Parse() resolves and merges them into one mechanism. +TEST(V1FileConfigs, ParsesMultiFileConfiguration) { - v1::Parser parser; - std::vector extensions = { "/json/main.json", "/yaml/main.yaml" }; - for (auto& extension : extensions) + for (const auto& main : { std::string("examples/v1/config/json/main.json"), + std::string("examples/v1/config/yaml/main.yaml") }) { - std::string path = "examples/v1/config" + extension; - auto parsed = parser.Parse(path); - for (const auto& error : parsed.errors) - std::cout << "[" << configParseStatusToString(error.first) << "] " << error.second << "\n"; + auto parsed = Parse(main); + if (!parsed) + for (const auto& [code, message] : parsed.error()) + std::cout << "[" << ErrorCodeToString(code) << "] " << message << "\n"; ASSERT_TRUE(parsed); - auto& mechanism = *parsed; - + const Mechanism& mechanism = *parsed; EXPECT_EQ(mechanism.name, "troposphere and stratosphere configs"); - // species: A, B, C ASSERT_EQ(mechanism.species.size(), 3); EXPECT_EQ(mechanism.species[0].name, "A"); EXPECT_EQ(mechanism.species[1].name, "B"); EXPECT_EQ(mechanism.species[2].name, "C"); - // phases: one gas phase with 3 species ASSERT_EQ(mechanism.phases.size(), 1); EXPECT_EQ(mechanism.phases[0].name, "gas"); ASSERT_EQ(mechanism.phases[0].species.size(), 3); - // reactions: 3 from troposphere + 3 from stratosphere = 6 arrhenius EXPECT_EQ(mechanism.reactions.arrhenius.size(), 6); } -} \ No newline at end of file +} diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 87110d74..c7386c03 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -1,3 +1,4 @@ +create_standard_test(NAME validate SOURCES test_validate.cpp) + add_subdirectory(v0) add_subdirectory(v1) -add_subdirectory(development) \ No newline at end of file diff --git a/test/unit/development/CMakeLists.txt b/test/unit/development/CMakeLists.txt deleted file mode 100644 index 30ffc98e..00000000 --- a/test/unit/development/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -################################################################################ -# Tests - -create_standard_test(NAME development_parse_phases SOURCES test_parse_phases.cpp) -create_standard_test(NAME development_parse_species SOURCES test_parse_species.cpp) - -################################################################################ -# Copy test data - -add_custom_target(copy_development_unit_test_configs ALL ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/development_unit_configs ${CMAKE_BINARY_DIR}/development_unit_configs) - -################################################################################ - -add_subdirectory(models) -add_subdirectory(reactions) \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/models/gas/gas_phase_not_found_in_phases.json b/test/unit/development/development_unit_configs/models/gas/gas_phase_not_found_in_phases.json deleted file mode 100644 index 70193719..00000000 --- a/test/unit/development/development_unit_configs/models/gas/gas_phase_not_found_in_phases.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "version": "2.0.0", - "name": "Gas phase not found in the initialized phases", - "species": [ - { - "name": "SO2" - }, - { - "name": "H2O2" - }, - { - "name": "O3" - }, - { - "name": "H2O" - }, - { - "name": "SO4" - } - ], - "phases": [ - { - "name": "gaseous_phase", - "species": [ - { - "name": "SO2" - }, - { - "name": "O3" - } - ] - }, - { - "name": "organic", - "species": [ - { - "name": "SO4" - }, - { - "name": "H2O2" - }, - { - "name": "H2O" - } - ] - } - ], - "models": [ - { - "name": "gas", - "type": "GAS_PHASE", - "phase": "gas" - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gaseous phase", - "species": [ - { - "name": "SO2", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "organic", - "solutes": [ - { - "name": "SO4", - "coefficient": 1.0 - }, - { - "name": "H2O2", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O", - "coefficient": 1.0 - } - ] - }, - "__comment": "comment" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/models/gas/gas_phase_not_found_in_phases.yaml b/test/unit/development/development_unit_configs/models/gas/gas_phase_not_found_in_phases.yaml deleted file mode 100644 index f5884833..00000000 --- a/test/unit/development/development_unit_configs/models/gas/gas_phase_not_found_in_phases.yaml +++ /dev/null @@ -1,47 +0,0 @@ -version: 2.0.0 -name: Gas phase not found in the initialized phases - -species: - - name: SO2 - - name: H2O2 - - name: O3 - - name: H2O - - name: SO4 - -phases: - - name: gaseous_phase - species: - - name: SO2 - - name: O3 - - name: organic - species: - - name: SO4 - - name: H2O2 - - name: H2O - -models: - - name: gas - type: GAS_PHASE - phase: gas - -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gaseous phase - species: - - name: SO2 - diffusion coefficient [m2 s-1]: 0.7 - - particle: - phase: organic - solutes: - - name: SO4 - coefficient: 1.0 - - name: H2O2 - coefficient: 1.0 - - solvent: - - name: H2O - coefficient: 1.0 - - __comment: comment diff --git a/test/unit/development/development_unit_configs/models/gas/missing_phase.json b/test/unit/development/development_unit_configs/models/gas/missing_phase.json deleted file mode 100644 index a22bdf57..00000000 --- a/test/unit/development/development_unit_configs/models/gas/missing_phase.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase in gas model", - "species": [ - { - "name": "SO2" - }, - { - "name": "H2O2" - }, - { - "name": "O3" - }, - { - "name": "H2O" - }, - { - "name": "SO4" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "SO2" - }, - { - "name": "O3" - } - ] - }, - { - "name": "organic", - "species": [ - { - "name": "SO4" - }, - { - "name": "H2O2" - }, - { - "name": "H2O" - } - ] - } - ], - "models": [ - { - "name": "gas", - "type": "GAS_PHASE" - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "SO2", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "organic", - "solutes": [ - { - "name": "SO4", - "coefficient": 1.0 - }, - { - "name": "H2O2", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O", - "coefficient": 1.0 - } - ] - }, - "__comment": "comment" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/models/gas/missing_phase.yaml b/test/unit/development/development_unit_configs/models/gas/missing_phase.yaml deleted file mode 100644 index 5ee5b01d..00000000 --- a/test/unit/development/development_unit_configs/models/gas/missing_phase.yaml +++ /dev/null @@ -1,46 +0,0 @@ -version: 2.0.0 -name: Missing phase in gas model - -species: - - name: SO2 - - name: H2O2 - - name: O3 - - name: H2O - - name: SO4 - -phases: - - name: gas - species: - - name: SO2 - - name: O3 - - name: organic - species: - - name: SO4 - - name: H2O2 - - name: H2O - -models: - - name: gas - type: GAS_PHASE - -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: SO2 - diffusion coefficient [m2 s-1]: 0.7 - - particle: - phase: organic - solutes: - - name: SO4 - coefficient: 1.0 - - name: H2O2 - coefficient: 1.0 - - solvent: - - name: H2O - coefficient: 1.0 - - __comment: comment diff --git a/test/unit/development/development_unit_configs/models/gas/valid.json b/test/unit/development/development_unit_configs/models/gas/valid.json deleted file mode 100644 index ede495bc..00000000 --- a/test/unit/development/development_unit_configs/models/gas/valid.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "version": "2.0.0", - "name": "Gas model", - "species": [ - { - "name": "SO2" - }, - { - "name": "H2O2" - }, - { - "name": "O3" - }, - { - "name": "H2O" - }, - { - "name": "SO4" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "SO2" - }, - { - "name": "O3" - } - ] - }, - { - "name": "organic", - "species": [ - { - "name": "SO4" - }, - { - "name": "H2O2" - }, - { - "name": "H2O" - } - ] - } - ], - "models": [ - { - "name": "gas", - "type": "GAS_PHASE", - "phase": "gas" - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "SO2", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "organic", - "solutes": [ - { - "name": "SO4", - "coefficient": 1.0 - }, - { - "name": "H2O2", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O", - "coefficient": 1.0 - } - ] - }, - "__comment": "comment" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/models/gas/valid.yaml b/test/unit/development/development_unit_configs/models/gas/valid.yaml deleted file mode 100644 index 6b7dde5e..00000000 --- a/test/unit/development/development_unit_configs/models/gas/valid.yaml +++ /dev/null @@ -1,48 +0,0 @@ -version: 2.0.0 -name: Gas model - -species: - - name: SO2 - - name: H2O2 - - name: O3 - - name: H2O - - name: SO4 - -phases: - - name: gas - species: - - name: SO2 - - name: O3 - - - name: organic - species: - - name: SO4 - - name: H2O2 - - name: H2O - -models: - - name: gas - type: GAS_PHASE - phase: gas - -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: SO2 - diffusion coefficient [m2 s-1]: 0.7 - - particle: - phase: organic - solutes: - - name: SO4 - coefficient: 1.0 - - name: H2O2 - coefficient: 1.0 - - solvent: - - name: H2O - coefficient: 1.0 - - __comment: comment diff --git a/test/unit/development/development_unit_configs/models/modal/missing_modal_variable.json b/test/unit/development/development_unit_configs/models/modal/missing_modal_variable.json deleted file mode 100644 index 2806eaf7..00000000 --- a/test/unit/development/development_unit_configs/models/modal/missing_modal_variable.json +++ /dev/null @@ -1,184 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing modal member variable", - "species": [ - { - "name": "SO2", - "molecular weight [kg mol-1]": 0.06407, - "density [kg m-3]": 2.628, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "H2O2", - "HLC(298K) [mol m-3 Pa-1]": 1.011596348, - "HLC exponential factor [K]": 6340, - "diffusion coefficient [m2 s-1]": 1.46E-05, - "N star": 1.74, - "molecular weight [kg mol-1]": 0.0340147, - "density [kg m-3]": 1000.0, - "__absolute tolerance": 1.0e-10 - }, - { - "name": "O3", - "molecular weight [kg mol-1]": 0.0479982, - "density [kg m-3]": 2.144, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "H2O", - "molecular weight [kg mol-1]": 0.01801528, - "density [kg m-3]": 997.0, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "H2SO4", - "molecular weight [kg mol-1]": 0.098079, - "density [kg m-3]": 1830.0, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "SO4", - "molecular weight [kg mol-1]": 0.09606, - "density [kg m-3]": 1769.0, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "organic carbon", - "molecular weight [kg mol-1]": 0.150, - "density [kg m-3]": 1200, - "__absolute tolerance": 1.0e-20 - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "SO2" - }, - { - "name": "H2O2" - }, - { - "name": "H2SO4" - }, - { - "name": "O3" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "SO4" - }, - { - "name": "H2O2" - }, - { - "name": "H2SO4" - }, - { - "name": "H2O" - }, - { - "name": "O3" - } - ] - } - ], - "models": [ - { - "name": "aqueous", - "type": "MODAL", - "modes": [ - { - "name": "aitken", - "geometric mean diameter [m]": 2.6e-8, - "phase": "aqueous", - "__comment": "Aitken mode" - }, - { - "name": "accumulation", - "geometric mean diameter [m]": 1.1e-7, - "phase": "aqueous" - } - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "SO2", - "diffusion coefficient [m2 s-1]": 0.7 - }, - { - "name": "H2O2", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "SO4", - "coefficient": 1.0 - }, - { - "name": "H2O2", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O", - "coefficient": 1.0 - } - ] - }, - "__comment": "SO4 condensed phase production due to H2O2 (kg/m2/s)" - }, - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "SO2", - "diffusion coefficient [m2 s-1]": 0.7 - }, - { - "name": "O3", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "SO4", - "coefficient": 1.0 - }, - { - "name": "O3", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O", - "coefficient": 1.0 - } - ] - }, - "__comment": "SO4 condensed phase production due to O3 (kg/m2/s)" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/models/modal/missing_modal_variable.yaml b/test/unit/development/development_unit_configs/models/modal/missing_modal_variable.yaml deleted file mode 100644 index c6c6c18c..00000000 --- a/test/unit/development/development_unit_configs/models/modal/missing_modal_variable.yaml +++ /dev/null @@ -1,116 +0,0 @@ -version: 2.0.0 -name: Missing modal member variable - -species: - - name: SO2 - molecular weight [kg mol-1]: 0.06407 - density [kg m-3]: 2.628 - __absolute tolerance: 1.0e-20 - - - name: H2O2 - HLC(298K) [mol m-3 Pa-1]: 1.011596348 - HLC exponential factor [K]: 6340 - diffusion coefficient [m2 s-1]: 1.46E-05 - N star: 1.74 - molecular weight [kg mol-1]: 0.0340147 - density [kg m-3]: 1000.0 - __absolute tolerance: 1.0e-10 - - - name: O3 - molecular weight [kg mol-1]: 0.0479982 - density [kg m-3]: 2.144 - __absolute tolerance: 1.0e-20 - - - name: H2O - molecular weight [kg mol-1]: 0.01801528 - density [kg m-3]: 997.0 - __absolute tolerance: 1.0e-20 - - - name: H2SO4 - molecular weight [kg mol-1]: 0.098079 - density [kg m-3]: 1830.0 - __absolute tolerance: 1.0e-20 - - - name: SO4 - molecular weight [kg mol-1]: 0.09606 - density [kg m-3]: 1769.0 - __absolute tolerance: 1.0e-20 - - - name: organic carbon - molecular weight [kg mol-1]: 0.150 - density [kg m-3]: 1200 - __absolute tolerance: 1.0e-20 - -phases: - - name: gas - species: - - name: SO2 - - name: H2O2 - - name: H2SO4 - - name: O3 - - - name: aqueous - species: - - name: SO4 - - name: H2O2 - - name: H2SO4 - - name: H2O - - name: O3 - -models: - - name: aqueous - type: MODAL - modes: - - name: aitken - geometric mean diameter [m]: 2.6e-8 - phase: aqueous - __comment: Aitken mode - - - name: accumulation - geometric mean diameter [m]: 1.1e-7 - phase: aqueous - -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: SO2 - diffusion coefficient [m2 s-1]: 0.7 - - name: H2O2 - diffusion coefficient [m2 s-1]: 0.7 - - particle: - phase: aqueous - solutes: - - name: SO4 - coefficient: 1.0 - - name: H2O2 - coefficient: 1.0 - solvent: - - name: H2O - coefficient: 1.0 - - __comment: SO4 condensed phase production due to H2O2 (kg/m2/s) - - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: SO2 - diffusion coefficient [m2 s-1]: 0.7 - - name: O3 - diffusion coefficient [m2 s-1]: 0.7 - - particle: - phase: aqueous - solutes: - - name: SO4 - coefficient: 1.0 - - name: O3 - coefficient: 1.0 - solvent: - - name: H2O - coefficient: 1.0 - - __comment: SO4 condensed phase production due to O3 (kg/m2/s) diff --git a/test/unit/development/development_unit_configs/models/modal/missing_modes.json b/test/unit/development/development_unit_configs/models/modal/missing_modes.json deleted file mode 100644 index 6f549e88..00000000 --- a/test/unit/development/development_unit_configs/models/modal/missing_modes.json +++ /dev/null @@ -1,88 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing modes", - "species": [ - { - "name": "SO2" - }, - { - "name": "H2O2" - }, - { - "name": "O3" - }, - { - "name": "H2O" - }, - { - "name": "SO4" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "SO2" - }, - { - "name": "O3" - } - ] - }, - { - "name": "organic", - "species": [ - { - "name": "SO4" - }, - { - "name": "H2O2" - }, - { - "name": "H2O" - } - ] - } - ], - "models": [ - { - "name": "aqueous", - "type": "MODAL" - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "SO2", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "organic", - "solutes": [ - { - "name": "SO4", - "coefficient": 1.0 - }, - { - "name": "H2O2", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O", - "coefficient": 1.0 - } - ] - }, - "__comment": "comment" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/models/modal/missing_modes.yaml b/test/unit/development/development_unit_configs/models/modal/missing_modes.yaml deleted file mode 100644 index 9fa5854d..00000000 --- a/test/unit/development/development_unit_configs/models/modal/missing_modes.yaml +++ /dev/null @@ -1,46 +0,0 @@ -version: 2.0.0 -name: Missing modes - -species: - - name: SO2 - - name: H2O2 - - name: O3 - - name: H2O - - name: SO4 - -phases: - - name: gas - species: - - name: SO2 - - name: O3 - - - name: organic - species: - - name: SO4 - - name: H2O2 - - name: H2O - -models: - - name: aqueous - type: MODAL - -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: SO2 - diffusion coefficient [m2 s-1]: 0.7 - - particle: - phase: organic - solutes: - - name: SO4 - coefficient: 1.0 - - name: H2O2 - coefficient: 1.0 - solvent: - - name: H2O - coefficient: 1.0 - - __comment: comment diff --git a/test/unit/development/development_unit_configs/models/modal/mode_phase_not_found_in_phases.json b/test/unit/development/development_unit_configs/models/modal/mode_phase_not_found_in_phases.json deleted file mode 100644 index 4b4bce8f..00000000 --- a/test/unit/development/development_unit_configs/models/modal/mode_phase_not_found_in_phases.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "version": "2.0.0", - "name": "Mode phase not found in the phases", - "species": [ - { - "name": "SO2" - }, - { - "name": "H2O2" - }, - { - "name": "O3" - }, - { - "name": "H2O" - }, - { - "name": "SO4" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "SO2" - }, - { - "name": "O3" - } - ] - }, - { - "name": "organic", - "species": [ - { - "name": "SO4" - }, - { - "name": "H2O2" - }, - { - "name": "H2O" - } - ] - } - ], - "models": [ - { - "name": "aqueous", - "type": "MODAL", - "modes": [ - { - "name": "aitken", - "geometric mean diameter [m]": 2.6e-8, - "geometric standard deviation": 1.6, - "phase": "aqueous", - "__comment": "Aitken mode" - }, - { - "name": "accumulation", - "geometric mean diameter [m]": 1.1e-7, - "geometric standard deviation": 1.6, - "phase": "organic" - } - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "SO2", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "organic", - "solutes": [ - { - "name": "SO4", - "coefficient": 1.0 - }, - { - "name": "H2O2", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O", - "coefficient": 1.0 - } - ] - }, - "__comment": "comment" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/models/modal/mode_phase_not_found_in_phases.yaml b/test/unit/development/development_unit_configs/models/modal/mode_phase_not_found_in_phases.yaml deleted file mode 100644 index e645e098..00000000 --- a/test/unit/development/development_unit_configs/models/modal/mode_phase_not_found_in_phases.yaml +++ /dev/null @@ -1,57 +0,0 @@ -version: 2.0.0 -name: Mode phase not found in the phases - -species: - - name: SO2 - - name: H2O2 - - name: O3 - - name: H2O - - name: SO4 - -phases: - - name: gas - species: - - name: SO2 - - name: O3 - - - name: organic - species: - - name: SO4 - - name: H2O2 - - name: H2O - -models: - - name: aqueous - type: MODAL - modes: - - name: aitken - geometric mean diameter [m]: 2.6e-8 - geometric standard deviation: 1.6 - phase: aqueous - __comment: Aitken mode - - - name: accumulation - geometric mean diameter [m]: 1.1e-7 - geometric standard deviation: 1.6 - phase: organic - -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: SO2 - diffusion coefficient [m2 s-1]: 0.7 - - particle: - phase: organic - solutes: - - name: SO4 - coefficient: 1.0 - - name: H2O2 - coefficient: 1.0 - solvent: - - name: H2O - coefficient: 1.0 - - __comment: comment diff --git a/test/unit/development/development_unit_configs/models/modal/valid.json b/test/unit/development/development_unit_configs/models/modal/valid.json deleted file mode 100644 index f049317f..00000000 --- a/test/unit/development/development_unit_configs/models/modal/valid.json +++ /dev/null @@ -1,200 +0,0 @@ -{ - "version": "2.0.0", - "name": "Sulfate Formation", - "species": [ - { - "name": "SO2", - "molecular weight [kg mol-1]": 0.06407, - "density [kg m-3]": 2.628, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "H2O2", - "HLC(298K) [mol m-3 Pa-1]": 1.011596348, - "HLC exponential factor [K]": 6340, - "diffusion coefficient [m2 s-1]": 1.46E-05, - "N star": 1.74, - "molecular weight [kg mol-1]": 0.0340147, - "density [kg m-3]": 1000.0, - "__absolute tolerance": 1.0e-10 - }, - { - "name": "O3", - "molecular weight [kg mol-1]": 0.0479982, - "density [kg m-3]": 2.144, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "H2O", - "molecular weight [kg mol-1]": 0.01801528, - "density [kg m-3]": 997.0, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "H2SO4", - "molecular weight [kg mol-1]": 0.098079, - "density [kg m-3]": 1830.0, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "SO4", - "molecular weight [kg mol-1]": 0.09606, - "density [kg m-3]": 1769.0, - "__absolute tolerance": 1.0e-20 - }, - { - "name": "organic carbon", - "molecular weight [kg mol-1]": 0.150, - "density [kg m-3]": 1200, - "__absolute tolerance": 1.0e-20 - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "SO2" - }, - { - "name": "H2O2" - }, - { - "name": "H2SO4" - }, - { - "name": "O3" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "SO4" - }, - { - "name": "H2O2" - }, - { - "name": "H2SO4" - }, - { - "name": "H2O" - }, - { - "name": "O3" - } - ] - }, - { - "name": "organic", - "species": [ - { - "name": "organic carbon" - } - ] - } - ], - "models": [ - { - "name": "gas", - "type": "GAS_PHASE", - "phase": "gas" - }, - { - "name": "aqueous", - "type": "MODAL", - "modes": [ - { - "name": "aitken", - "geometric mean diameter [m]": 2.6e-8, - "geometric standard deviation": 1.6, - "phase": "aqueous", - "__comment": "Aitken mode" - }, - { - "name": "accumulation", - "geometric mean diameter [m]": 1.1e-7, - "geometric standard deviation": 1.8, - "phase": "organic" - } - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "SO2", - "diffusion coefficient [m2 s-1]": 0.7 - }, - { - "name": "H2O2", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "SO4", - "coefficient": 1.0 - }, - { - "name": "H2O2", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O", - "coefficient": 1.0 - } - ] - }, - "__comment": "SO4 condensed phase production due to H2O2 (kg/m2/s)" - }, - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "SO2", - "diffusion coefficient [m2 s-1]": 0.7 - }, - { - "name": "O3", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "SO4", - "coefficient": 1.0 - }, - { - "name": "O3", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O", - "coefficient": 1.0 - } - ] - }, - "__comment": "SO4 condensed phase production due to O3 (kg/m2/s)" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/models/modal/valid.yaml b/test/unit/development/development_unit_configs/models/modal/valid.yaml deleted file mode 100644 index 2e3c47bb..00000000 --- a/test/unit/development/development_unit_configs/models/modal/valid.yaml +++ /dev/null @@ -1,122 +0,0 @@ -version: 2.0.0 -name: Sulfate Formation - -species: - - name: SO2 - molecular weight [kg mol-1]: 0.06407 - density [kg m-3]: 2.628 - __absolute tolerance: 1.0e-20 - - - name: H2O2 - HLC(298K) [mol m-3 Pa-1]: 1.011596348 - HLC exponential factor [K]: 6340 - diffusion coefficient [m2 s-1]: 1.46e-05 - N star: 1.74 - molecular weight [kg mol-1]: 0.0340147 - density [kg m-3]: 1000.0 - __absolute tolerance: 1.0e-10 - - - name: O3 - molecular weight [kg mol-1]: 0.0479982 - density [kg m-3]: 2.144 - __absolute tolerance: 1.0e-20 - - - name: H2O - molecular weight [kg mol-1]: 0.01801528 - density [kg m-3]: 997.0 - __absolute tolerance: 1.0e-20 - - - name: H2SO4 - molecular weight [kg mol-1]: 0.098079 - density [kg m-3]: 1830.0 - __absolute tolerance: 1.0e-20 - - - name: SO4 - molecular weight [kg mol-1]: 0.09606 - density [kg m-3]: 1769.0 - __absolute tolerance: 1.0e-20 - - - name: organic carbon - molecular weight [kg mol-1]: 0.150 - density [kg m-3]: 1200 - __absolute tolerance: 1.0e-20 - -phases: - - name: gas - species: - - name: SO2 - - name: H2O2 - - name: H2SO4 - - name: O3 - - - name: aqueous - species: - - name: SO4 - - name: H2O2 - - name: H2SO4 - - name: H2O - - name: O3 - - - name: organic - species: - - name: organic carbon - -models: - - name: gas - type: GAS_PHASE - phase: gas - - - name: aqueous - type: MODAL - modes: - - name: aitken - geometric mean diameter [m]: 2.6e-8 - geometric standard deviation: 1.6 - phase: aqueous - __comment: Aitken mode - - - name: accumulation - geometric mean diameter [m]: 1.1e-7 - geometric standard deviation: 1.8 - phase: organic - -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: SO2 - diffusion coefficient [m2 s-1]: 0.7 - - name: H2O2 - diffusion coefficient [m2 s-1]: 0.7 - particle: - phase: aqueous - solutes: - - name: SO4 - coefficient: 1.0 - - name: H2O2 - coefficient: 1.0 - solvent: - - name: H2O - coefficient: 1.0 - __comment: SO4 condensed phase production due to H2O2 (kg/m2/s) - - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: SO2 - diffusion coefficient [m2 s-1]: 0.7 - - name: O3 - diffusion coefficient [m2 s-1]: 0.7 - particle: - phase: aqueous - solutes: - - name: SO4 - coefficient: 1.0 - - name: O3 - coefficient: 1.0 - solvent: - - name: H2O - coefficient: 1.0 - __comment: SO4 condensed phase production due to O3 (kg/m2/s) diff --git a/test/unit/development/development_unit_configs/phases/duplicate_phases.json b/test/unit/development/development_unit_configs/phases/duplicate_phases.json deleted file mode 100644 index 2f7f58ca..00000000 --- a/test/unit/development/development_unit_configs/phases/duplicate_phases.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "version": "2.0.0", - "name": "Duplicate phases configuration", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - }, - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - }, - { - "name": "aqueos", - "species": [ - { - "name": "C" - } - ] - } - ], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/phases/duplicate_phases.yaml b/test/unit/development/development_unit_configs/phases/duplicate_phases.yaml deleted file mode 100644 index e1a5b75c..00000000 --- a/test/unit/development/development_unit_configs/phases/duplicate_phases.yaml +++ /dev/null @@ -1,24 +0,0 @@ -version: 2.0.0 -name: Duplicate phases configuration - -species: - - name: A - - name: B - - name: C - -phases: - - name: gas - species: - - name: A - - name: B - - - name: gas - species: - - name: A - - name: B - - - name: aqueos - species: - - name: C - -reactions: [] diff --git a/test/unit/development/development_unit_configs/phases/duplicate_species_in_phase.json b/test/unit/development/development_unit_configs/phases/duplicate_species_in_phase.json deleted file mode 100644 index a836f824..00000000 --- a/test/unit/development/development_unit_configs/phases/duplicate_species_in_phase.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "version": "2.0.0", - "name": "Duplicate species in phase configuration", - "species": [ - { - "name": "O2" - }, - { - "name": "N2" - }, - { - "name": "CO2" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "O2" - }, - { - "name": "N2" - }, - { - "name": "O2" - } - ] - } - ], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/phases/duplicate_species_in_phase.yaml b/test/unit/development/development_unit_configs/phases/duplicate_species_in_phase.yaml deleted file mode 100644 index ca022cde..00000000 --- a/test/unit/development/development_unit_configs/phases/duplicate_species_in_phase.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: 2.0.0 -name: Duplicate species in phase configuration - -species: - - name: O2 - - name: N2 - - name: CO2 - -phases: - - name: gas - species: - - name: O2 - - name: N2 - - name: O2 # Duplicate species - -reactions: [] diff --git a/test/unit/development/development_unit_configs/phases/invalid_key.json b/test/unit/development/development_unit_configs/phases/invalid_key.json deleted file mode 100644 index ee9fe57a..00000000 --- a/test/unit/development/development_unit_configs/phases/invalid_key.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "version": "2.0.0", - "name": "Invalid key configuration", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "other": "key" - } - ], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/phases/invalid_key.yaml b/test/unit/development/development_unit_configs/phases/invalid_key.yaml deleted file mode 100644 index f3c0a497..00000000 --- a/test/unit/development/development_unit_configs/phases/invalid_key.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: 2.0.0 -name: Invalid key configuration - -species: - - name: A - - name: B - - name: C - -phases: - - name: gas - species: - - name: A - - name: B - other: key - -reactions: [] diff --git a/test/unit/development/development_unit_configs/phases/invalid_species_object.json b/test/unit/development/development_unit_configs/phases/invalid_species_object.json deleted file mode 100644 index 37ac5547..00000000 --- a/test/unit/development/development_unit_configs/phases/invalid_species_object.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "version": "2.0.0", - "name": "Invalid species object test - missing name", - "species": [ - { - "name": "foo" - } - ], - "phases": [ - { - "name": "test phase", - "species": [ - { - "name": "foo" - }, - { - "diffusion coefficient [m2 s-1]": 1.0 - } - ] - } - ], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/phases/invalid_species_object.yaml b/test/unit/development/development_unit_configs/phases/invalid_species_object.yaml deleted file mode 100644 index 7199e442..00000000 --- a/test/unit/development/development_unit_configs/phases/invalid_species_object.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -version: 2.0.0 -name: Invalid species object test - missing name -species: -- name: foo -phases: -- name: test phase - species: - - name: foo - - "diffusion coefficient [m2 s-1]": 1.0 # Missing name field -reactions: [] \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/phases/missing_required_key.json b/test/unit/development/development_unit_configs/phases/missing_required_key.json deleted file mode 100644 index 5c5cf8a3..00000000 --- a/test/unit/development/development_unit_configs/phases/missing_required_key.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing required phases key configuration", - "species": [], - "phases": [ - { - "name": "gas" - } - ], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/phases/missing_required_key.yaml b/test/unit/development/development_unit_configs/phases/missing_required_key.yaml deleted file mode 100644 index 78686843..00000000 --- a/test/unit/development/development_unit_configs/phases/missing_required_key.yaml +++ /dev/null @@ -1,6 +0,0 @@ -name: Missing required phases key configuration -phases: -- name: gas -reactions: [] -species: [] -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/phases/phase_species_properties.json b/test/unit/development/development_unit_configs/phases/phase_species_properties.json deleted file mode 100644 index 8525e37d..00000000 --- a/test/unit/development/development_unit_configs/phases/phase_species_properties.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "version": "2.0.0", - "name": "Phase species properties test configuration", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - } - ], - "phases": [ - { - "name": "my phase", - "species": [ - { - "name": "foo", - "diffusion coefficient [m2 s-1]": 4.23e-7 - }, - { - "name": "bar", - "__custom property": 0.5, - "__another custom property": "value" - }, - { - "name": "baz", - } - ], - "__my custom phase property": "custom value" - } - ], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/phases/phase_species_properties.yaml b/test/unit/development/development_unit_configs/phases/phase_species_properties.yaml deleted file mode 100644 index e127f0b8..00000000 --- a/test/unit/development/development_unit_configs/phases/phase_species_properties.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -version: 2.0.0 -name: Phase species properties test configuration -species: -- name: foo -- name: bar -- name: baz -phases: -- name: my phase - species: - - name: foo - "diffusion coefficient [m2 s-1]": 4.23e-7 - - name: bar - "__custom property": 0.5 - "__another custom property": "value" - - name: baz - "__my custom phase property": "custom value" -reactions: [] \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/phases/unknown_species.json b/test/unit/development/development_unit_configs/phases/unknown_species.json deleted file mode 100644 index 79598c3b..00000000 --- a/test/unit/development/development_unit_configs/phases/unknown_species.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species configuration", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "D" - }, - ], - "__other": "key" - } - ], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/phases/unknown_species.yaml b/test/unit/development/development_unit_configs/phases/unknown_species.yaml deleted file mode 100644 index 57a8e90c..00000000 --- a/test/unit/development/development_unit_configs/phases/unknown_species.yaml +++ /dev/null @@ -1,16 +0,0 @@ -version: 2.0.0 -name: Unknown species configuration - -species: - - name: A - - name: B - - name: C - -phases: - - name: gas - species: - - name: A - - name: D - __other: key - -reactions: [] diff --git a/test/unit/development/development_unit_configs/phases/valid_phases.json b/test/unit/development/development_unit_configs/phases/valid_phases.json deleted file mode 100644 index ed9c157f..00000000 --- a/test/unit/development/development_unit_configs/phases/valid_phases.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid phases configuration", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A", - "diffusion coefficient [m2 s-1]": 4.23e-7 - }, - { - "name": "B" - } - ], - "__other": "This is a comment." - }, - { - "name": "aqueous", - "species": [ - { - "name": "C", - "diffusion coefficient [m2 s-1]": 4.23e-7 - } - ], - "__other1": "This is another comment.", - "__other2": "This is again a comment." - } - ], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/phases/valid_phases.yaml b/test/unit/development/development_unit_configs/phases/valid_phases.yaml deleted file mode 100644 index 8de098f4..00000000 --- a/test/unit/development/development_unit_configs/phases/valid_phases.yaml +++ /dev/null @@ -1,24 +0,0 @@ -version: 2.0.0 -name: Valid phases configuration - -species: - - name: A - - name: B - - name: C - -phases: - - name: gas - species: - - name: A - diffusion coefficient [m2 s-1]: 4.23e-7 - - name: B - __other: This is a comment. - - - name: aqueous - species: - - name: C - diffusion coefficient [m2 s-1]: 4.23e-7 - __other1: This is another comment. - __other2: This is again a comment. - -reactions: [] diff --git a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.json deleted file mode 100644 index e8bc0faf..00000000 --- a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "k_reverse": 0.32, - "reactants": [ - { - "name": "A", - "Coefficient": 2 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1 - }, - { - "name": "C", - "coefficient": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.yaml deleted file mode 100644 index 87f98a87..00000000 --- a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Bad reaction component -phases: -- name: aqueous - species: - - name: A - - name: B - - name: C - - name: H2O -reactions: -- condensed phase: aqueous - condensed-phase water: H2O - k_reverse: 0.32 - products: - - name: B - coefficient: 1 - - name: C - coefficient: 1 - reactants: - - name: A - Coefficient: 2 - type: AQUEOUS_EQUILIBRIUM -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/missing_phase.json b/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/missing_phase.json deleted file mode 100644 index 3bdc0ce4..00000000 --- a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/missing_phase.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [], - "reactions": [ - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "k_reverse": 0.32, - "reactants": [ - { - "name": "A", - "coefficient": 2 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1 - }, - { - "name": "C", - "coefficient": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/missing_phase.yaml deleted file mode 100644 index 0da54d56..00000000 --- a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/missing_phase.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- condensed phase: aqueous - condensed-phase water: H2O - k_reverse: 0.32 - products: - - coefficient: 1 - name: B - - coefficient: 1 - name: C - reactants: - - coefficient: 2 - name: A - type: AQUEOUS_EQUILIBRIUM -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/unknown_species.json b/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/unknown_species.json deleted file mode 100644 index d7a16ff8..00000000 --- a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/unknown_species.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "k_reverse": 0.32, - "reactants": [ - { - "name": "A", - "coefficient": 2 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1 - }, - { - "name": "C", - "coefficient": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/unknown_species.yaml deleted file mode 100644 index 38bb5b97..00000000 --- a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/unknown_species.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: Unknown species -phases: -- name: aqueous - species: - - name: A - - name: B -reactions: -- condensed phase: aqueous - condensed-phase water: H2O - k_reverse: 0.32 - products: - - coefficient: 1 - name: B - - coefficient: 1 - name: C - reactants: - - coefficient: 2 - name: A - type: AQUEOUS_EQUILIBRIUM -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/valid.json b/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/valid.json deleted file mode 100644 index 6e3c89a4..00000000 --- a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/valid.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid aqueous equilibrium", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "A": 1.14e-2, - "C": 2300.0, - "k_reverse": 0.32, - "reactants": [ - { - "name": "A", - "coefficient": 2 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1 - }, - { - "name": "C", - "coefficient": 1 - } - ], - "name": "my aqueous eq", - "__comment": "GIF is pronounced with a hard g" - }, - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "k_reverse": 0.32, - "reactants": [ - { - "name": "A", - "coefficient": 2 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1 - }, - { - "name": "C", - "coefficient": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/valid.yaml b/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/valid.yaml deleted file mode 100644 index 82be5ab4..00000000 --- a/test/unit/development/development_unit_configs/reactions/aqueous_equilibrium/valid.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: Valid aqueous equilibrium -phases: -- name: aqueous - species: - - name: A - - name: B - - name: C - - name: H2O -reactions: -- A: 0.0114 - C: 2300.0 - __comment: GIF is pronounced with a hard g - condensed phase: aqueous - condensed-phase water: H2O - k_reverse: 0.32 - name: my aqueous eq - products: - - coefficient: 1 - name: B - - coefficient: 1 - name: C - reactants: - - coefficient: 2 - name: A - type: AQUEOUS_EQUILIBRIUM -- condensed phase: aqueous - condensed-phase water: H2O - k_reverse: 0.32 - products: - - coefficient: 1 - name: B - - coefficient: 1 - name: C - reactants: - - coefficient: 2 - name: A - type: AQUEOUS_EQUILIBRIUM -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/arrhenius/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/arrhenius/bad_reaction_component.json deleted file mode 100644 index de4014d6..00000000 --- a/test/unit/development/development_unit_configs/reactions/arrhenius/bad_reaction_component.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "ARRHENIUS", - "gas phase": "gas", - "reactants": [ - { - "Species name": "A" - } - ], - "products": [ - { - "name": "B" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/arrhenius/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/arrhenius/bad_reaction_component.yaml deleted file mode 100644 index ea232211..00000000 --- a/test/unit/development/development_unit_configs/reactions/arrhenius/bad_reaction_component.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Bad reaction component -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - name: B - reactants: - - Species name: A - type: ARRHENIUS -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/arrhenius/missing_phase.json b/test/unit/development/development_unit_configs/reactions/arrhenius/missing_phase.json deleted file mode 100644 index 7ebfab75..00000000 --- a/test/unit/development/development_unit_configs/reactions/arrhenius/missing_phase.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [], - "reactions": [ - { - "type": "ARRHENIUS", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/arrhenius/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/arrhenius/missing_phase.yaml deleted file mode 100644 index 7d3ceeb6..00000000 --- a/test/unit/development/development_unit_configs/reactions/arrhenius/missing_phase.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- gas phase: gas - products: - - name: C - reactants: - - name: A - type: ARRHENIUS -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/arrhenius/mutually_exclusive.json b/test/unit/development/development_unit_configs/reactions/arrhenius/mutually_exclusive.json deleted file mode 100644 index 0c3f5733..00000000 --- a/test/unit/development/development_unit_configs/reactions/arrhenius/mutually_exclusive.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "version": "2.0.0", - "name": "Mutually Exclusive", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "ARRHENIUS", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "B" - } - ], - "C": 10, - "Ea": 0.5 - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/arrhenius/mutually_exclusive.yaml b/test/unit/development/development_unit_configs/reactions/arrhenius/mutually_exclusive.yaml deleted file mode 100644 index 3165dfc7..00000000 --- a/test/unit/development/development_unit_configs/reactions/arrhenius/mutually_exclusive.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Mutually Exclusive -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- C: 10 - Ea: 0.5 - gas phase: gas - products: - - name: B - reactants: - - name: A - type: ARRHENIUS -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/arrhenius/unknown_species.json b/test/unit/development/development_unit_configs/reactions/arrhenius/unknown_species.json deleted file mode 100644 index 7e0cdddf..00000000 --- a/test/unit/development/development_unit_configs/reactions/arrhenius/unknown_species.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "ARRHENIUS", - "name": "Arrhenius", - "gas phase": "gas", - "reactants": [ - { - "name": "D" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/arrhenius/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/arrhenius/unknown_species.yaml deleted file mode 100644 index 8a962236..00000000 --- a/test/unit/development/development_unit_configs/reactions/arrhenius/unknown_species.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - name: C - reactants: - - name: D - type: ARRHENIUS - name: Arrhenius -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/arrhenius/valid.json b/test/unit/development/development_unit_configs/reactions/arrhenius/valid.json deleted file mode 100644 index 30a8d201..00000000 --- a/test/unit/development/development_unit_configs/reactions/arrhenius/valid.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid arrhenius", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "ARRHENIUS", - "gas phase": "gas", - "reactants": [ - { - "name": "A", - "coefficient": 1 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1.2 - }, - { - "name": "C", - "coefficient": 0.3 - } - ], - "A": 32.1, - "B": -2.3, - "C": 102.3, - "D": 63.4, - "E": -1.3, - "name": "my arrhenius", - "__solver_param": 0.1 - }, - { - "type": "ARRHENIUS", - "gas phase": "gas", - "reactants": [ - { - "name": "A", - "coefficient": 2 - }, - { - "name": "B", - "coefficient": 0.1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.5, - "__optional thing": "hello" - } - ], - "A": 3.1, - "B": -0.3, - "C": 12.3, - "D": 6.4, - "E": -0.3, - "name": "my arrhenius2" - }, - { - "type": "ARRHENIUS", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/arrhenius/valid.yaml b/test/unit/development/development_unit_configs/reactions/arrhenius/valid.yaml deleted file mode 100644 index 54f356dd..00000000 --- a/test/unit/development/development_unit_configs/reactions/arrhenius/valid.yaml +++ /dev/null @@ -1,53 +0,0 @@ -name: Valid arrhenius -phases: -- name: gas - species: - - name: A - - name: B - - name: C -reactions: -- A: 32.1 - B: -2.3 - C: 102.3 - D: 63.4 - E: -1.3 - __solver_param: 0.1 - gas phase: gas - name: my arrhenius - products: - - coefficient: 1.2 - name: B - - coefficient: 0.3 - name: C - reactants: - - coefficient: 1 - name: A - type: ARRHENIUS -- A: 3.1 - B: -0.3 - C: 12.3 - D: 6.4 - E: -0.3 - gas phase: gas - name: my arrhenius2 - products: - - __optional thing: hello - coefficient: 0.5 - name: C - reactants: - - coefficient: 2 - name: A - - coefficient: 0.1 - name: B - type: ARRHENIUS -- gas phase: gas - products: - - name: C - reactants: - - name: A - type: ARRHENIUS -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/branched/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/branched/bad_reaction_component.json deleted file mode 100644 index 2433c84e..00000000 --- a/test/unit/development/development_unit_configs/reactions/branched/bad_reaction_component.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "BRANCHED_NO_RO2", - "gas phase": "gas", - "reactants": [ - { - "Species name": "A" - } - ], - "alkoxy products": [ - { - "name": "B", - "coefficient": 0.2 - }, - { - "name": "A", - "coefficient": 1.2 - } - ], - "nitrate products": [ - { - "name": "C", - "coefficient": 1.2, - "__thing": "hi" - } - ], - "X": 1.2e-4, - "Y": 167, - "a0": 0.15, - "n": 9, - "name": "my branched", - "__comment": "thing" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/branched/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/branched/bad_reaction_component.yaml deleted file mode 100644 index 8b3c91d6..00000000 --- a/test/unit/development/development_unit_configs/reactions/branched/bad_reaction_component.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: Bad reaction component -phases: -- name: gas - species: - - name: A - - name: B - - name: C -reactions: -- X: 0.00012 - Y: 167 - __comment: thing - a0: 0.15 - alkoxy products: - - coefficient: 0.2 - name: B - - coefficient: 1.2 - name: A - gas phase: gas - n: 9 - name: my branched - nitrate products: - - __thing: hi - coefficient: 1.2 - name: C - reactants: - - Species name: A - type: BRANCHED_NO_RO2 -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/branched/missing_phase.json b/test/unit/development/development_unit_configs/reactions/branched/missing_phase.json deleted file mode 100644 index 5f9e21b4..00000000 --- a/test/unit/development/development_unit_configs/reactions/branched/missing_phase.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [], - "reactions": [ - { - "type": "BRANCHED_NO_RO2", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "alkoxy products": [ - { - "name": "B", - "coefficient": 0.2 - }, - { - "name": "A", - "coefficient": 1.2 - } - ], - "nitrate products": [ - { - "name": "C", - "coefficient": 1.2, - "__thing": "hi" - } - ], - "X": 1.2e-4, - "Y": 167, - "a0": 0.15, - "n": 9, - "name": "my branched", - "__comment": "thing" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/branched/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/branched/missing_phase.yaml deleted file mode 100644 index fe0aa204..00000000 --- a/test/unit/development/development_unit_configs/reactions/branched/missing_phase.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- X: 0.00012 - Y: 167 - __comment: thing - a0: 0.15 - alkoxy products: - - coefficient: 0.2 - name: B - - coefficient: 1.2 - name: A - gas phase: gas - n: 9 - name: my branched - nitrate products: - - __thing: hi - coefficient: 1.2 - name: C - reactants: - - name: A - type: BRANCHED_NO_RO2 -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/branched/unknown_species.json b/test/unit/development/development_unit_configs/reactions/branched/unknown_species.json deleted file mode 100644 index e7ee16d8..00000000 --- a/test/unit/development/development_unit_configs/reactions/branched/unknown_species.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "BRANCHED_NO_RO2", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "alkoxy products": [ - { - "name": "B", - "coefficient": 0.2 - }, - { - "name": "A", - "coefficient": 1.2 - } - ], - "nitrate products": [ - { - "name": "C", - "coefficient": 1.2, - "__thing": "hi" - } - ], - "X": 1.2e-4, - "Y": 167, - "a0": 0.15, - "n": 9, - "name": "my branched", - "__comment": "thing" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/branched/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/branched/unknown_species.yaml deleted file mode 100644 index 191f97bd..00000000 --- a/test/unit/development/development_unit_configs/reactions/branched/unknown_species.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- X: 0.00012 - Y: 167 - __comment: thing - a0: 0.15 - alkoxy products: - - coefficient: 0.2 - name: B - - coefficient: 1.2 - name: A - gas phase: gas - n: 9 - name: my branched - nitrate products: - - __thing: hi - coefficient: 1.2 - name: C - reactants: - - name: A - type: BRANCHED_NO_RO2 -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/branched/valid.json b/test/unit/development/development_unit_configs/reactions/branched/valid.json deleted file mode 100644 index d5b10444..00000000 --- a/test/unit/development/development_unit_configs/reactions/branched/valid.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid branched", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "BRANCHED_NO_RO2", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "alkoxy products": [ - { - "name": "B", - "coefficient": 0.2 - }, - { - "name": "A", - "coefficient": 1.2 - } - ], - "nitrate products": [ - { - "name": "C", - "coefficient": 1.2, - "__thing": "hi" - } - ], - "X": 1.2e-4, - "Y": 167, - "a0": 0.15, - "n": 9, - "name": "my branched", - "__comment": "thing" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/branched/valid.yaml b/test/unit/development/development_unit_configs/reactions/branched/valid.yaml deleted file mode 100644 index f0bdeb88..00000000 --- a/test/unit/development/development_unit_configs/reactions/branched/valid.yaml +++ /dev/null @@ -1,32 +0,0 @@ -name: Valid branched -phases: -- name: gas - species: - - name: A - - name: B - - name: C -reactions: -- X: 0.00012 - Y: 167 - __comment: thing - a0: 0.15 - alkoxy products: - - coefficient: 0.2 - name: B - - coefficient: 1.2 - name: A - gas phase: gas - n: 9 - name: my branched - nitrate products: - - __thing: hi - coefficient: 1.2 - name: C - reactants: - - name: A - type: BRANCHED_NO_RO2 -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/bad_reaction_component.json deleted file mode 100644 index b9a3f1eb..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/bad_reaction_component.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "reactants": [ - { - "Name": "A" - } - ], - "products": [ - { - "name": "B" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/bad_reaction_component.yaml deleted file mode 100644 index 9fb842c6..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/bad_reaction_component.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Bad reaction component -phases: -- name: aqueous - species: - - name: A - - name: B - - name: H2O -reactions: -- condensed phase: aqueous - products: - - name: B - reactants: - - Name: A - type: CONDENSED_PHASE_ARRHENIUS -species: -- name: A -- name: B -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/missing_phase.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/missing_phase.json deleted file mode 100644 index a2518c4f..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/missing_phase.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [], - "reactions": [ - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/missing_phase.yaml deleted file mode 100644 index 9af64e90..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/missing_phase.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- condensed phase: aqueous - products: - - name: C - reactants: - - name: A - type: CONDENSED_PHASE_ARRHENIUS -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/mutually_exclusive.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/mutually_exclusive.json deleted file mode 100644 index 07dfe1b1..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/mutually_exclusive.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "version": "2.0.0", - "name": "Mutually Exclusive", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "B" - } - ], - "C": 10, - "Ea": 0.5 - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/mutually_exclusive.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/mutually_exclusive.yaml deleted file mode 100644 index 708caaab..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/mutually_exclusive.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Mutually Exclusive -phases: -- name: aqueous - species: - - name: A - - name: B - - name: H2O -reactions: -- C: 10 - Ea: 0.5 - condensed phase: aqueous - products: - - name: B - reactants: - - name: A - type: CONDENSED_PHASE_ARRHENIUS -species: -- name: A -- name: B -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/species_not_in_aqueous_phase.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/species_not_in_aqueous_phase.json deleted file mode 100644 index 419da12b..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/species_not_in_aqueous_phase.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "version": "2.0.0", - "name": "Condensed phase arrhenius using species not in its requested condensed phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A", - "coefficient": 1 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1.2 - }, - { - "name": "C", - "coefficient": 0.3 - } - ], - "A": 32.1, - "B": -2.3, - "C": 102.3, - "D": 63.4, - "E": -1.3, - "name": "my arrhenius", - "__solver_param": 0.1 - }, - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A", - "coefficient": 2 - }, - { - "name": "B", - "coefficient": 0.1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.5, - "__optional thing": "hello" - } - ], - "A": 3.1, - "B": -0.3, - "C": 12.3, - "D": 6.4, - "E": -0.3, - "name": "my arrhenius2" - }, - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/species_not_in_aqueous_phase.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/species_not_in_aqueous_phase.yaml deleted file mode 100644 index 5fb21e55..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/species_not_in_aqueous_phase.yaml +++ /dev/null @@ -1,54 +0,0 @@ -name: Condensed phase arrhenius using species not in its requested condensed phase -phases: -- name: aqueous - species: - - name: A - - name: C - - name: H2O -reactions: -- A: 32.1 - B: -2.3 - C: 102.3 - D: 63.4 - E: -1.3 - __solver_param: 0.1 - condensed phase: aqueous - name: my arrhenius - products: - - coefficient: 1.2 - name: B - - coefficient: 0.3 - name: C - reactants: - - coefficient: 1 - name: A - type: CONDENSED_PHASE_ARRHENIUS -- A: 3.1 - B: -0.3 - C: 12.3 - D: 6.4 - E: -0.3 - condensed phase: aqueous - name: my arrhenius2 - products: - - __optional thing: hello - coefficient: 0.5 - name: C - reactants: - - coefficient: 2 - name: A - - coefficient: 0.1 - name: B - type: CONDENSED_PHASE_ARRHENIUS -- condensed phase: aqueous - products: - - name: C - reactants: - - name: A - type: CONDENSED_PHASE_ARRHENIUS -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/unknown_species.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/unknown_species.json deleted file mode 100644 index 0a095c87..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/unknown_species.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/unknown_species.yaml deleted file mode 100644 index 210aeaa8..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/unknown_species.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Unknown species -phases: -- name: aqueous - species: - - name: A - - name: B - - name: H2O -reactions: -- condensed phase: aqueous - products: - - name: C - reactants: - - name: A - type: CONDENSED_PHASE_ARRHENIUS -species: -- name: A -- name: B -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/valid.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/valid.json deleted file mode 100644 index c21a90da..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/valid.json +++ /dev/null @@ -1,107 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid condensed phase arrhenius", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A", - "coefficient": 1 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1.2 - }, - { - "name": "C", - "coefficient": 0.3 - } - ], - "A": 32.1, - "B": -2.3, - "C": 102.3, - "D": 63.4, - "E": -1.3, - "name": "my arrhenius", - "__solver_param": 0.1 - }, - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A", - "coefficient": 2 - }, - { - "name": "B", - "coefficient": 0.1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.5, - "__optional thing": "hello" - } - ], - "A": 3.1, - "B": -0.3, - "C": 12.3, - "D": 6.4, - "E": -0.3, - "name": "my arrhenius2" - }, - { - "type": "CONDENSED_PHASE_ARRHENIUS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/valid.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/valid.yaml deleted file mode 100644 index 22e13f65..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_arrhenius/valid.yaml +++ /dev/null @@ -1,55 +0,0 @@ -name: Valid condensed phase arrhenius -phases: -- name: aqueous - species: - - name: A - - name: B - - name: C - - name: H2O -reactions: -- A: 32.1 - B: -2.3 - C: 102.3 - D: 63.4 - E: -1.3 - __solver_param: 0.1 - condensed phase: aqueous - name: my arrhenius - products: - - coefficient: 1.2 - name: B - - coefficient: 0.3 - name: C - reactants: - - coefficient: 1 - name: A - type: CONDENSED_PHASE_ARRHENIUS -- A: 3.1 - B: -0.3 - C: 12.3 - D: 6.4 - E: -0.3 - condensed phase: aqueous - name: my arrhenius2 - products: - - __optional thing: hello - coefficient: 0.5 - name: C - reactants: - - coefficient: 2 - name: A - - coefficient: 0.1 - name: B - type: CONDENSED_PHASE_ARRHENIUS -- condensed phase: aqueous - products: - - name: C - reactants: - - name: A - type: CONDENSED_PHASE_ARRHENIUS -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/bad_reaction_component.json deleted file mode 100644 index fcee9c1a..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/bad_reaction_component.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "CONDENSED_PHASE_PHOTOLYSIS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A", - "Coefficient": 1.2 - } - ], - "products": [ - { - "name": "B", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/bad_reaction_component.yaml deleted file mode 100644 index b990b5a7..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/bad_reaction_component.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: Bad reaction component -phases: -- name: aqueous - species: - - name: A - - name: B - - name: C - - name: H2O -reactions: -- condensed phase: aqueous - products: - - coefficient: 0.2 - name: B - reactants: - - Coefficient: 1.2 - name: A - type: CONDENSED_PHASE_PHOTOLYSIS -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/missing_phase.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/missing_phase.json deleted file mode 100644 index d733db96..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/missing_phase.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [], - "reactions": [ - { - "type": "CONDENSED_PHASE_PHOTOLYSIS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "B", - "coefficient": 1.2 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/missing_phase.yaml deleted file mode 100644 index e517cb4c..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/missing_phase.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- condensed phase: aqueous - products: - - coefficient: 0.2 - name: C - reactants: - - coefficient: 1.2 - name: B - type: CONDENSED_PHASE_PHOTOLYSIS -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/more_than_one_reactant.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/more_than_one_reactant.json deleted file mode 100644 index e3eaf29d..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/more_than_one_reactant.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "version": "2.0.0", - "name": "more than one reactant", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "CONDENSED_PHASE_PHOTOLYSIS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/more_than_one_reactant.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/more_than_one_reactant.yaml deleted file mode 100644 index 980380bb..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/more_than_one_reactant.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: more than one reactant -phases: -- name: aqueous - species: - - name: A - - name: B - - name: C - - name: H2O -reactions: -- condensed phase: aqueous - products: - - coefficient: 0.2 - name: C - reactants: - - name: A - - name: B - type: CONDENSED_PHASE_PHOTOLYSIS -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/species_not_in_aqueous_phase.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/species_not_in_aqueous_phase.json deleted file mode 100644 index cbd06486..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/species_not_in_aqueous_phase.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "version": "2.0.0", - "name": "Condensed phase photolysis using species not in its requested condensed phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "CONDENSED_PHASE_PHOTOLYSIS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A", - "coefficient": 1 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1.2 - }, - { - "name": "C", - "coefficient": 0.3 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/species_not_in_aqueous_phase.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/species_not_in_aqueous_phase.yaml deleted file mode 100644 index 9c6b8600..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/species_not_in_aqueous_phase.yaml +++ /dev/null @@ -1,24 +0,0 @@ -name: Condensed phase photolysis using species not in its requested condensed phase -phases: -- name: aqueous - species: - - name: A - - name: C - - name: H2O -reactions: -- condensed phase: aqueous - products: - - coefficient: 1.2 - name: B - - coefficient: 0.3 - name: C - reactants: - - coefficient: 1 - name: A - type: CONDENSED_PHASE_PHOTOLYSIS -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/unknown_species.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/unknown_species.json deleted file mode 100644 index 6a9365c9..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/unknown_species.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "CONDENSED_PHASE_PHOTOLYSIS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "A", - "coefficient": 1.2 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/unknown_species.yaml deleted file mode 100644 index 26ecb52c..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/unknown_species.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Unknown species -phases: -- name: aqueous - species: - - name: A - - name: B -reactions: -- condensed phase: aqueous - products: - - coefficient: 0.2 - name: C - reactants: - - coefficient: 1.2 - name: A - type: CONDENSED_PHASE_PHOTOLYSIS -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/valid.json b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/valid.json deleted file mode 100644 index 05d65ad3..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/valid.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid surface", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "CONDENSED_PHASE_PHOTOLYSIS", - "condensed phase": "aqueous", - "__comment": "hi", - "reactants": [ - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 1 - } - ], - "name": "my condensed phase photolysis", - "scaling factor": 12.3 - }, - { - "type": "CONDENSED_PHASE_PHOTOLYSIS", - "condensed phase": "aqueous", - "reactants": [ - { - "name": "B", - "coefficient": 1.2 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/valid.yaml b/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/valid.yaml deleted file mode 100644 index 441a2508..00000000 --- a/test/unit/development/development_unit_configs/reactions/condensed_phase_photolysis/valid.yaml +++ /dev/null @@ -1,34 +0,0 @@ -name: Valid surface -phases: -- name: aqueous - species: - - name: A - - name: B - - name: C - - name: H2O -reactions: -- __comment: hi - condensed phase: aqueous - name: my condensed phase photolysis - products: - - coefficient: 1 - name: C - reactants: - - coefficient: 1 - name: B - scaling factor: 12.3 - type: CONDENSED_PHASE_PHOTOLYSIS -- condensed phase: aqueous - products: - - coefficient: 0.2 - name: C - reactants: - - coefficient: 1.2 - name: B - type: CONDENSED_PHASE_PHOTOLYSIS -species: -- name: A -- name: B -- name: C -- name: H2O -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/emission/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/emission/bad_reaction_component.json deleted file mode 100644 index 6b88a2f4..00000000 --- a/test/unit/development/development_unit_configs/reactions/emission/bad_reaction_component.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "EMISSION", - "gas phase": "gas", - "products": [ - { - "Name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/emission/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/emission/bad_reaction_component.yaml deleted file mode 100644 index 57d5a0d1..00000000 --- a/test/unit/development/development_unit_configs/reactions/emission/bad_reaction_component.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: Bad reaction component -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - Name: C - type: EMISSION -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/emission/missing_phase.json b/test/unit/development/development_unit_configs/reactions/emission/missing_phase.json deleted file mode 100644 index 010827da..00000000 --- a/test/unit/development/development_unit_configs/reactions/emission/missing_phase.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [], - "reactions": [ - { - "type": "EMISSION", - "gas phase": "gas", - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/emission/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/emission/missing_phase.yaml deleted file mode 100644 index 2eaf63ce..00000000 --- a/test/unit/development/development_unit_configs/reactions/emission/missing_phase.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- gas phase: gas - products: - - name: C - type: EMISSION -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/emission/unknown_species.json b/test/unit/development/development_unit_configs/reactions/emission/unknown_species.json deleted file mode 100644 index 81ecc45f..00000000 --- a/test/unit/development/development_unit_configs/reactions/emission/unknown_species.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "EMISSION", - "gas phase": "gas", - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/emission/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/emission/unknown_species.yaml deleted file mode 100644 index 0dc0c52c..00000000 --- a/test/unit/development/development_unit_configs/reactions/emission/unknown_species.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - name: C - type: EMISSION -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/emission/valid.json b/test/unit/development/development_unit_configs/reactions/emission/valid.json deleted file mode 100644 index 3e029042..00000000 --- a/test/unit/development/development_unit_configs/reactions/emission/valid.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid surface", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - }, - { - "name": "surface reacting phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "EMISSION", - "gas phase": "gas", - "products": [ - { - "name": "B", - "coefficient": 1 - } - ], - "name": "my emission", - "scaling factor": 12.3, - "__comment": "Dr. Pepper outranks any other soda" - }, - { - "type": "EMISSION", - "gas phase": "gas", - "products": [ - { - "name": "B" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/emission/valid.yaml b/test/unit/development/development_unit_configs/reactions/emission/valid.yaml deleted file mode 100644 index 4c07d29e..00000000 --- a/test/unit/development/development_unit_configs/reactions/emission/valid.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: Valid surface -phases: -- name: gas - species: - - name: A - - name: B - - name: C -- name: surface reacting phase - species: - - name: A - - name: B - - name: C -reactions: -- __comment: Dr. Pepper outranks any other soda - gas phase: gas - name: my emission - products: - - coefficient: 1 - name: B - scaling factor: 12.3 - type: EMISSION -- gas phase: gas - products: - - name: B - type: EMISSION -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/first_order_loss/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/first_order_loss/bad_reaction_component.json deleted file mode 100644 index 4cca178c..00000000 --- a/test/unit/development/development_unit_configs/reactions/first_order_loss/bad_reaction_component.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "FIRST_ORDER_LOSS", - "gas phase": "gas", - "reactants": [ - { - "Name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/first_order_loss/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/first_order_loss/bad_reaction_component.yaml deleted file mode 100644 index 33f5c65d..00000000 --- a/test/unit/development/development_unit_configs/reactions/first_order_loss/bad_reaction_component.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: Bad reaction component -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - reactants: - - Name: C - type: FIRST_ORDER_LOSS -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/first_order_loss/missing_phase.json b/test/unit/development/development_unit_configs/reactions/first_order_loss/missing_phase.json deleted file mode 100644 index 1379f77d..00000000 --- a/test/unit/development/development_unit_configs/reactions/first_order_loss/missing_phase.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [], - "reactions": [ - { - "type": "FIRST_ORDER_LOSS", - "gas phase": "gas", - "reactants": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/first_order_loss/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/first_order_loss/missing_phase.yaml deleted file mode 100644 index ef54f286..00000000 --- a/test/unit/development/development_unit_configs/reactions/first_order_loss/missing_phase.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- gas phase: gas - reactants: - - name: C - type: FIRST_ORDER_LOSS -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/first_order_loss/too_many_reactants.json b/test/unit/development/development_unit_configs/reactions/first_order_loss/too_many_reactants.json deleted file mode 100644 index 3c3f6a8c..00000000 --- a/test/unit/development/development_unit_configs/reactions/first_order_loss/too_many_reactants.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version": "2.0.0", - "name": "Too many reactants", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "FIRST_ORDER_LOSS", - "gas phase": "gas", - "reactants": [ - { - "name": "C", - "coefficient": 1 - }, - { - "name": "B", - "coefficient": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/first_order_loss/too_many_reactants.yaml b/test/unit/development/development_unit_configs/reactions/first_order_loss/too_many_reactants.yaml deleted file mode 100644 index 20ef4e1d..00000000 --- a/test/unit/development/development_unit_configs/reactions/first_order_loss/too_many_reactants.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: Too many reactants -phases: -- name: gas - species: - - name: A - - name: B - - name: C -reactions: -- gas phase: gas - reactants: - - coefficient: 1 - name: C - - coefficient: 1 - name: B - type: FIRST_ORDER_LOSS -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/first_order_loss/unknown_species.json b/test/unit/development/development_unit_configs/reactions/first_order_loss/unknown_species.json deleted file mode 100644 index 8370ff98..00000000 --- a/test/unit/development/development_unit_configs/reactions/first_order_loss/unknown_species.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "FIRST_ORDER_LOSS", - "gas phase": "gas", - "reactants": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/first_order_loss/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/first_order_loss/unknown_species.yaml deleted file mode 100644 index 6b3ff2e4..00000000 --- a/test/unit/development/development_unit_configs/reactions/first_order_loss/unknown_species.yaml +++ /dev/null @@ -1,15 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - reactants: - - name: C - type: FIRST_ORDER_LOSS -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/first_order_loss/valid.json b/test/unit/development/development_unit_configs/reactions/first_order_loss/valid.json deleted file mode 100644 index 8f51799c..00000000 --- a/test/unit/development/development_unit_configs/reactions/first_order_loss/valid.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid surface", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "FIRST_ORDER_LOSS", - "gas phase": "gas", - "reactants": [ - { - "name": "C", - "coefficient": 1 - } - ], - "name": "my first order loss", - "scaling factor": 12.3, - "__comment": "Strawberries are the superior fruit" - }, - { - "type": "FIRST_ORDER_LOSS", - "gas phase": "gas", - "reactants": [ - { - "name": "C", - "coefficient": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/first_order_loss/valid.yaml b/test/unit/development/development_unit_configs/reactions/first_order_loss/valid.yaml deleted file mode 100644 index c1f80e05..00000000 --- a/test/unit/development/development_unit_configs/reactions/first_order_loss/valid.yaml +++ /dev/null @@ -1,26 +0,0 @@ -name: Valid surface -phases: -- name: gas - species: - - name: A - - name: B - - name: C -reactions: -- __comment: Strawberries are the superior fruit - gas phase: gas - name: my first order loss - reactants: - - coefficient: 1 - name: C - scaling factor: 12.3 - type: FIRST_ORDER_LOSS -- gas phase: gas - reactants: - - coefficient: 1 - name: C - type: FIRST_ORDER_LOSS -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.json b/test/unit/development/development_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.json deleted file mode 100644 index babc1773..00000000 --- a/test/unit/development/development_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "version": "2.0.0", - "name": "Solvent species in not registered in the corresponding phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "C" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "A", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "C", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "B" - } - ] - }, - "name": "my henry's law", - "__comment": "hi" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.yaml b/test/unit/development/development_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.yaml deleted file mode 100644 index 241cff87..00000000 --- a/test/unit/development/development_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.yaml +++ /dev/null @@ -1,32 +0,0 @@ -version: 2.0.0 -name: Solvent species in not registered in the corresponding phase -species: - - name: A - - name: B - - name: C - - name: H2O -phases: - - name: gas - species: - - name: A - - name: B - - name: aqueous - species: - - name: H2O - - name: C -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: A - diffusion coefficient [m2 s-1]: 0.7 - particle: - phase: aqueous - solutes: - - name: C - coefficient: 1.0 - solvent: - - name: B - name: my henry's law - __comment: hi diff --git a/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.json b/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.json deleted file mode 100644 index 90c94eec..00000000 --- a/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "version": "2.0.0", - "name": "Gas species in reactions are not found in gas phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "B" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "H2O", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "B", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.yaml b/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.yaml deleted file mode 100644 index b37db7a1..00000000 --- a/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.yaml +++ /dev/null @@ -1,28 +0,0 @@ -version: 2.0.0 -name: Gas species in reactions are not found in gas phase -species: - - name: A - - name: B - - name: H2O -phases: - - name: gas - species: - - name: A - - name: aqueous - species: - - name: B - - name: H2O -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: H2O - diffusion coefficient [m2 s-1]: 0.7 - particle: - phase: aqueous - solutes: - - name: B - coefficient: 1.0 - solvent: - - name: H2O diff --git a/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.json b/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.json deleted file mode 100644 index 7e78118c..00000000 --- a/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "version": "2.0.0", - "name": "Condensed phase arrhenius using species not in its requested condensed phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "A", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "B", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O" - } - ] - }, - "name": "my henry's law", - "__comment": "hi" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.yaml b/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.yaml deleted file mode 100644 index 1978b1e2..00000000 --- a/test/unit/development/development_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.yaml +++ /dev/null @@ -1,30 +0,0 @@ -version: 2.0.0 -name: Condensed phase arrhenius using species not in its requested condensed phase -species: - - name: A - - name: B - - name: H2O -phases: - - name: gas - species: - - name: A - - name: B - - name: aqueous - species: - - name: H2O -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: A - diffusion coefficient [m2 s-1]: 0.7 - particle: - phase: aqueous - solutes: - - name: B - coefficient: 1.0 - solvent: - - name: H2O - name: my henry's law - __comment: hi diff --git a/test/unit/development/development_unit_configs/reactions/henrys_law/unknown_species.json b/test/unit/development/development_unit_configs/reactions/henrys_law/unknown_species.json deleted file mode 100644 index 8eaad466..00000000 --- a/test/unit/development/development_unit_configs/reactions/henrys_law/unknown_species.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "B" - }, - { - "name": "H2O" - } - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "C", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "B", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O" - } - ] - } - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/henrys_law/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/henrys_law/unknown_species.yaml deleted file mode 100644 index b0f22388..00000000 --- a/test/unit/development/development_unit_configs/reactions/henrys_law/unknown_species.yaml +++ /dev/null @@ -1,29 +0,0 @@ -version: 2.0.0 -name: Unknown species -species: - - name: A - - name: B - - name: H2O -phases: - - name: gas - species: - - name: A - diffusion coefficient [m2 s-1]: 0.7 - - name: aqueous - species: - - name: B - - name: H2O -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: C - diffusion coefficient [m2 s-1]: 0.7 - particle: - phase: aqueous - solutes: - - name: B - coefficient: 1.0 - solvent: - - name: H2O diff --git a/test/unit/development/development_unit_configs/reactions/henrys_law/valid.json b/test/unit/development/development_unit_configs/reactions/henrys_law/valid.json deleted file mode 100644 index c5bcb41a..00000000 --- a/test/unit/development/development_unit_configs/reactions/henrys_law/valid.json +++ /dev/null @@ -1,102 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid surface", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "B" - }, - { - "name": "H2O" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "A", - "diffusion coefficient [m2 s-1]": 0.7 - } - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "B", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O" - } - ] - }, - "name": "my henry's law", - "__comment": "B condensed phase production (kg/m2/s)" - }, - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - { - "name": "A" - } - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - { - "name": "B", - "coefficient": 1.0 - }, - { - "name": "C", - "coefficient": 1.0 - } - ], - "solvent": [ - { - "name": "H2O", - "coefficient": 1.0 - } - ] - } - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/henrys_law/valid.yaml b/test/unit/development/development_unit_configs/reactions/henrys_law/valid.yaml deleted file mode 100644 index af35edb0..00000000 --- a/test/unit/development/development_unit_configs/reactions/henrys_law/valid.yaml +++ /dev/null @@ -1,52 +0,0 @@ -version: 2.0.0 -name: Valid surface - -species: - - name: A - - name: B - - name: H2O - - name: C - -phases: - - name: gas - species: - - name: A - - name: aqueous - species: - - name: B - - name: H2O - - name: C - -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: A - diffusion coefficient [m2 s-1]: 0.7 - particle: - phase: aqueous - solutes: - - name: B - coefficient: 1.0 - solvent: - - name: H2O - name: my henry's law - __comment: B condensed phase production (kg/m2/s) - - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - name: A - diffusion coefficient [m2 s-1]: 0.7 - particle: - phase: aqueous - solutes: - - name: B - coefficient: 1.0 - - name: C - coefficient: 1.0 - solvent: - - name: H2O - coefficient: 1.0 diff --git a/test/unit/development/development_unit_configs/reactions/photolysis/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/photolysis/bad_reaction_component.json deleted file mode 100644 index df753d1a..00000000 --- a/test/unit/development/development_unit_configs/reactions/photolysis/bad_reaction_component.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "PHOTOLYSIS", - "gas phase": "gas", - "reactants": [ - { - "name": "A", - "Coefficient": 1.2 - } - ], - "products": [ - { - "name": "B", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/photolysis/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/photolysis/bad_reaction_component.yaml deleted file mode 100644 index d836c363..00000000 --- a/test/unit/development/development_unit_configs/reactions/photolysis/bad_reaction_component.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Bad reaction component -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - coefficient: 0.2 - name: B - reactants: - - Coefficient: 1.2 - name: A - type: PHOTOLYSIS -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/photolysis/missing_phase.json b/test/unit/development/development_unit_configs/reactions/photolysis/missing_phase.json deleted file mode 100644 index ca28ef33..00000000 --- a/test/unit/development/development_unit_configs/reactions/photolysis/missing_phase.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [], - "reactions": [ - { - "type": "PHOTOLYSIS", - "gas phase": "gas", - "reactants": [ - { - "name": "B", - "coefficient": 1.2 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/photolysis/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/photolysis/missing_phase.yaml deleted file mode 100644 index 49842303..00000000 --- a/test/unit/development/development_unit_configs/reactions/photolysis/missing_phase.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- gas phase: gas - products: - - coefficient: 0.2 - name: C - reactants: - - coefficient: 1.2 - name: B - type: PHOTOLYSIS -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/photolysis/more_than_one_reactant.json b/test/unit/development/development_unit_configs/reactions/photolysis/more_than_one_reactant.json deleted file mode 100644 index c6ac0371..00000000 --- a/test/unit/development/development_unit_configs/reactions/photolysis/more_than_one_reactant.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "version": "2.0.0", - "name": "more than one reactant", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - }, - { - "name": "surface reacting phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "PHOTOLYSIS", - "gas phase": "gas", - "__comment": "hi", - "reactants": [ - { - "name": "B" - }, - { - "name": "A" - } - ], - "products": [ - { - "name": "C", - "coefficient": 1 - } - ], - "name": "my photolysis", - "scaling factor": 12.3 - }, - { - "type": "PHOTOLYSIS", - "gas phase": "gas", - "reactants": [ - { - "name": "B", - "coefficient": 1.2 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/photolysis/more_than_one_reactant.yaml b/test/unit/development/development_unit_configs/reactions/photolysis/more_than_one_reactant.yaml deleted file mode 100644 index a3710036..00000000 --- a/test/unit/development/development_unit_configs/reactions/photolysis/more_than_one_reactant.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: more than one reactant -phases: -- name: gas - species: - - name: A - - name: B - - name: C -- name: surface reacting phase - species: - - name: A - - name: B - - name: C -reactions: -- __comment: hi - gas phase: gas - name: my photolysis - products: - - coefficient: 1 - name: C - reactants: - - name: B - - name: A - scaling factor: 12.3 - type: PHOTOLYSIS -- gas phase: gas - products: - - coefficient: 0.2 - name: C - reactants: - - coefficient: 1.2 - name: B - type: PHOTOLYSIS -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/photolysis/unknown_species.json b/test/unit/development/development_unit_configs/reactions/photolysis/unknown_species.json deleted file mode 100644 index dcb12f45..00000000 --- a/test/unit/development/development_unit_configs/reactions/photolysis/unknown_species.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "PHOTOLYSIS", - "gas phase": "gas", - "reactants": [ - { - "name": "B", - "coefficient": 1.2 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/photolysis/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/photolysis/unknown_species.yaml deleted file mode 100644 index 0ee34dba..00000000 --- a/test/unit/development/development_unit_configs/reactions/photolysis/unknown_species.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - coefficient: 0.2 - name: C - reactants: - - coefficient: 1.2 - name: B - type: PHOTOLYSIS -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/photolysis/valid.json b/test/unit/development/development_unit_configs/reactions/photolysis/valid.json deleted file mode 100644 index a0c0ba26..00000000 --- a/test/unit/development/development_unit_configs/reactions/photolysis/valid.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid photolysis", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - }, - { - "name": "surface reacting phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "PHOTOLYSIS", - "gas phase": "gas", - "__comment": "hi", - "reactants": [ - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 1 - } - ], - "name": "my photolysis", - "scaling factor": 12.3 - }, - { - "type": "PHOTOLYSIS", - "gas phase": "gas", - "reactants": [ - { - "name": "B", - "coefficient": 1.2 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/photolysis/valid.yaml b/test/unit/development/development_unit_configs/reactions/photolysis/valid.yaml deleted file mode 100644 index 451f22a6..00000000 --- a/test/unit/development/development_unit_configs/reactions/photolysis/valid.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: Valid photolysis -phases: -- name: gas - species: - - name: A - - name: B - - name: C -- name: surface reacting phase - species: - - name: A - - name: B - - name: C -reactions: -- __comment: hi - gas phase: gas - name: my photolysis - products: - - coefficient: 1 - name: C - reactants: - - coefficient: 1 - name: B - scaling factor: 12.3 - type: PHOTOLYSIS -- gas phase: gas - products: - - coefficient: 0.2 - name: C - reactants: - - coefficient: 1.2 - name: B - type: PHOTOLYSIS -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase.json b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase.json deleted file mode 100644 index a848606f..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid surface", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - } - ] - } - ], - "reactions": [ - { - "type": "SIMPOL_PHASE_TRANSFER", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "condensed phase": "aqueous", - "condensed-phase species": [ - { - "name": "B", - "coefficient": 1 - } - ], - "B": [ - -1.97E+03, - 2.91E+00, - 1.96E-03, - -4.96E-01 - ], - "name": "my simpol" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase.yaml b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase.yaml deleted file mode 100644 index 3c489672..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Valid surface -phases: -- name: gas - species: - - name: A -reactions: -- B: - - -1970.0 - - 2.91 - - 0.00196 - - -0.496 - condensed phase: aqueous - condensed-phase species: - - name: B - coefficient: 1 - gas phase: gas - gas-phase species: - - name: A - coefficient: 1 - name: my simpol - type: SIMPOL_PHASE_TRANSFER -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase_species_in_aqueous_phase.json b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase_species_in_aqueous_phase.json deleted file mode 100644 index c1483a2d..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase_species_in_aqueous_phase.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing gas phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "A" - } - ] - } - ], - "reactions": [ - { - "type": "SIMPOL_PHASE_TRANSFER", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "condensed phase": "aqueous", - "condensed-phase species": [ - { - "name": "B", - "coefficient": 1 - } - ], - "B": [ - -1.97E+03, - 2.91E+00, - 1.96E-03, - -4.96E-01 - ], - "name": "my simpol" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase_species_in_aqueous_phase.yaml b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase_species_in_aqueous_phase.yaml deleted file mode 100644 index b84766d1..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase_species_in_aqueous_phase.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: Missing gas phase -phases: -- name: gas - species: - - name: A -- name: aqueous - species: - - name: A -reactions: -- B: - - -1970.0 - - 2.91 - - 0.00196 - - -0.496 - condensed phase: aqueous - condensed-phase species: - - name: B - coefficient: 1 - gas phase: gas - gas-phase species: - - name: A - coefficient: 1 - name: my simpol - type: SIMPOL_PHASE_TRANSFER -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase.json b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase.json deleted file mode 100644 index 852a78a1..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing gas phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "SIMPOL_PHASE_TRANSFER", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "condensed phase": "aqueous", - "condensed-phase species": [ - { - "name": "B", - "coefficient": 1 - } - ], - "B": [ - -1.97E+03, - 2.91E+00, - 1.96E-03, - -4.96E-01 - ], - "name": "my simpol" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase.yaml b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase.yaml deleted file mode 100644 index 43eaf4b6..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase.yaml +++ /dev/null @@ -1,25 +0,0 @@ -name: Missing gas phase -phases: -- name: aqueous - species: - - name: B -reactions: -- B: - - -1970.0 - - 2.91 - - 0.00196 - - -0.496 - condensed phase: aqueous - condensed-phase species: - - name: B - coefficient: 1 - gas phase: gas - gas-phase species: - - name: A - coefficient: 1 - name: my simpol - type: SIMPOL_PHASE_TRANSFER -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase_species_in_gas_phase.json b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase_species_in_gas_phase.json deleted file mode 100644 index 75df0e7d..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase_species_in_gas_phase.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing gas phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "B" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "SIMPOL_PHASE_TRANSFER", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "condensed phase": "aqueous", - "condensed-phase species": [ - { - "name": "B", - "coefficient": 1 - } - ], - "B": [ - -1.97E+03, - 2.91E+00, - 1.96E-03, - -4.96E-01 - ], - "name": "my simpol" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase_species_in_gas_phase.yaml b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase_species_in_gas_phase.yaml deleted file mode 100644 index d908be79..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase_species_in_gas_phase.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: Missing gas phase -phases: -- name: gas - species: - - name: B -- name: aqueous - species: - - name: B -reactions: -- B: - - -1970.0 - - 2.91 - - 0.00196 - - -0.496 - condensed phase: aqueous - condensed-phase species: - - name: B - coefficient: 1 - gas phase: gas - gas-phase species: - - name: A - coefficient: 1 - name: my simpol - type: SIMPOL_PHASE_TRANSFER -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/unknown_species.json b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/unknown_species.json deleted file mode 100644 index fe1d362c..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/unknown_species.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "SIMPOL_PHASE_TRANSFER", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "C", - "coefficient": 1 - } - ], - "condensed phase": "aqueous", - "condensed-phase species": [ - { - "name": "B", - "coefficient": 1 - } - ], - "B": [ - -1.97E+03, - 2.91E+00, - 1.96E-03, - -4.96E-01 - ], - "name": "my simpol" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/unknown_species.yaml deleted file mode 100644 index 7f77d491..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/unknown_species.yaml +++ /dev/null @@ -1,28 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A -- name: aqueous - species: - - name: B -reactions: -- B: - - -1970.0 - - 2.91 - - 0.00196 - - -0.496 - condensed phase: aqueous - condensed-phase species: - - name: B - coefficient: 1 - gas phase: gas - gas-phase species: - - name: C - coefficient: 1 - name: my simpol - type: SIMPOL_PHASE_TRANSFER -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/valid.json b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/valid.json deleted file mode 100644 index 97a98546..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/valid.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid surface", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - } - ] - }, - { - "name": "aqueous", - "species": [ - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "SIMPOL_PHASE_TRANSFER", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "condensed phase": "aqueous", - "condensed-phase species": [ - { - "name": "B", - "coefficient": 1 - } - ], - "B": [ - -1.97E+03, - 2.91E+00, - 1.96E-03, - -4.96E-01 - ], - "name": "my simpol", - "__comment": "cereal is also soup" - }, - { - "type": "SIMPOL_PHASE_TRANSFER", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "condensed phase": "aqueous", - "condensed-phase species": [ - { - "name": "B", - "coefficient": 1 - } - ], - "B": [ - -1.97E+03, - 2.91E+00, - 1.96E-03, - -4.96E-01 - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/valid.yaml b/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/valid.yaml deleted file mode 100644 index 90749998..00000000 --- a/test/unit/development/development_unit_configs/reactions/simpol_phase_transfer/valid.yaml +++ /dev/null @@ -1,43 +0,0 @@ -version: 2.0.0 -name: Valid surface -species: - - name: A - - name: B -phases: - - name: gas - species: - - name: A - - name: aqueous - species: - - name: B -reactions: - - type: SIMPOL_PHASE_TRANSFER - gas phase: gas - gas-phase species: - - name: A - coefficient: 1 - condensed phase: aqueous - condensed-phase species: - - name: B - coefficient: 1 - B: - - -1970.0 - - 2.91 - - 0.00196 - - -0.496 - name: my simpol - __comment: cereal is also soup - - type: SIMPOL_PHASE_TRANSFER - gas phase: gas - gas-phase species: - - name: A - coefficient: 1 - condensed phase: aqueous - condensed-phase species: - - name: B - coefficient: 1 - B: - - -1970.0 - - 2.91 - - 0.00196 - - -0.496 diff --git a/test/unit/development/development_unit_configs/reactions/surface/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/surface/bad_reaction_component.json deleted file mode 100644 index 73e68672..00000000 --- a/test/unit/development/development_unit_configs/reactions/surface/bad_reaction_component.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - }, - { - "name": "surface reacting phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "SURFACE", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "reaction probability": 2.0e-2, - "gas-phase products": [ - { - "Name": "B", - "coefficient": 1 - } - ], - "condensed phase": "surface reacting phase", - "name": "my surface", - "__coment": "key lime pie is superior to all other pies" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/surface/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/surface/bad_reaction_component.yaml deleted file mode 100644 index f9f7c24f..00000000 --- a/test/unit/development/development_unit_configs/reactions/surface/bad_reaction_component.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Bad reaction component -phases: -- name: gas - species: - - name: A - - name: B -- name: surface reacting phase - species: - - name: A - - name: B -reactions: -- __coment: key lime pie is superior to all other pies - condensed phase: surface reacting phase - gas phase: gas - gas-phase products: - - Name: B - coefficient: 1 - gas-phase species: - - name: "A" - coefficient: 1 - name: my surface - reaction probability: 0.02 - type: SURFACE -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/surface/missing_condensed_phase.json b/test/unit/development/development_unit_configs/reactions/surface/missing_condensed_phase.json deleted file mode 100644 index 569cf997..00000000 --- a/test/unit/development/development_unit_configs/reactions/surface/missing_condensed_phase.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing condensed phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "SURFACE", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "gas-phase products": [ - { - "name": "B", - "__optional thing": "hello" - }, - { - "name": "C" - } - ], - "condensed phase": "surface reacting phase" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/surface/missing_condensed_phase.yaml b/test/unit/development/development_unit_configs/reactions/surface/missing_condensed_phase.yaml deleted file mode 100644 index 77e8e0bd..00000000 --- a/test/unit/development/development_unit_configs/reactions/surface/missing_condensed_phase.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: Missing condensed phase -phases: -- name: gas - species: - - name: A - - name: B - - name: C -reactions: -- condensed phase: surface reacting phase - gas phase: gas - gas-phase products: - - __optional thing: hello - name: B - - name: C - gas-phase species: - - name: "A" - coefficient: 1 - type: SURFACE -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/surface/missing_gas_phase.json b/test/unit/development/development_unit_configs/reactions/surface/missing_gas_phase.json deleted file mode 100644 index b0ddb2a6..00000000 --- a/test/unit/development/development_unit_configs/reactions/surface/missing_gas_phase.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing gas phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "surface reacting phase", - "species": [ - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "SURFACE", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "gas-phase products": [ - { - "name": "B", - "__optional thing": "hello" - }, - { - "name": "C" - } - ], - "condensed phase": "surface reacting phase" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/surface/missing_gas_phase.yaml b/test/unit/development/development_unit_configs/reactions/surface/missing_gas_phase.yaml deleted file mode 100644 index 464a2be4..00000000 --- a/test/unit/development/development_unit_configs/reactions/surface/missing_gas_phase.yaml +++ /dev/null @@ -1,22 +0,0 @@ -name: Missing gas phase -phases: -- name: surface reacting phase - species: - - name: B - - name: C -reactions: -- condensed phase: surface reacting phase - gas phase: gas - gas-phase products: - - __optional thing: hello - name: B - - name: C - gas-phase species: - - name: "A" - coefficient: 1 - type: SURFACE -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/surface/unknown_species.json b/test/unit/development/development_unit_configs/reactions/surface/unknown_species.json deleted file mode 100644 index a1d4b624..00000000 --- a/test/unit/development/development_unit_configs/reactions/surface/unknown_species.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - }, - { - "name": "surface reacting phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "SURFACE", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "reaction probability": 2.0e-2, - "gas-phase products": [ - { - "name": "B", - "coefficient": 1 - }, - { - "name": "C", - "coefficient": 1 - } - ], - "condensed phase": "surface reacting phase" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/surface/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/surface/unknown_species.yaml deleted file mode 100644 index 34d9840c..00000000 --- a/test/unit/development/development_unit_configs/reactions/surface/unknown_species.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A - - name: B -- name: surface reacting phase - species: - - name: A - - name: B -reactions: -- condensed phase: surface reacting phase - gas phase: gas - gas-phase products: - - coefficient: 1 - name: B - - coefficient: 1 - name: C - gas-phase species: - - name: "A" - coefficient: 1 - reaction probability: 0.02 - type: SURFACE -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/surface/valid.json b/test/unit/development/development_unit_configs/reactions/surface/valid.json deleted file mode 100644 index a446cdc4..00000000 --- a/test/unit/development/development_unit_configs/reactions/surface/valid.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid surface", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - }, - { - "name": "surface reacting phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "SURFACE", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "reaction probability": 2.0e-2, - "gas-phase products": [ - { - "name": "B", - "coefficient": 1 - }, - { - "name": "C", - "coefficient": 1 - } - ], - "condensed phase": "surface reacting phase", - "name": "my surface", - "__comment": "key lime pie is superior to all other pies" - }, - { - "type": "SURFACE", - "gas phase": "gas", - "gas-phase species": [ - { - "name": "A", - "coefficient": 1 - } - ], - "gas-phase products": [ - { - "name": "B", - "__optional thing": "hello" - }, - { - "name": "C" - } - ], - "condensed phase": "surface reacting phase" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/surface/valid.yaml b/test/unit/development/development_unit_configs/reactions/surface/valid.yaml deleted file mode 100644 index 165c5418..00000000 --- a/test/unit/development/development_unit_configs/reactions/surface/valid.yaml +++ /dev/null @@ -1,47 +0,0 @@ -version: "2.0.0" -name: "Valid surface" - -species: - - name: "A" - - name: "B" - - name: "C" - -phases: - - name: "gas" - species: - - name: "A" - - name: "B" - - name: "C" - - - name: "surface reacting phase" - species: - - name: "A" - - name: "B" - - name: "C" - -reactions: - - type: "SURFACE" - gas phase: "gas" - gas-phase species: - - name: "A" - coefficient: 1 - reaction probability: 2.0e-2 - gas-phase products: - - name: "B" - coefficient: 1 - - name: "C" - coefficient: 1 - condensed phase: "surface reacting phase" - name: "my surface" - __comment: "key lime pie is superior to all other pies" - - - type: "SURFACE" - gas phase: "gas" - gas-phase species: - - name: "A" - coefficient: 1 - gas-phase products: - - name: "B" - __optional thing: "hello" - - name: "C" - condensed phase: "surface reacting phase" diff --git a/test/unit/development/development_unit_configs/reactions/taylor_series/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/taylor_series/bad_reaction_component.json deleted file mode 100644 index d2db359f..00000000 --- a/test/unit/development/development_unit_configs/reactions/taylor_series/bad_reaction_component.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "TAYLOR_SERIES", - "gas phase": "gas", - "reactants": [ - { - "Name": "A" - } - ], - "products": [ - { - "name": "B" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/taylor_series/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/taylor_series/bad_reaction_component.yaml deleted file mode 100644 index 985e3cb1..00000000 --- a/test/unit/development/development_unit_configs/reactions/taylor_series/bad_reaction_component.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Bad reaction component -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - name: B - reactants: - - name: A - type: TAYLOR_SERIES -species: -- Name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/taylor_series/missing_phase.json b/test/unit/development/development_unit_configs/reactions/taylor_series/missing_phase.json deleted file mode 100644 index a136d87c..00000000 --- a/test/unit/development/development_unit_configs/reactions/taylor_series/missing_phase.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [], - "reactions": [ - { - "type": "TAYLOR_SERIES", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/taylor_series/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/taylor_series/missing_phase.yaml deleted file mode 100644 index 7d570684..00000000 --- a/test/unit/development/development_unit_configs/reactions/taylor_series/missing_phase.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- gas phase: gas - products: - - name: C - reactants: - - name: A - type: TAYLOR_SERIES -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/taylor_series/mutually_exclusive.json b/test/unit/development/development_unit_configs/reactions/taylor_series/mutually_exclusive.json deleted file mode 100644 index 98212368..00000000 --- a/test/unit/development/development_unit_configs/reactions/taylor_series/mutually_exclusive.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "version": "2.0.0", - "name": "Mutually Exclusive", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "TAYLOR_SERIES", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "B" - } - ], - "C": 10, - "Ea": 0.5 - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/taylor_series/mutually_exclusive.yaml b/test/unit/development/development_unit_configs/reactions/taylor_series/mutually_exclusive.yaml deleted file mode 100644 index 5e7e7853..00000000 --- a/test/unit/development/development_unit_configs/reactions/taylor_series/mutually_exclusive.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Mutually Exclusive -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- C: 10 - Ea: 0.5 - gas phase: gas - products: - - name: B - reactants: - - name: A - type: TAYLOR_SERIES -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/taylor_series/unknown_species.json b/test/unit/development/development_unit_configs/reactions/taylor_series/unknown_species.json deleted file mode 100644 index a9a2d0c5..00000000 --- a/test/unit/development/development_unit_configs/reactions/taylor_series/unknown_species.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "TAYLOR_SERIES", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/taylor_series/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/taylor_series/unknown_species.yaml deleted file mode 100644 index f6d49972..00000000 --- a/test/unit/development/development_unit_configs/reactions/taylor_series/unknown_species.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - name: C - reactants: - - name: A - type: TAYLOR_SERIES -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/taylor_series/valid.json b/test/unit/development/development_unit_configs/reactions/taylor_series/valid.json deleted file mode 100644 index ed1aed21..00000000 --- a/test/unit/development/development_unit_configs/reactions/taylor_series/valid.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid taylor_series", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "TAYLOR_SERIES", - "gas phase": "gas", - "reactants": [ - { - "name": "A", - "coefficient": 1 - } - ], - "products": [ - { - "name": "B", - "coefficient": 1.2 - }, - { - "name": "C", - "coefficient": 0.3 - } - ], - "A": 32.1, - "B": -2.3, - "C": 102.3, - "D": 63.4, - "E": -1.3, - "taylor coefficients": [ - 1.0, - 2.0, - 3.0 - ], - "name": "my taylor_series", - "__solver_param": 0.1 - }, - { - "type": "TAYLOR_SERIES", - "gas phase": "gas", - "reactants": [ - { - "name": "A", - "coefficient": 2 - }, - { - "name": "B", - "coefficient": 0.1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.5, - "__optional thing": "hello" - } - ], - "A": 3.1, - "B": -0.3, - "C": 12.3, - "D": 6.4, - "E": -0.3, - "taylor coefficients": [ - 10.5 - ], - "name": "my taylor_series2" - }, - { - "type": "TAYLOR_SERIES", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/taylor_series/valid.yaml b/test/unit/development/development_unit_configs/reactions/taylor_series/valid.yaml deleted file mode 100644 index 0e7be1df..00000000 --- a/test/unit/development/development_unit_configs/reactions/taylor_series/valid.yaml +++ /dev/null @@ -1,59 +0,0 @@ -name: Valid taylor_series -phases: -- name: gas - species: - - name: A - - name: B - - name: C -reactions: -- A: 32.1 - B: -2.3 - C: 102.3 - D: 63.4 - E: -1.3 - taylor coefficients: - - 1.0 - - 2.0 - - 3.0 - __solver_param: 0.1 - gas phase: gas - name: my taylor_series - products: - - coefficient: 1.2 - name: B - - coefficient: 0.3 - name: C - reactants: - - coefficient: 1 - name: A - type: TAYLOR_SERIES -- A: 3.1 - B: -0.3 - C: 12.3 - D: 6.4 - E: -0.3 - taylor coefficients: - - 10.5 - gas phase: gas - name: my taylor_series2 - products: - - __optional thing: hello - coefficient: 0.5 - name: C - reactants: - - coefficient: 2 - name: A - - coefficient: 0.1 - name: B - type: TAYLOR_SERIES -- gas phase: gas - products: - - name: C - reactants: - - name: A - type: TAYLOR_SERIES -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/contains_nonstandard_key.json b/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/contains_nonstandard_key.json deleted file mode 100644 index f3d156bf..00000000 --- a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/contains_nonstandard_key.json +++ /dev/null @@ -1,127 +0,0 @@ -{ - "version": "2.0.0", - "name": "Contains Nonstandard Key", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - }, - { - "name": "quz" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - }, - { - "name": "quz" - } - ] - } - ], - "reactions": [ - { - "type": "TERNARY_CHEMICAL_ACTIVATION", - "gas phase": "gas", - "Reactants": [ - { - "name": "foo", - "coefficient": 1 - }, - { - "name": "quz", - "coefficient": 2 - } - ], - "products": [ - { - "name": "bar", - "coefficient": 1.0 - }, - { - "name": "baz", - "coefficient": 3.2 - } - ] - }, - { - "type": "TERNARY_CHEMICAL_ACTIVATION", - "gas phase": "gas", - "reactants": [ - { - "name": "bar", - "coefficient": 1 - }, - { - "name": "baz", - "coefficient": 1 - } - ], - "Products": [ - { - "name": "bar", - "coefficient": 0.5 - }, - { - "name": "foo", - "coefficient": 0.0 - } - ], - "k0_A": 32.1, - "k0_B": -2.3, - "k0_C": 102.3, - "kinf_A": 63.4, - "kinf_B": -1.3, - "kinf_C": 908.5, - "Fc": 1.3, - "N": 32.1 - }, - { - "type": "TERNARY_CHEMICAL_ACTIVATION", - "gas phase": "gas", - "reactants": [ - { - "name": "bar", - "coefficient": 1 - }, - { - "name": "baz", - "coefficient": 1 - } - ], - "products": [ - { - "name": "bar", - "coefficient": 0.5 - }, - { - "name": "foo", - "coefficient": 0.0 - } - ], - "k0_a": 32.1, - "k0_b": -2.3, - "k0_c": 102.3, - "kinf_a": 63.4, - "kinf_b": -1.3, - "kinf_c": 908.5, - "fc": 1.3, - "n": 32.1 - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/contains_nonstandard_key.yaml b/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/contains_nonstandard_key.yaml deleted file mode 100644 index 8a9a3a3a..00000000 --- a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/contains_nonstandard_key.yaml +++ /dev/null @@ -1,68 +0,0 @@ ---- -version: 2.0.0 -name: Contains Nonstandard Key -species: -- name: foo -- name: bar -- name: baz -- name: quz -phases: -- name: gas - species: - - name: foo - - name: bar - - name: baz - - name: quz -reactions: -- type: TERNARY_CHEMICAL_ACTIVATION - gas phase: gas - Reactants: - - name: foo - coefficient: 1 - - name: quz - coefficient: 2 - products: - - name: bar - coefficient: 1 - - name: baz - coefficient: 3.2 -- type: TERNARY_CHEMICAL_ACTIVATION - gas phase: gas - reactants: - - name: bar - coefficient: 1 - - name: baz - coefficient: 1 - Products: - - name: bar - coefficient: 0.5 - - name: foo - coefficient: 0 - k0_A: 32.1 - k0_B: -2.3 - k0_C: 102.3 - kinf_A: 63.4 - kinf_B: -1.3 - kinf_C: 908.5 - Fc: 1.3 - "N": 32.1 -- type: TERNARY_CHEMICAL_ACTIVATION - gas phase: gas - reactants: - - name: bar - coefficient: 1 - - name: baz - coefficient: 1 - products: - - name: bar - coefficient: 0.5 - - name: foo - coefficient: 0 - k0_a: 32.1 - k0_b: -2.3 - k0_c: 102.3 - kinf_a: 63.4 - kinf_b: -1.3 - kinf_c: 908.5 - fc: 1.3 - "n": 32.1 diff --git a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_products.json b/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_products.json deleted file mode 100644 index 183f0966..00000000 --- a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_products.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing products", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - }, - { - "name": "quz" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - }, - { - "name": "quz" - } - ] - } - ], - "reactions": [ - { - "type": "TERNARY_CHEMICAL_ACTIVATION", - "gas phase": "gas", - "reactants": [ - { - "name": "foo", - "coefficient": 1 - }, - { - "name": "quz", - "coefficient": 2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_products.yaml b/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_products.yaml deleted file mode 100644 index df24feb5..00000000 --- a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_products.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- -version: 2.0.0 -name: Missing products -species: -- name: foo -- name: bar -- name: baz -- name: quz -phases: -- name: gas - species: - - name: foo - - name: bar - - name: baz - - name: quz -reactions: -- type: TERNARY_CHEMICAL_ACTIVATION - gas phase: gas - reactants: - - name: foo - coefficient: 1 - - name: quz - coefficient: 2 diff --git a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_reactants.json b/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_reactants.json deleted file mode 100644 index 519a19e4..00000000 --- a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_reactants.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing reactants", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - }, - { - "name": "quz" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - }, - { - "name": "quz" - } - ] - } - ], - "reactions": [ - { - "type": "TERNARY_CHEMICAL_ACTIVATION", - "gas phase": "gas", - "products": [ - { - "name": "bar", - "yield": 1.0 - }, - { - "name": "baz", - "yield": 3.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_reactants.yaml b/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_reactants.yaml deleted file mode 100644 index bbbe7423..00000000 --- a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/missing_reactants.yaml +++ /dev/null @@ -1,23 +0,0 @@ ---- -version: 2.0.0 -name: Missing reactants -species: -- name: foo -- name: bar -- name: baz -- name: quz -phases: -- name: gas - species: - - name: foo - - name: bar - - name: baz - - name: quz -reactions: -- type: TERNARY_CHEMICAL_ACTIVATION - gas phase: gas - products: - - name: bar - yield: 1 - - name: baz - yield: 3.2 diff --git a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/unknown_species.json b/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/unknown_species.json deleted file mode 100644 index 843a933a..00000000 --- a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/unknown_species.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - }, - { - "name": "quz" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - }, - { - "name": "quz" - } - ] - } - ], - "reactions": [ - { - "type": "TERNARY_CHEMICAL_ACTIVATION", - "gas phase": "gas", - "reactants": [ - { - "name": "foo", - "coefficient": 1 - }, - { - "name": "quz", - "coefficient": 2 - } - ], - "products": [ - { - "name": "bar", - "coefficient": 1.0 - }, - { - "name": "baz", - "coefficient": 3.2 - } - ] - }, - { - "__optional thing": "hello", - "type": "TERNARY_CHEMICAL_ACTIVATION", - "gas phase": "gas", - "reactants": [ - { - "name": "bar", - "coefficient": 1 - }, - { - "name": "baz", - "coefficient": 1 - } - ], - "products": [ - { - "name": "bar", - "coefficient": 0.5 - }, - { - "name": "FooFoo", - "coefficient": 0.0 - } - ], - "k0_A": 32.1, - "k0_B": -2.3, - "k0_C": 102.3, - "kinf_A": 63.4, - "kinf_B": -1.3, - "kinf_C": 908.5, - "Fc": 1.3, - "N": 32.1, - "name": "my ternary chemical activation" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/unknown_species.yaml deleted file mode 100644 index 6a38908a..00000000 --- a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/unknown_species.yaml +++ /dev/null @@ -1,52 +0,0 @@ -version: 2.0.0 -name: Valid -species: - - name: foo - - name: bar - - name: baz - - name: quz - -phases: - - name: gas - species: - - name: foo - - name: bar - - name: baz - - name: quz - -reactions: - - type: TERNARY_CHEMICAL_ACTIVATION - gas phase: gas - reactants: - - name: foo - coefficient: 1 - - name: quz - coefficient: 2 - products: - - name: bar - coefficient: 1.0 - - name: baz - coefficient: 3.2 - - - __optional thing: hello - type: TERNARY_CHEMICAL_ACTIVATION - gas phase: gas - reactants: - - name: bar - coefficient: 1 - - name: baz - coefficient: 1 - products: - - name: bar - coefficient: 0.5 - - name: FooFoo - coefficient: 0.0 - k0_A: 32.1 - k0_B: -2.3 - k0_C: 102.3 - kinf_A: 63.4 - kinf_B: -1.3 - kinf_C: 908.5 - Fc: 1.3 - N: 32.1 - name: my ternary chemical activation diff --git a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/valid.json b/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/valid.json deleted file mode 100644 index d0f2e820..00000000 --- a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/valid.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - }, - { - "name": "quz" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "foo" - }, - { - "name": "bar" - }, - { - "name": "baz" - }, - { - "name": "quz" - } - ] - } - ], - "reactions": [ - { - "type": "TERNARY_CHEMICAL_ACTIVATION", - "gas phase": "gas", - "reactants": [ - { - "name": "foo", - "coefficient": 1 - }, - { - "name": "quz", - "coefficient": 2 - } - ], - "products": [ - { - "name": "bar", - "coefficient": 1.0 - }, - { - "name": "baz", - "coefficient": 3.2 - } - ] - }, - { - "__optional thing": "hello", - "type": "TERNARY_CHEMICAL_ACTIVATION", - "gas phase": "gas", - "reactants": [ - { - "name": "bar", - "coefficient": 1 - }, - { - "name": "baz", - "coefficient": 1 - } - ], - "products": [ - { - "name": "bar", - "coefficient": 0.5 - }, - { - "name": "foo", - "coefficient": 0.0 - } - ], - "k0_A": 32.1, - "k0_B": -2.3, - "k0_C": 102.3, - "kinf_A": 63.4, - "kinf_B": -1.3, - "kinf_C": 908.5, - "Fc": 1.3, - "N": 32.1, - "name": "my ternary chemical activation" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/valid.yaml b/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/valid.yaml deleted file mode 100644 index 21d8d484..00000000 --- a/test/unit/development/development_unit_configs/reactions/ternary_chemical_activation/valid.yaml +++ /dev/null @@ -1,50 +0,0 @@ ---- -version: 2.0.0 -name: Valid -species: -- name: foo -- name: bar -- name: baz -- name: quz -phases: -- name: gas - species: - - name: foo - - name: bar - - name: baz - - name: quz -reactions: -- type: TERNARY_CHEMICAL_ACTIVATION - gas phase: gas - reactants: - - name: foo - coefficient: 1 - - name: quz - coefficient: 2 - products: - - name: bar - coefficient: 1 - - name: baz - coefficient: 3.2 -- type: TERNARY_CHEMICAL_ACTIVATION - __optional thing: hello - gas phase: gas - reactants: - - name: bar - coefficient: 1 - - name: baz - coefficient: 1 - products: - - name: bar - coefficient: 0.5 - - name: foo - coefficient: 0 - k0_A: 32.1 - k0_B: -2.3 - k0_C: 102.3 - kinf_A: 63.4 - kinf_B: -1.3 - kinf_C: 908.5 - Fc: 1.3 - "N": 32.1 - name: my ternary chemical activation diff --git a/test/unit/development/development_unit_configs/reactions/troe/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/troe/bad_reaction_component.json deleted file mode 100644 index 71bdf348..00000000 --- a/test/unit/development/development_unit_configs/reactions/troe/bad_reaction_component.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "TROE", - "gas phase": "gas", - "reactants": [ - { - "Name": "A" - } - ], - "products": [ - { - "name": "B" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/troe/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/troe/bad_reaction_component.yaml deleted file mode 100644 index 969f8516..00000000 --- a/test/unit/development/development_unit_configs/reactions/troe/bad_reaction_component.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Bad reaction component -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - name: B - reactants: - - Name: A - type: TROE -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/troe/missing_phase.json b/test/unit/development/development_unit_configs/reactions/troe/missing_phase.json deleted file mode 100644 index 45a33c9a..00000000 --- a/test/unit/development/development_unit_configs/reactions/troe/missing_phase.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [], - "reactions": [ - { - "type": "TROE", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/troe/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/troe/missing_phase.yaml deleted file mode 100644 index 2bc6b03c..00000000 --- a/test/unit/development/development_unit_configs/reactions/troe/missing_phase.yaml +++ /dev/null @@ -1,14 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- gas phase: gas - products: - - name: C - reactants: - - name: A - type: TROE -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/troe/unknown_species.json b/test/unit/development/development_unit_configs/reactions/troe/unknown_species.json deleted file mode 100644 index 849f1d64..00000000 --- a/test/unit/development/development_unit_configs/reactions/troe/unknown_species.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "__my comment": {}, - "type": "TROE", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/troe/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/troe/unknown_species.yaml deleted file mode 100644 index 7766b6fc..00000000 --- a/test/unit/development/development_unit_configs/reactions/troe/unknown_species.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- __my comment: {} - gas phase: gas - products: - - name: C - reactants: - - name: A - type: TROE -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/troe/valid.json b/test/unit/development/development_unit_configs/reactions/troe/valid.json deleted file mode 100644 index 0051bb55..00000000 --- a/test/unit/development/development_unit_configs/reactions/troe/valid.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid troe", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "__my object": { - "a": 1.0 - }, - "type": "TROE", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - }, - { - "type": "TROE", - "gas phase": "gas", - "name": "my troe", - "reactants": [ - { - "name": "C" - } - ], - "products": [ - { - "name": "A", - "coefficient": 0.2, - "__optional thing": "hello" - }, - { - "name": "B", - "coefficient": 1.2 - } - ], - "k0_A": 32.1, - "k0_B": -2.3, - "k0_C": 102.3, - "kinf_A": 63.4, - "kinf_B": -1.3, - "kinf_C": 908.5, - "Fc": 1.3, - "N": 32.1 - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/troe/valid.yaml b/test/unit/development/development_unit_configs/reactions/troe/valid.yaml deleted file mode 100644 index 1611749a..00000000 --- a/test/unit/development/development_unit_configs/reactions/troe/valid.yaml +++ /dev/null @@ -1,40 +0,0 @@ -name: Valid troe -phases: -- name: gas - species: - - name: A - - name: B - - name: C -reactions: -- __my object: - a: 1.0 - gas phase: gas - products: - - name: C - reactants: - - name: A - type: TROE -- Fc: 1.3 - N: 32.1 - gas phase: gas - k0_A: 32.1 - k0_B: -2.3 - k0_C: 102.3 - kinf_A: 63.4 - kinf_B: -1.3 - kinf_C: 908.5 - name: my troe - products: - - __optional thing: hello - coefficient: 0.2 - name: A - - coefficient: 1.2 - name: B - reactants: - - name: C - type: TROE -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/tunneling/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/tunneling/bad_reaction_component.json deleted file mode 100644 index 00ab7d08..00000000 --- a/test/unit/development/development_unit_configs/reactions/tunneling/bad_reaction_component.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "TUNNELING", - "gas phase": "gas", - "reactants": [ - { - "Name": "A" - } - ], - "products": [ - { - "name": "B" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/tunneling/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/tunneling/bad_reaction_component.yaml deleted file mode 100644 index eeca6c8c..00000000 --- a/test/unit/development/development_unit_configs/reactions/tunneling/bad_reaction_component.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Bad reaction component -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - name: B - reactants: - - Name: A - type: TUNNELING -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/tunneling/missing_phase.json b/test/unit/development/development_unit_configs/reactions/tunneling/missing_phase.json deleted file mode 100644 index aded9ad0..00000000 --- a/test/unit/development/development_unit_configs/reactions/tunneling/missing_phase.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [], - "reactions": [ - { - "type": "TUNNELING", - "gas phase": "gas", - "A": 123.45, - "B": 1200.0, - "C": 1.0e8, - "reactants": [ - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/tunneling/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/tunneling/missing_phase.yaml deleted file mode 100644 index f669aaa4..00000000 --- a/test/unit/development/development_unit_configs/reactions/tunneling/missing_phase.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- A: 123.45 - B: 1200.0 - C: 100000000.0 - gas phase: gas - products: - - name: C - reactants: - - coefficient: 1 - name: B - type: TUNNELING -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/tunneling/unknown_species.json b/test/unit/development/development_unit_configs/reactions/tunneling/unknown_species.json deleted file mode 100644 index 343e5e4d..00000000 --- a/test/unit/development/development_unit_configs/reactions/tunneling/unknown_species.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "__my comment": {}, - "type": "TUNNELING", - "gas phase": "gas", - "reactants": [ - { - "name": "A" - } - ], - "products": [ - { - "name": "C" - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/tunneling/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/tunneling/unknown_species.yaml deleted file mode 100644 index bc7a7a4f..00000000 --- a/test/unit/development/development_unit_configs/reactions/tunneling/unknown_species.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- __my comment: {} - gas phase: gas - products: - - name: C - reactants: - - name: A - type: TUNNELING -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/tunneling/valid.json b/test/unit/development/development_unit_configs/reactions/tunneling/valid.json deleted file mode 100644 index 6d43ea44..00000000 --- a/test/unit/development/development_unit_configs/reactions/tunneling/valid.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid tunneling", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "TUNNELING", - "gas phase": "gas", - "A": 123.45, - "B": 1200.0, - "C": 1.0e8, - "reactants": [ - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "C" - } - ] - }, - { - "type": "TUNNELING", - "gas phase": "gas", - "name": "my tunneling", - "reactants": [ - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "A", - "coefficient": 0.2, - "__optional thing": "hello" - }, - { - "name": "B", - "coefficient": 1.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/tunneling/valid.yaml b/test/unit/development/development_unit_configs/reactions/tunneling/valid.yaml deleted file mode 100644 index a3888a93..00000000 --- a/test/unit/development/development_unit_configs/reactions/tunneling/valid.yaml +++ /dev/null @@ -1,35 +0,0 @@ -name: Valid tunneling -phases: -- name: gas - species: - - name: A - - name: B - - name: C -reactions: -- A: 123.45 - B: 1200.0 - C: 100000000.0 - gas phase: gas - products: - - name: C - reactants: - - coefficient: 1 - name: B - type: TUNNELING -- gas phase: gas - name: my tunneling - products: - - __optional thing: hello - coefficient: 0.2 - name: A - - coefficient: 1.2 - name: B - reactants: - - coefficient: 1 - name: B - type: TUNNELING -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/user_defined/bad_reaction_component.json b/test/unit/development/development_unit_configs/reactions/user_defined/bad_reaction_component.json deleted file mode 100644 index 199830f9..00000000 --- a/test/unit/development/development_unit_configs/reactions/user_defined/bad_reaction_component.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "version": "2.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "USER_DEFINED", - "gas phase": "gas", - "reactants": [ - { - "Name": "A", - "Coefficient": 1.2 - } - ], - "products": [ - { - "name": "B", - "coefficient": 0.2 - } - ], - "name": "my bad reaction" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/user_defined/bad_reaction_component.yaml b/test/unit/development/development_unit_configs/reactions/user_defined/bad_reaction_component.yaml deleted file mode 100644 index 1cea14c8..00000000 --- a/test/unit/development/development_unit_configs/reactions/user_defined/bad_reaction_component.yaml +++ /dev/null @@ -1,20 +0,0 @@ -name: Bad reaction component -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - coefficient: 0.2 - name: B - reactants: - - Coefficient: 1.2 - Name: A - type: USER_DEFINED - name: my bad reaction -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/user_defined/missing_phase.json b/test/unit/development/development_unit_configs/reactions/user_defined/missing_phase.json deleted file mode 100644 index 16062550..00000000 --- a/test/unit/development/development_unit_configs/reactions/user_defined/missing_phase.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [], - "reactions": [ - { - "type": "USER_DEFINED", - "gas phase": "gas", - "reactants": [ - { - "name": "B", - "coefficient": 1.2 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/user_defined/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/user_defined/missing_phase.yaml deleted file mode 100644 index ca0ca681..00000000 --- a/test/unit/development/development_unit_configs/reactions/user_defined/missing_phase.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- gas phase: gas - products: - - coefficient: 0.2 - name: C - reactants: - - coefficient: 1.2 - name: B - type: USER_DEFINED -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/user_defined/unknown_species.json b/test/unit/development/development_unit_configs/reactions/user_defined/unknown_species.json deleted file mode 100644 index 679a2e66..00000000 --- a/test/unit/development/development_unit_configs/reactions/user_defined/unknown_species.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "version": "2.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ] - } - ], - "reactions": [ - { - "type": "USER_DEFINED", - "gas phase": "gas", - "reactants": [ - { - "name": "B", - "coefficient": 1.2 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/user_defined/unknown_species.yaml b/test/unit/development/development_unit_configs/reactions/user_defined/unknown_species.yaml deleted file mode 100644 index 00eb1334..00000000 --- a/test/unit/development/development_unit_configs/reactions/user_defined/unknown_species.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Unknown species -phases: -- name: gas - species: - - name: A - - name: B -reactions: -- gas phase: gas - products: - - coefficient: 0.2 - name: C - reactants: - - coefficient: 1.2 - name: B - type: USER_DEFINED -species: -- name: A -- name: B -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/user_defined/valid.json b/test/unit/development/development_unit_configs/reactions/user_defined/valid.json deleted file mode 100644 index 9b3a33b6..00000000 --- a/test/unit/development/development_unit_configs/reactions/user_defined/valid.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid user_defined", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - }, - { - "name": "surface reacting phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "USER_DEFINED", - "gas phase": "gas", - "__comment": "hi", - "reactants": [ - { - "name": "B", - "coefficient": 1 - } - ], - "products": [ - { - "name": "C", - "coefficient": 1 - } - ], - "name": "my user defined", - "scaling factor": 12.3 - }, - { - "type": "USER_DEFINED", - "gas phase": "gas", - "reactants": [ - { - "name": "B", - "coefficient": 1.2 - }, - { - "name": "A", - "coefficient": 0.5 - } - ], - "products": [ - { - "name": "C", - "coefficient": 0.2 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/user_defined/valid.yaml b/test/unit/development/development_unit_configs/reactions/user_defined/valid.yaml deleted file mode 100644 index 99ebfcbf..00000000 --- a/test/unit/development/development_unit_configs/reactions/user_defined/valid.yaml +++ /dev/null @@ -1,39 +0,0 @@ -name: Valid user_defined -phases: -- name: gas - species: - - name: A - - name: B - - name: C -- name: surface reacting phase - species: - - name: A - - name: B - - name: C -reactions: -- __comment: hi - gas phase: gas - name: my user defined - products: - - coefficient: 1 - name: C - reactants: - - coefficient: 1 - name: B - scaling factor: 12.3 - type: USER_DEFINED -- gas phase: gas - products: - - coefficient: 0.2 - name: C - reactants: - - coefficient: 1.2 - name: B - - coefficient: 0.5 - name: A - type: USER_DEFINED -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/wet_deposition/missing_phase.json b/test/unit/development/development_unit_configs/reactions/wet_deposition/missing_phase.json deleted file mode 100644 index 040a6f31..00000000 --- a/test/unit/development/development_unit_configs/reactions/wet_deposition/missing_phase.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "version": "2.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [], - "reactions": [ - { - "type": "WET_DEPOSITION", - "condensed phase": "cloud", - "name": "rxn cloud" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/wet_deposition/missing_phase.yaml b/test/unit/development/development_unit_configs/reactions/wet_deposition/missing_phase.yaml deleted file mode 100644 index 80d5b066..00000000 --- a/test/unit/development/development_unit_configs/reactions/wet_deposition/missing_phase.yaml +++ /dev/null @@ -1,11 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- condensed phase: cloud - name: rxn cloud - type: WET_DEPOSITION -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/reactions/wet_deposition/valid.json b/test/unit/development/development_unit_configs/reactions/wet_deposition/valid.json deleted file mode 100644 index ebe924ca..00000000 --- a/test/unit/development/development_unit_configs/reactions/wet_deposition/valid.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid wet deposition", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "cloud", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ] - } - ], - "reactions": [ - { - "type": "WET_DEPOSITION", - "condensed phase": "cloud", - "name": "rxn cloud", - "scaling factor": 12.3, - "__comment": "Tuxedo cats are the best" - }, - { - "type": "WET_DEPOSITION", - "condensed phase": "cloud", - "name": "rxn cloud2" - } - ] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/reactions/wet_deposition/valid.yaml b/test/unit/development/development_unit_configs/reactions/wet_deposition/valid.yaml deleted file mode 100644 index 55fe0866..00000000 --- a/test/unit/development/development_unit_configs/reactions/wet_deposition/valid.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Valid wet deposition -phases: -- name: cloud - species: - - name: A - - name: B - - name: C -reactions: -- __comment: Tuxedo cats are the best - condensed phase: cloud - name: rxn cloud - scaling factor: 12.3 - type: WET_DEPOSITION -- condensed phase: cloud - name: rxn cloud2 - type: WET_DEPOSITION -species: -- name: A -- name: B -- name: C -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/species/duplicate_species.json b/test/unit/development/development_unit_configs/species/duplicate_species.json deleted file mode 100644 index 57274a6e..00000000 --- a/test/unit/development/development_unit_configs/species/duplicate_species.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "version": "2.0.0", - "name": "Duplicate Species", - "species": [ - { - "name": "FOO" - }, - { - "name": "BAZ" - }, - { - "name": "CYON" - }, - { - "name": "QUIZ" - }, - { - "name": "BAR" - }, - { - "name": "FOO" - }, - { - "name": "QUIZ" - } - ], - "phases": [], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/species/duplicate_species.yaml b/test/unit/development/development_unit_configs/species/duplicate_species.yaml deleted file mode 100644 index 6a459180..00000000 --- a/test/unit/development/development_unit_configs/species/duplicate_species.yaml +++ /dev/null @@ -1,12 +0,0 @@ -name: Duplicate Species -phases: [] -reactions: [] -species: -- name: FOO -- name: BAZ -- name: CYON -- name: QUIZ -- name: BAR -- name: FOO -- name: QUIZ -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/species/invalid_key.json b/test/unit/development/development_unit_configs/species/invalid_key.json deleted file mode 100644 index 421366dc..00000000 --- a/test/unit/development/development_unit_configs/species/invalid_key.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": "2.0.0", - "name": "Invalid key", - "species": [ - { - "name": "A", - "_absolute tolerance": 1.0e-30 - } - ], - "phases": [], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/species/invalid_key.yaml b/test/unit/development/development_unit_configs/species/invalid_key.yaml deleted file mode 100644 index 5e4219f4..00000000 --- a/test/unit/development/development_unit_configs/species/invalid_key.yaml +++ /dev/null @@ -1,7 +0,0 @@ -name: Invalid key -phases: [] -reactions: [] -species: -- _absolute tolerance: 1.0e-30 - name: A -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/species/missing_required_key.json b/test/unit/development/development_unit_configs/species/missing_required_key.json deleted file mode 100644 index 941dda61..00000000 --- a/test/unit/development/development_unit_configs/species/missing_required_key.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "version": "2.0.0", - "name": "Invalid key", - "species": [ - { - "Name": "A" - } - ], - "phases": [], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/species/missing_required_key.yaml b/test/unit/development/development_unit_configs/species/missing_required_key.yaml deleted file mode 100644 index c88932fd..00000000 --- a/test/unit/development/development_unit_configs/species/missing_required_key.yaml +++ /dev/null @@ -1,6 +0,0 @@ -name: Invalid key -phases: [] -reactions: [] -species: -- Name: A -version: 2.0.0 diff --git a/test/unit/development/development_unit_configs/species/valid_species.json b/test/unit/development/development_unit_configs/species/valid_species.json deleted file mode 100644 index 6ee8969f..00000000 --- a/test/unit/development/development_unit_configs/species/valid_species.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "version": "2.0.0", - "name": "Valid species configuration", - "species": [ - { - "name": "A", - "__absolute tolerance": 1.0e-30, - "is third body": true, - "__long name": "ozone" - }, - { - "name": "H2O2", - "HLC(298K) [mol m-3 Pa-1]": 1.011596348, - "HLC exponential factor [K]": 6340, - "diffusion coefficient [m2 s-1]": 1.46E-05, - "N star": 1.74, - "molecular weight [kg mol-1]": 0.0340147, - "constant concentration [mol m-3]": 2.5E19, - "density [kg m-3]": 1000.0, - "__absolute tolerance": 1.0e-10 - }, - { - "name": "aerosol stuff", - "molecular weight [kg mol-1]": 0.5, - "density [kg m-3]": 1000.0, - "constant mixing ratio [mol mol-1]": 1.0e-6, - "__absolute tolerance": 1.0e-20 - } - ], - "phases": [], - "reactions": [] -} \ No newline at end of file diff --git a/test/unit/development/development_unit_configs/species/valid_species.yaml b/test/unit/development/development_unit_configs/species/valid_species.yaml deleted file mode 100644 index af7ca8d6..00000000 --- a/test/unit/development/development_unit_configs/species/valid_species.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: Valid species configuration -phases: [] -reactions: [] -species: -- __absolute tolerance: 1.0e-30 - name: A - is third body: true - __long name: ozone -- HLC exponential factor [K]: 6340 - HLC(298K) [mol m-3 Pa-1]: 1.011596348 - N star: 1.74 - __absolute tolerance: 1.0e-10 - density [kg m-3]: 1000.0 - diffusion coefficient [m2 s-1]: 1.46e-05 - molecular weight [kg mol-1]: 0.0340147 - constant concentration [mol m-3]: 2.5e19 - name: H2O2 -- __absolute tolerance: 1.0e-20 - density [kg m-3]: 1000.0 - molecular weight [kg mol-1]: 0.5 - constant mixing ratio [mol mol-1]: 1.0e-6 - name: aerosol stuff -version: 2.0.0 diff --git a/test/unit/development/models/CMakeLists.txt b/test/unit/development/models/CMakeLists.txt deleted file mode 100644 index 54835df8..00000000 --- a/test/unit/development/models/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -################################################################################ -# Tests - -create_standard_test(NAME development_parse_modal SOURCES test_parse_modal.cpp) -create_standard_test(NAME development_parse_gas_model SOURCES test_parse_gas_model.cpp) \ No newline at end of file diff --git a/test/unit/development/models/test_parse_gas_model.cpp b/test/unit/development/models/test_parse_gas_model.cpp deleted file mode 100644 index 2c3e3377..00000000 --- a/test/unit/development/models/test_parse_gas_model.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseGas, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/models/gas/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.models.gas_model.name, "gas"); - EXPECT_EQ(mechanism.models.gas_model.type, "GAS_PHASE"); - EXPECT_EQ(mechanism.models.gas_model.phase, "gas"); - } -} - -TEST(ParseGas, MissingPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/models/gas/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseGas, PhaseNotFoundInRegisteredPhases) -{ - development::Parser parser; - - std::string path = "development_unit_configs/models/gas/gas_phase_not_found_in_phases"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::UnknownPhase, ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} \ No newline at end of file diff --git a/test/unit/development/models/test_parse_modal.cpp b/test/unit/development/models/test_parse_modal.cpp deleted file mode 100644 index ed9f1fc1..00000000 --- a/test/unit/development/models/test_parse_modal.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseModal, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/models/modal/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.models.modal_model.type, "MODAL"); - EXPECT_EQ(mechanism.models.modal_model.name, "aqueous"); - EXPECT_EQ(mechanism.models.modal_model.modes.size(), 2); - EXPECT_EQ(mechanism.models.modal_model.modes[0].name, "aitken"); - EXPECT_EQ(mechanism.models.modal_model.modes[0].geometric_mean_diameter, 2.6e-8); - EXPECT_EQ(mechanism.models.modal_model.modes[0].geometric_standard_deviation, 1.6); - EXPECT_EQ(mechanism.models.modal_model.modes[0].phase, "aqueous"); - EXPECT_EQ(mechanism.models.modal_model.modes[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.models.modal_model.modes[0].unknown_properties["__comment"], "Aitken mode"); - - EXPECT_EQ(mechanism.models.modal_model.modes[1].name, "accumulation"); - EXPECT_EQ(mechanism.models.modal_model.modes[1].geometric_mean_diameter, 1.1e-7); - EXPECT_EQ(mechanism.models.modal_model.modes[1].geometric_standard_deviation, 1.8); - EXPECT_EQ(mechanism.models.modal_model.modes[1].phase, "organic"); - EXPECT_EQ(mechanism.models.modal_model.modes[1].unknown_properties.size(), 0); - } -} - -TEST(ParseModal, MissingModes) -{ - development::Parser parser; - - std::string path = "development_unit_configs/models/modal/missing_modes"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseModal, MissingModalMemberData) -{ - development::Parser parser; - - std::string path = "development_unit_configs/models/modal/missing_modal_variable"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, - ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseModal, PhaseInModeNotFoundInRegisteredPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/models/modal/mode_phase_not_found_in_phases"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} \ No newline at end of file diff --git a/test/unit/development/reactions/CMakeLists.txt b/test/unit/development/reactions/CMakeLists.txt deleted file mode 100644 index 70c6192c..00000000 --- a/test/unit/development/reactions/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -################################################################################ -# Tests - -create_standard_test(NAME development_parse_aqueous_equilibrium SOURCES test_parse_aqueous_equilibrium.cpp) -create_standard_test(NAME development_parse_arrhenius SOURCES test_parse_arrhenius.cpp) -create_standard_test(NAME development_parse_branched SOURCES test_parse_branched.cpp) -create_standard_test(NAME development_parse_condensed_phase_arrhenius SOURCES test_parse_condensed_phase_arrhenius.cpp) -create_standard_test(NAME development_parse_condensed_phase_photolysis SOURCES test_parse_condensed_phase_photolysis.cpp) -create_standard_test(NAME development_parse_emission SOURCES test_parse_emission.cpp) -create_standard_test(NAME development_parse_first_order_loss SOURCES test_parse_first_order_loss.cpp) -create_standard_test(NAME development_parse_henrys_law SOURCES test_parse_henrys_law.cpp) -create_standard_test(NAME development_parse_photolysis SOURCES test_parse_photolysis.cpp) -create_standard_test(NAME development_parse_surface SOURCES test_parse_surface.cpp) -create_standard_test(NAME development_parse_taylor_series SOURCES test_parse_taylor_series.cpp) -create_standard_test(NAME development_parse_troe SOURCES test_parse_troe.cpp) -create_standard_test(NAME development_parse_tunneling SOURCES test_parse_tunneling.cpp) -create_standard_test(NAME development_parse_simpol_phase_transfer SOURCES test_parse_simpol_phase_transfer.cpp) -create_standard_test(NAME development_parse_wet_deposition SOURCES test_parse_wet_deposition.cpp) -create_standard_test(NAME development_parse_user_defined SOURCES test_parse_user_defined.cpp) -create_standard_test(NAME development_parse_ternary_chemical_activation SOURCES test_parse_ternary_chemical_activation.cpp) \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_aqueous_equilibrium.cpp b/test/unit/development/reactions/test_parse_aqueous_equilibrium.cpp deleted file mode 100644 index ca98e211..00000000 --- a/test/unit/development/reactions/test_parse_aqueous_equilibrium.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseAqueousEquilibrium, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/aqueous_equilibrium/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium.size(), 2); - - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].name, "my aqueous eq"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].condensed_phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].condensed_phase_water, "H2O"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].A, 1.14e-2); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].C, 2300.0); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].k_reverse, 0.32); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].reactants[0].coefficient, 2); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].products.size(), 2); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].products[0].name, "B"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].products[1].name, "C"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].products[1].coefficient, 1); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[0].unknown_properties["__comment"], "GIF is pronounced with a hard g"); - - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].condensed_phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].condensed_phase_water, "H2O"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].A, 1); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].C, 0); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].k_reverse, 0.32); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].reactants[0].coefficient, 2); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].products.size(), 2); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].products[0].name, "B"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].products[1].name, "C"); - EXPECT_EQ(mechanism.reactions.aqueous_equilibrium[1].products[1].coefficient, 1); - } -} - -TEST(ParseAqueousEquilibrium, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/aqueous_equilibrium/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseAqueousEquilibrium, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseAqueousEquilibrium, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/aqueous_equilibrium/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateAqueousEquilibrium, UnknownSpeciesUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, types::Species{ .name = "bar" } }; - std::vector existing_phases = { types::Phase{ .name = "aqueous" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "AQUEOUS_EQUILIBRIUM"; - reaction_node["products"] = YAML::Load("[{ name: foo }]"); - reaction_node["condensed-phase water"] = "H2O"; - reaction_node["k_reverse"] = 0.46; - reaction_node["reactants"] = YAML::Load("[{ name: Foo }, { name: bar }]"); - - // Unknown gas phase name triggers validation error - reaction_node["condensed phase"] = "Aqueous"; - - AqueousEquilibriumParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_arrhenius.cpp b/test/unit/development/reactions/test_parse_arrhenius.cpp deleted file mode 100644 index 36d6fe37..00000000 --- a/test/unit/development/reactions/test_parse_arrhenius.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseArrhenius, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/arrhenius/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.arrhenius.size(), 3); - - EXPECT_EQ(mechanism.reactions.arrhenius[0].name, "my arrhenius"); - EXPECT_EQ(mechanism.reactions.arrhenius[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.arrhenius[0].A, 32.1); - EXPECT_EQ(mechanism.reactions.arrhenius[0].B, -2.3); - EXPECT_EQ(mechanism.reactions.arrhenius[0].C, 102.3); - EXPECT_EQ(mechanism.reactions.arrhenius[0].D, 63.4); - EXPECT_EQ(mechanism.reactions.arrhenius[0].E, -1.3); - EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.arrhenius[0].products.size(), 2); - EXPECT_EQ(mechanism.reactions.arrhenius[0].products[0].name, "B"); - EXPECT_EQ(mechanism.reactions.arrhenius[0].products[0].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.arrhenius[0].products[1].name, "C"); - EXPECT_EQ(mechanism.reactions.arrhenius[0].products[1].coefficient, 0.3); - EXPECT_EQ(mechanism.reactions.arrhenius[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius[0].unknown_properties["__solver_param"], "0.1"); - - EXPECT_EQ(mechanism.reactions.arrhenius[1].name, "my arrhenius2"); - EXPECT_EQ(mechanism.reactions.arrhenius[1].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.arrhenius[1].A, 3.1); - EXPECT_EQ(mechanism.reactions.arrhenius[1].B, -0.3); - EXPECT_EQ(mechanism.reactions.arrhenius[1].C, 12.3); - EXPECT_EQ(mechanism.reactions.arrhenius[1].D, 6.4); - EXPECT_EQ(mechanism.reactions.arrhenius[1].E, -0.3); - EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[0].coefficient, 2); - EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[1].name, "B"); - EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[1].coefficient, 0.1); - EXPECT_EQ(mechanism.reactions.arrhenius[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].coefficient, 0.5); - EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].unknown_properties["__optional thing"], "hello"); - - EXPECT_EQ(mechanism.reactions.arrhenius[2].name, ""); - EXPECT_EQ(mechanism.reactions.arrhenius[2].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.arrhenius[2].A, 1); - EXPECT_EQ(mechanism.reactions.arrhenius[2].B, 0); - EXPECT_EQ(mechanism.reactions.arrhenius[2].C, 0); - EXPECT_EQ(mechanism.reactions.arrhenius[2].D, 300); - EXPECT_EQ(mechanism.reactions.arrhenius[2].E, 0); - EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.arrhenius[2].products.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius[2].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.arrhenius[2].products[0].coefficient, 1); - } -} - -TEST(ParseArrhenius, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/arrhenius/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 4); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseArrhenius, DetectsMutuallyExclusiveOptions) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/arrhenius/mutually_exclusive"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::MutuallyExclusiveOption }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseArrhenius, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/arrhenius/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseArrhenius, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/arrhenius/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateArrhenius, MutuallyExclusiveEaAndCFailsValidation) -{ - using namespace development; - - YAML::Node reaction_node; - reaction_node["reactants"] = YAML::Load("[{ name: foo }]"); - reaction_node["products"] = YAML::Load("[{ name: bar }]"); - reaction_node["type"] = "ARRHENIUS"; - reaction_node["gas phase"] = "gas"; - - // Specify both Ea and C to trigger validation error - reaction_node["Ea"] = 0.5; - reaction_node["C"] = 10.0; - - std::vector existing_species = { types::Species{ .name = "foo" }, types::Species{ .name = "bar" } }; - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - ArrheniusParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::MutuallyExclusiveOption }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_branched.cpp b/test/unit/development/reactions/test_parse_branched.cpp deleted file mode 100644 index 8062d00c..00000000 --- a/test/unit/development/reactions/test_parse_branched.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseBranched, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/branched/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.branched.size(), 1); - - EXPECT_EQ(mechanism.reactions.branched[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.branched[0].name, "my branched"); - EXPECT_EQ(mechanism.reactions.branched[0].X, 1.2e-4); - EXPECT_EQ(mechanism.reactions.branched[0].Y, 167); - EXPECT_EQ(mechanism.reactions.branched[0].a0, 0.15); - EXPECT_EQ(mechanism.reactions.branched[0].n, 9); - EXPECT_EQ(mechanism.reactions.branched[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.branched[0].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.branched[0].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products.size(), 1); - EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products[0].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products[0].unknown_properties["__thing"], "hi"); - EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products.size(), 2); - EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products[0].name, "B"); - EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products[0].coefficient, 0.2); - EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products[1].name, "A"); - EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products[1].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.branched[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.branched[0].unknown_properties["__comment"], "thing"); - } -} - -TEST(ParseBranched, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/branched/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseBranched, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/branched/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseBranched, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/branched/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseBranched, MissingRequiredKeyFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, - types::Species{ .name = "bar" }, - types::Species{ .name = "quiz" } }; - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "BRANCHED_NO_RO2"; - reaction_node["gas phase"] = "gas"; - reaction_node["reactants"] = YAML::Load("[{ name: foo }]"); - reaction_node["alkoxy products"] = YAML::Load("[{ name: bar }]"); - - // Incorrect required key triggers validation error - reaction_node["wrong nitrate products"] = YAML::Load("[{ name: quiz }]"); - - BranchedParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateBranched, UnknownSpeciesAndUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, - types::Species{ .name = "bar" }, - types::Species{ .name = "quiz" } }; - - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "BRANCHED_NO_RO2"; - reaction_node["reactants"] = YAML::Load("[{ name: foo }]"); - reaction_node["nitrate products"] = YAML::Load("[{ name: quiz }]"); - - // Unknown species triggers validation error - reaction_node["alkoxy products"] = YAML::Load("[{ name: bar }, { name: ABC }]"); - - // Unknown gas phase name triggers validation error - reaction_node["gas phase"] = "Gaseous Phase"; - - BranchedParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_condensed_phase_arrhenius.cpp b/test/unit/development/reactions/test_parse_condensed_phase_arrhenius.cpp deleted file mode 100644 index 7754fe6b..00000000 --- a/test/unit/development/reactions/test_parse_condensed_phase_arrhenius.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseCondensedPhaseArrhenius, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_arrhenius/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius.size(), 3); - - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].name, "my arrhenius"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].condensed_phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].A, 32.1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].B, -2.3); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].C, 102.3); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].D, 63.4); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].E, -1.3); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].products.size(), 2); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].products[0].name, "B"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].products[0].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].products[1].name, "C"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].products[1].coefficient, 0.3); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[0].unknown_properties["__solver_param"], "0.1"); - - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].name, "my arrhenius2"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].condensed_phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].A, 3.1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].B, -0.3); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].C, 12.3); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].D, 6.4); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].E, -0.3); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].reactants[0].coefficient, 2); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].reactants[1].name, "B"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].reactants[1].coefficient, 0.1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].products[0].coefficient, 0.5); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].products[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[1].products[0].unknown_properties["__optional thing"], "hello"); - - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].name, ""); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].condensed_phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].A, 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].B, 0); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].C, 0); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].D, 300); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].E, 0); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].products.size(), 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.condensed_phase_arrhenius[2].products[0].coefficient, 1); - } -} - -TEST(ParseCondensedPhaseArrhenius, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_arrhenius/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseCondensedPhaseArrhenius, DetectsMutuallyExclusiveOptions) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_arrhenius/mutually_exclusive"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::MutuallyExclusiveOption }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseCondensedPhaseArrhenius, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_arrhenius/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::InvalidKey, ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseCondensedPhaseArrhenius, DetectsWhenRequestedSpeciesAreNotInAqueousPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_arrhenius/species_not_in_aqueous_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseCondensedPhaseArrhenius, DetectsMissingPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_arrhenius/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateCondensedPhaseArrhenius, MutuallyExclusiveEaAndCFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, types::Species{ .name = "bar" } }; - std::vector existing_phases = { types::Phase{ .name = "aqueous" } }; - - YAML::Node reaction_node; - reaction_node["reactants"] = YAML::Load("[{ name: foo }]"); - reaction_node["products"] = YAML::Load("[{ name: bar }]"); - reaction_node["type"] = "CONDENSED_PHASE_ARRHENIUS"; - reaction_node["condensed phase"] = "organic"; - - // Specify both Ea and C to trigger validation error - reaction_node["Ea"] = 0.5; - reaction_node["C"] = 10.0; - - CondensedPhaseArrheniusParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::MutuallyExclusiveOption }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_condensed_phase_photolysis.cpp b/test/unit/development/reactions/test_parse_condensed_phase_photolysis.cpp deleted file mode 100644 index 024223e9..00000000 --- a/test/unit/development/reactions/test_parse_condensed_phase_photolysis.cpp +++ /dev/null @@ -1,205 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseCondensedPhasePhotolysis, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_photolysis/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis.size(), 2); - - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[0].condensed_phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[0].name, "my condensed phase photolysis"); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[0].scaling_factor, 12.3); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[0].reactants.name, "B"); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[0].reactants.coefficient, 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[0].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[0].products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[0].unknown_properties["__comment"], "hi"); - - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[1].condensed_phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[1].scaling_factor, 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[1].reactants.name, "B"); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[1].reactants.coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[1].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.condensed_phase_photolysis[1].products[0].coefficient, 0.2); - } -} - -TEST(ParseCondensedPhasePhotolysis, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_photolysis/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseCondensedPhasePhotolysis, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_photolysis/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseCondensedPhasePhotolysis, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_photolysis/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseCondensedPhasePhotolysis, DoesNotAcceptMoreThanOneReactant) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_photolysis/more_than_one_reactant"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseCondensedPhasePhotolysis, DetectsWhenRequestedSpeciesAreNotInAqueousPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/condensed_phase_photolysis/species_not_in_aqueous_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateCondensedPhasePhotolysis, InvalidNumberReactantUnknownSpeciesUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, types::Species{ .name = "bar" } }; - std::vector existing_phases = { types::Phase{ .name = "aqueous" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "CONDENSED_PHASE_PHOTOLYSIS"; - reaction_node["products"] = YAML::Load("[{ name: foo }]"); - - // Invalid number of reactions triggers validation error - reaction_node["reactants"] = YAML::Load("[{ name: quiz }, { name: bar }]"); - - // Unknown phase name triggers validation error - reaction_node["condensed phase"] = "organic"; - - CondensedPhasePhotolysisParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 3); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents, - ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_emission.cpp b/test/unit/development/reactions/test_parse_emission.cpp deleted file mode 100644 index 709d463b..00000000 --- a/test/unit/development/reactions/test_parse_emission.cpp +++ /dev/null @@ -1,147 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseEmission, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/emission/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.emission.size(), 2); - - EXPECT_EQ(mechanism.reactions.emission[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.emission[0].name, "my emission"); - EXPECT_EQ(mechanism.reactions.emission[0].scaling_factor, 12.3); - EXPECT_EQ(mechanism.reactions.emission[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.emission[0].products[0].name, "B"); - EXPECT_EQ(mechanism.reactions.emission[0].products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.emission[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.emission[0].unknown_properties["__comment"], "Dr. Pepper outranks any other soda"); - - EXPECT_EQ(mechanism.reactions.emission[1].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.emission[1].scaling_factor, 1); - EXPECT_EQ(mechanism.reactions.emission[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.emission[1].products[0].name, "B"); - EXPECT_EQ(mechanism.reactions.emission[1].products[0].coefficient, 1); - } -} - -TEST(ParseEmission, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/emission/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseEmission, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/emission/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseEmission, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/emission/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateEmission, UnknownSpeciesAndUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, types::Species{ .name = "bar" } }; - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "EMISSION"; - reaction_node["products"] = YAML::Load("[{ name: quiz }]"); - - // Unknown gas phase name triggers validation error - reaction_node["gas phase"] = "what is emission phase"; - - EmissionParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_first_order_loss.cpp b/test/unit/development/reactions/test_parse_first_order_loss.cpp deleted file mode 100644 index 22974b61..00000000 --- a/test/unit/development/reactions/test_parse_first_order_loss.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseFirstOrderLoss, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/first_order_loss/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.first_order_loss.size(), 2); - - EXPECT_EQ(mechanism.reactions.first_order_loss[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].name, "my first order loss"); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].scaling_factor, 12.3); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants.name, "C"); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants.coefficient, 1); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].unknown_properties.size(), 1); - EXPECT_EQ( - mechanism.reactions.first_order_loss[0].unknown_properties["__comment"], "Strawberries are the superior fruit"); - - EXPECT_EQ(mechanism.reactions.first_order_loss[1].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.first_order_loss[1].scaling_factor, 1); - EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants.name, "C"); - EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants.coefficient, 1); - } -} - -TEST(ParseFirstOrderLoss, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/first_order_loss/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseFirstOrderLoss, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/first_order_loss/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseFirstOrderLoss, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/first_order_loss/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseFirstOrderLoss, DetectsMoreThanOneSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/first_order_loss/too_many_reactants"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateFirstOrderLoss, InvalidNumberReactantUnknownSpeciesUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, types::Species{ .name = "bar" } }; - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "FIRST_ORDER_LOSS"; - - // Invalid number of reactions triggers validation error - reaction_node["reactants"] = YAML::Load("[{ name: quiz }, { name: bar }]"); - - // Unknown gas phase name triggers validation error - reaction_node["gas phase"] = "what is first order loss phase"; - - FirstOrderLossParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 3); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents, - ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_henrys_law.cpp b/test/unit/development/reactions/test_parse_henrys_law.cpp deleted file mode 100644 index 63facace..00000000 --- a/test/unit/development/reactions/test_parse_henrys_law.cpp +++ /dev/null @@ -1,360 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseHenrysLaw, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/henrys_law/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.henrys_law.size(), 2); - EXPECT_EQ(mechanism.reactions.henrys_law[0].name, "my henry's law"); - EXPECT_EQ(mechanism.reactions.henrys_law[0].gas.name, "gas"); - EXPECT_EQ(mechanism.reactions.henrys_law[0].gas.species.size(), 1); - EXPECT_EQ(mechanism.reactions.henrys_law[0].gas.species[0].name, "A"); - EXPECT_EQ(mechanism.reactions.henrys_law[0].particle.phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.henrys_law[0].particle.solutes.size(), 1); - EXPECT_EQ(mechanism.reactions.henrys_law[0].particle.solutes[0].name, "B"); - EXPECT_EQ(mechanism.reactions.henrys_law[0].particle.solutes[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.henrys_law[0].particle.solvent.name, "H2O"); - EXPECT_EQ(mechanism.reactions.henrys_law[0].particle.solvent.coefficient, 1); - EXPECT_EQ(mechanism.reactions.henrys_law[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.henrys_law[0].unknown_properties["__comment"], "B condensed phase production (kg/m2/s)"); - - EXPECT_EQ(mechanism.reactions.henrys_law[1].name, ""); - EXPECT_EQ(mechanism.reactions.henrys_law[1].gas.name, "gas"); - EXPECT_EQ(mechanism.reactions.henrys_law[1].gas.species.size(), 1); - EXPECT_EQ(mechanism.reactions.henrys_law[1].gas.species[0].name, "A"); - EXPECT_EQ(mechanism.reactions.henrys_law[1].particle.phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.henrys_law[1].particle.solutes.size(), 2); - EXPECT_EQ(mechanism.reactions.henrys_law[1].particle.solutes[0].name, "B"); - EXPECT_EQ(mechanism.reactions.henrys_law[1].particle.solutes[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.henrys_law[1].particle.solutes[1].name, "C"); - EXPECT_EQ(mechanism.reactions.henrys_law[1].particle.solutes[1].coefficient, 1); - EXPECT_EQ(mechanism.reactions.henrys_law[1].particle.solvent.name, "H2O"); - EXPECT_EQ(mechanism.reactions.henrys_law[1].particle.solvent.coefficient, 1); - EXPECT_EQ(mechanism.reactions.henrys_law[1].unknown_properties.size(), 0); - } -} - -TEST(ParseHenrysLaw, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/henrys_law/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::PhaseRequiresUnknownSpecies }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseHenrysLaw, DetectsGasSpeciesInReactionNotFoundInGasPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseHenrysLaw, DetectsWhenRequestedSpeciesAreNotInAqueousPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseHenrysLaw, DetectsWhenRequestedSolventIsNotRegisteredInCorrectPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateHenrysLaw, ValidationWithUnknownSpeciesUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, types::Species{ .name = "H2O" } }; - std::vector existing_phases = { - types::Phase{ .name = "gas", .species = { types::PhaseSpecies{ .name = "A" } } }, - types::Phase{ .name = "aqueous", .species = { types::PhaseSpecies{ .name = "H2O" } } } - }; - - YAML::Node reaction_node; - reaction_node["type"] = "HL_PHASE_TRANSFER"; - - reaction_node["gas"]["name"] = "gas"; - reaction_node["gas"]["species"] = YAML::Load("[{ name: A }]"); - - // Particle with unknown phase and unknown species - reaction_node["particle"]["phase"] = "unknown_phase"; - reaction_node["particle"]["solutes"] = YAML::Load("[{ name: H2O2, coefficient: 1.0 }]"); - reaction_node["particle"]["solvent"] = YAML::Load("[{ name: water, coefficient: 1.0 }]"); - - HenrysLawParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 3); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateHenrysLaw, ValidationWithSpeciesNotInPhasesFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, - types::Species{ .name = "B" }, - types::Species{ .name = "C" }, - types::Species{ .name = "H2O" } }; - std::vector existing_phases = { - types::Phase{ .name = "gas", .species = { types::PhaseSpecies{ .name = "A" } } }, - types::Phase{ .name = "aqueous", .species = { types::PhaseSpecies{ .name = "H2O" } } } - }; - - YAML::Node reaction_node; - reaction_node["type"] = "HL_PHASE_TRANSFER"; - - // Gas phase - species B exists but not in gas phase - reaction_node["gas"]["name"] = "gas"; - reaction_node["gas"]["species"] = YAML::Load("[{ name: B }]"); - - // Particle phase - species C exists but not in aqueous phase - reaction_node["particle"]["phase"] = "aqueous"; - reaction_node["particle"]["solutes"] = YAML::Load("[{ name: C, coefficient: 1.0 }]"); - reaction_node["particle"]["solvent"] = YAML::Load("[{ name: H2O, coefficient: 1.0 }]"); - - HenrysLawParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateHenrysLaw, ValidationWithMissingRequiredKeysFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, types::Species{ .name = "H2O" } }; - std::vector existing_phases = { types::Phase{ .name = "gas" }, types::Phase{ .name = "aqueous" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "HL_PHASE_TRANSFER"; - // Missing required "gas" and "particle" keys - - HenrysLawParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, - ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateHenrysLaw, ValidationWithValidConfigurationPassesValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, - types::Species{ .name = "B" }, - types::Species{ .name = "H2O" } }; - std::vector existing_phases = { - types::Phase{ .name = "gas", .species = { types::PhaseSpecies{ .name = "A" } } }, - types::Phase{ .name = "aqueous", - .species = { types::PhaseSpecies{ .name = "B" }, types::PhaseSpecies{ .name = "H2O" } } } - }; - - YAML::Node reaction_node; - reaction_node["type"] = "HL_PHASE_TRANSFER"; - - reaction_node["gas"]["name"] = "gas"; - reaction_node["gas"]["species"] = YAML::Load("[{ name: A, \"diffusion coefficient [m2 s-1]\": 0.7 }]"); - - reaction_node["particle"]["phase"] = "aqueous"; - reaction_node["particle"]["solutes"] = YAML::Load("[{ name: B, coefficient: 1.0 }]"); - reaction_node["particle"]["solvent"] = YAML::Load("[{ name: H2O, coefficient: 1.0 }]"); - - // Optional name field - reaction_node["name"] = "test henry's law reaction"; - - HenrysLawParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 0); -} - -TEST(ValidateHenrysLaw, ValidationWithMultipleSolutes) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, - types::Species{ .name = "B" }, - types::Species{ .name = "C" }, - types::Species{ .name = "H2O" } }; - std::vector existing_phases = { types::Phase{ .name = "gas", - .species = { types::PhaseSpecies{ .name = "A" } } }, - types::Phase{ .name = "aqueous", - .species = { types::PhaseSpecies{ .name = "B" }, - types::PhaseSpecies{ .name = "C" }, - types::PhaseSpecies{ .name = "H2O" } } } }; - - YAML::Node reaction_node; - reaction_node["type"] = "HL_PHASE_TRANSFER"; - - reaction_node["gas"]["name"] = "gas"; - reaction_node["gas"]["species"] = YAML::Load("[{ name: A }]"); - - // Valid particle phase configuration with multiple solutes - reaction_node["particle"]["phase"] = "aqueous"; - reaction_node["particle"]["solutes"] = YAML::Load("[{ name: B, coefficient: 1.0 }, { name: C, coefficient: 2.0 }]"); - reaction_node["particle"]["solvent"] = YAML::Load("[{ name: H2O, coefficient: 1.0 }]"); - - HenrysLawParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 0); -} - -TEST(ValidateHenrysLaw, InvalidNumberSolventFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, - types::Species{ .name = "B" }, - types::Species{ .name = "C" }, - types::Species{ .name = "H2O" }, - types::Species{ .name = "water" } }; - std::vector existing_phases = { types::Phase{ .name = "gas", - .species = { types::PhaseSpecies{ .name = "A" } } }, - types::Phase{ .name = "aqueous", - .species = { types::PhaseSpecies{ .name = "B" }, - types::PhaseSpecies{ .name = "C" }, - types::PhaseSpecies{ .name = "H2O" }, - types::PhaseSpecies{ .name = "water" } } } }; - - YAML::Node reaction_node; - reaction_node["type"] = "HL_PHASE_TRANSFER"; - - reaction_node["gas"]["name"] = "gas"; - reaction_node["gas"]["species"] = YAML::Load("[{ name: A }]"); - reaction_node["particle"]["phase"] = "aqueous"; - reaction_node["particle"]["solutes"] = YAML::Load("[{ name: B, coefficient: 1.0 }, { name: C, coefficient: 2.0 }]"); - - // The invalid number of the solvent triggers validation error - reaction_node["particle"]["solvent"] = YAML::Load("[{ name: H2O, coefficient: 1.0 }, { name: water, coefficient: 1.0 }]"); - - HenrysLawParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_photolysis.cpp b/test/unit/development/reactions/test_parse_photolysis.cpp deleted file mode 100644 index afd287c3..00000000 --- a/test/unit/development/reactions/test_parse_photolysis.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParsePhotolysis, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/photolysis/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.photolysis.size(), 2); - - EXPECT_EQ(mechanism.reactions.photolysis[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.photolysis[0].name, "my photolysis"); - EXPECT_EQ(mechanism.reactions.photolysis[0].scaling_factor, 12.3); - EXPECT_EQ(mechanism.reactions.photolysis[0].reactants.name, "B"); - EXPECT_EQ(mechanism.reactions.photolysis[0].reactants.coefficient, 1); - EXPECT_EQ(mechanism.reactions.photolysis[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.photolysis[0].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.photolysis[0].products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.photolysis[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.photolysis[0].unknown_properties["__comment"], "hi"); - - EXPECT_EQ(mechanism.reactions.photolysis[1].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.photolysis[1].scaling_factor, 1); - EXPECT_EQ(mechanism.reactions.photolysis[1].reactants.name, "B"); - EXPECT_EQ(mechanism.reactions.photolysis[1].reactants.coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.photolysis[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.photolysis[1].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.photolysis[1].products[0].coefficient, 0.2); - } -} - -TEST(ParsePhotolysis, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/photolysis/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParsePhotolysis, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/photolysis/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParsePhotolysis, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/photolysis/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParsePhotolysis, DoesNotAcceptMoreThanOneReactant) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/photolysis/more_than_one_reactant"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidatePhotolysis, InvalidNumberReactantUnknownSpeciesUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, types::Species{ .name = "bar" } }; - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "PHOTOLYSIS"; - reaction_node["products"] = YAML::Load("[{ name: foo }]"); - - // Invalid number of reactions triggers validation error - reaction_node["reactants"] = YAML::Load("[{ name: quiz }, { name: bar }]"); - - // Unknown gas phase name triggers validation error - reaction_node["gas phase"] = "aqueous"; - - PhotolysisParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 3); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents, - ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_simpol_phase_transfer.cpp b/test/unit/development/reactions/test_parse_simpol_phase_transfer.cpp deleted file mode 100644 index 6eb65d83..00000000 --- a/test/unit/development/reactions/test_parse_simpol_phase_transfer.cpp +++ /dev/null @@ -1,356 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseSimpolPhaseTransfer, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/simpol_phase_transfer/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer.size(), 2); - - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].name, "my simpol"); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].gas_phase_species[0].name, "A"); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].gas_phase_species[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].condensed_phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].condensed_phase_species[0].name, "B"); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].condensed_phase_species[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].B[0], -1.97e3); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].B[1], 2.91e0); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].B[2], 1.96e-3); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].B[3], -4.96e-1); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[0].unknown_properties["__comment"], "cereal is also soup"); - - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].name, ""); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].gas_phase_species[0].name, "A"); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].gas_phase_species[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].condensed_phase, "aqueous"); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].condensed_phase_species[0].name, "B"); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].condensed_phase_species[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].B[0], -1.97e3); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].B[1], 2.91e0); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].B[2], 1.96e-3); - EXPECT_EQ(mechanism.reactions.simpol_phase_transfer[1].B[3], -4.96e-1); - } -} - -TEST(ParseSimpolPhaseTransfer, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/simpol_phase_transfer/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseSimpolPhaseTransfer, DetectsUnknownAqueousPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseSimpolPhaseTransfer, DetectsUnknownGasPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseSimpolPhaseTransfer, DetectsUnknownGasPhaseSpeciesNotInGasPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/simpol_phase_transfer/missing_gas_phase_species_in_gas_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseSimpolPhaseTransfer, DetectsUnknownAqueousPhaseSpeciesNotInAqueousPhase) -{ - development::Parser parser; - - std::string path = - "development_unit_configs/reactions/simpol_phase_transfer/missing_aqueous_phase_species_in_aqueous_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateSimpolPhaseTransfer, InvalidBParameterNotSequenceFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, types::Species{ .name = "B" } }; - std::vector existing_phases = { - types::Phase{ .name = "gas", .species = { types::PhaseSpecies{ .name = "A" } } }, - types::Phase{ .name = "aqueous", .species = { types::PhaseSpecies{ .name = "B" } } } - }; - - YAML::Node reaction_node; - reaction_node["type"] = "SIMPOL_PHASE_TRANSFER"; - reaction_node["gas phase"] = "gas"; - reaction_node["gas-phase species"] = YAML::Load("[{ name: A, coefficient: 1 }]"); - reaction_node["condensed phase"] = "aqueous"; - reaction_node["condensed-phase species"] = YAML::Load("[{ name: B, coefficient: 1 }]"); - - // Invalid B parameter - not a sequence - reaction_node["B"] = "not a sequence"; - - SimpolPhaseTransferParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::InvalidParameterNumber }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateSimpolPhaseTransfer, InvalidBParameterWrongCountFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, types::Species{ .name = "B" } }; - std::vector existing_phases = { - types::Phase{ .name = "gas", .species = { types::PhaseSpecies{ .name = "A" } } }, - types::Phase{ .name = "aqueous", .species = { types::PhaseSpecies{ .name = "B" } } } - }; - - YAML::Node reaction_node; - reaction_node["type"] = "SIMPOL_PHASE_TRANSFER"; - reaction_node["gas phase"] = "gas"; - reaction_node["gas-phase species"] = YAML::Load("[{ name: A, coefficient: 1 }]"); - reaction_node["condensed phase"] = "aqueous"; - reaction_node["condensed-phase species"] = YAML::Load("[{ name: B, coefficient: 1 }]"); - - // Invalid B parameter - wrong number of parameters (should be 4) - reaction_node["B"] = YAML::Load("[-1.97E+03, 2.91E+00]"); - - SimpolPhaseTransferParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::InvalidParameterNumber }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateSimpolPhaseTransfer, TooManyGasSpeciesFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, - types::Species{ .name = "B" }, - types::Species{ .name = "C" } }; - std::vector existing_phases = { - types::Phase{ .name = "gas", .species = { types::PhaseSpecies{ .name = "A" }, types::PhaseSpecies{ .name = "C" } } }, - types::Phase{ .name = "aqueous", .species = { types::PhaseSpecies{ .name = "B" } } } - }; - - YAML::Node reaction_node; - reaction_node["type"] = "SIMPOL_PHASE_TRANSFER"; - reaction_node["gas phase"] = "gas"; - - // Too many gas phase species (should be exactly 1) - reaction_node["gas-phase species"] = YAML::Load("[{ name: A, coefficient: 1 }, { name: C, coefficient: 1 }]"); - - reaction_node["condensed phase"] = "aqueous"; - reaction_node["condensed-phase species"] = YAML::Load("[{ name: B, coefficient: 1 }]"); - reaction_node["B"] = YAML::Load("[-1.97E+03, 2.91E+00, 1.96E-03, -4.96E-01]"); - - SimpolPhaseTransferParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateSimpolPhaseTransfer, TooManyCondensedSpeciesFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, - types::Species{ .name = "B" }, - types::Species{ .name = "C" } }; - std::vector existing_phases = { - types::Phase{ .name = "gas", .species = { types::PhaseSpecies{ .name = "A" } } }, - types::Phase{ .name = "aqueous", .species = { types::PhaseSpecies{ .name = "B" }, types::PhaseSpecies{ .name = "C" } } } - }; - - YAML::Node reaction_node; - reaction_node["type"] = "SIMPOL_PHASE_TRANSFER"; - reaction_node["gas phase"] = "gas"; - reaction_node["gas-phase species"] = YAML::Load("[{ name: A, coefficient: 1 }]"); - reaction_node["condensed phase"] = "aqueous"; - - // Too many condensed phase species (should be exactly 1) - reaction_node["condensed-phase species"] = YAML::Load("[{ name: B, coefficient: 1 }, { name: C, coefficient: 1 }]"); - - reaction_node["B"] = YAML::Load("[-1.97E+03, 2.91E+00, 1.96E-03, -4.96E-01]"); - - SimpolPhaseTransferParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateSimpolPhaseTransfer, MultipleErrorsFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "A" }, types::Species{ .name = "B" } }; - std::vector existing_phases = { types::Phase{ .name = "gas" } }; // Missing aqueous phase - - YAML::Node reaction_node; - reaction_node["type"] = "SIMPOL_PHASE_TRANSFER"; - reaction_node["gas phase"] = "gas"; - - // Too many gas species + unknown species + unknown phase + invalid B parameter - reaction_node["gas-phase species"] = YAML::Load("[{ name: A, coefficient: 1 }, { name: UNKNOWN, coefficient: 1 }]"); - reaction_node["condensed phase"] = "aqueous"; // Unknown phase - reaction_node["condensed-phase species"] = YAML::Load("[{ name: B, coefficient: 1 }]"); - reaction_node["B"] = "invalid"; // Invalid B parameter - - SimpolPhaseTransferParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_GE(errors.size(), 3); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents, - ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase, - ConfigParseStatus::InvalidParameterNumber }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_surface.cpp b/test/unit/development/reactions/test_parse_surface.cpp deleted file mode 100644 index 628d358c..00000000 --- a/test/unit/development/reactions/test_parse_surface.cpp +++ /dev/null @@ -1,190 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseSurface, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/surface/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.surface.size(), 2); - - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.surface[0].name, "my surface"); - EXPECT_EQ(mechanism.reactions.surface[0].condensed_phase, "surface reacting phase"); - EXPECT_EQ(mechanism.reactions.surface[0].reaction_probability, 2.0e-2); - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_species.name, "A"); - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_species.coefficient, 1); - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products.size(), 2); - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products[0].name, "B"); - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products[1].name, "C"); - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products[1].coefficient, 1); - EXPECT_EQ(mechanism.reactions.surface[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.surface[0].unknown_properties["__comment"], "key lime pie is superior to all other pies"); - - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.surface[1].condensed_phase, "surface reacting phase"); - EXPECT_EQ(mechanism.reactions.surface[1].reaction_probability, 1.0); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_species.name, "A"); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_species.coefficient, 1); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products.size(), 2); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[0].name, "B"); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[0].unknown_properties["__optional thing"], "hello"); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[1].name, "C"); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[1].coefficient, 1); - } -} - -TEST(ParseSurface, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/surface/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseSurface, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/surface/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseSurface, DetectsUnknownCondensedPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/surface/missing_condensed_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseSurface, DetectsUnknownGasPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/surface/missing_gas_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateSurface, InvalidNumberReactantUnknownSpeciesUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, types::Species{ .name = "bar" } }; - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "SURFACE"; - reaction_node["reaction probability"] = 0.7; - reaction_node["gas-phase products"] = YAML::Load("[{ name: foo }]"); - reaction_node["gas phase"] = "gas"; - - // Invalid number of reactions triggers validation error - reaction_node["gas-phase species"] = YAML::Load("[{ name: quiz }, { name: bar }]"); - - // Unknown condensed phase name triggers validation error - reaction_node["condensed phase"] = "condensed phase"; - - SurfaceParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 3); - - std::multiset expected = { ConfigParseStatus::TooManyReactionComponents, - ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_taylor_series.cpp b/test/unit/development/reactions/test_parse_taylor_series.cpp deleted file mode 100644 index 403b4939..00000000 --- a/test/unit/development/reactions/test_parse_taylor_series.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseTaylorSeries, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/taylor_series/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.taylor_series.size(), 3); - - EXPECT_EQ(mechanism.reactions.taylor_series[0].name, "my taylor_series"); - EXPECT_EQ(mechanism.reactions.taylor_series[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.taylor_series[0].A, 32.1); - EXPECT_EQ(mechanism.reactions.taylor_series[0].B, -2.3); - EXPECT_EQ(mechanism.reactions.taylor_series[0].C, 102.3); - EXPECT_EQ(mechanism.reactions.taylor_series[0].D, 63.4); - EXPECT_EQ(mechanism.reactions.taylor_series[0].E, -1.3); - EXPECT_EQ(mechanism.reactions.taylor_series[0].taylor_coefficients.size(), 3); - EXPECT_EQ(mechanism.reactions.taylor_series[0].taylor_coefficients[0], 1.0); - EXPECT_EQ(mechanism.reactions.taylor_series[0].taylor_coefficients[1], 2.0); - EXPECT_EQ(mechanism.reactions.taylor_series[0].taylor_coefficients[2], 3.0); - EXPECT_EQ(mechanism.reactions.taylor_series[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[0].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.taylor_series[0].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.taylor_series[0].products.size(), 2); - EXPECT_EQ(mechanism.reactions.taylor_series[0].products[0].name, "B"); - EXPECT_EQ(mechanism.reactions.taylor_series[0].products[0].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.taylor_series[0].products[1].name, "C"); - EXPECT_EQ(mechanism.reactions.taylor_series[0].products[1].coefficient, 0.3); - EXPECT_EQ(mechanism.reactions.taylor_series[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[0].unknown_properties["__solver_param"], "0.1"); - - EXPECT_EQ(mechanism.reactions.taylor_series[1].name, "my taylor_series2"); - EXPECT_EQ(mechanism.reactions.taylor_series[1].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.taylor_series[1].A, 3.1); - EXPECT_EQ(mechanism.reactions.taylor_series[1].B, -0.3); - EXPECT_EQ(mechanism.reactions.taylor_series[1].C, 12.3); - EXPECT_EQ(mechanism.reactions.taylor_series[1].D, 6.4); - EXPECT_EQ(mechanism.reactions.taylor_series[1].E, -0.3); - EXPECT_EQ(mechanism.reactions.taylor_series[1].taylor_coefficients.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[1].taylor_coefficients[0], 10.5); - EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants[0].coefficient, 2); - EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants[1].name, "B"); - EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants[1].coefficient, 0.1); - EXPECT_EQ(mechanism.reactions.taylor_series[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[1].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.taylor_series[1].products[0].coefficient, 0.5); - EXPECT_EQ(mechanism.reactions.taylor_series[1].products[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[1].products[0].unknown_properties["__optional thing"], "hello"); - - EXPECT_EQ(mechanism.reactions.taylor_series[2].name, ""); - EXPECT_EQ(mechanism.reactions.taylor_series[2].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.taylor_series[2].A, 1); - EXPECT_EQ(mechanism.reactions.taylor_series[2].B, 0); - EXPECT_EQ(mechanism.reactions.taylor_series[2].C, 0); - EXPECT_EQ(mechanism.reactions.taylor_series[2].D, 300); - EXPECT_EQ(mechanism.reactions.taylor_series[2].E, 0); - EXPECT_EQ(mechanism.reactions.taylor_series[2].taylor_coefficients.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[2].taylor_coefficients[0], 1.0); - EXPECT_EQ(mechanism.reactions.taylor_series[2].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[2].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.taylor_series[2].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.taylor_series[2].products.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[2].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.taylor_series[2].products[0].coefficient, 1); - } -} - -TEST(ParseTaylorSeries, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/taylor_series/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseTaylorSeries, DetectsMutuallyExclusiveOptions) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/taylor_series/mutually_exclusive"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::MutuallyExclusiveOption }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseTaylorSeries, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/taylor_series/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::InvalidKey, ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseTaylorSeries, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/taylor_series/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateTaylorSeries, MutuallyExclusiveEaAndCFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, types::Species{ .name = "bar" } }; - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["reactants"] = YAML::Load("[{ name: foo }]"); - reaction_node["products"] = YAML::Load("[{ name: bar }]"); - reaction_node["type"] = "TAYLOR_SERIES"; - reaction_node["gas phase"] = "gas"; - - // Specify both Ea and C to trigger validation error - reaction_node["Ea"] = 0.5; - reaction_node["C"] = 10.0; - - TaylorSeriesParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::MutuallyExclusiveOption }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} diff --git a/test/unit/development/reactions/test_parse_ternary_chemical_activation.cpp b/test/unit/development/reactions/test_parse_ternary_chemical_activation.cpp deleted file mode 100644 index e19144ca..00000000 --- a/test/unit/development/reactions/test_parse_ternary_chemical_activation.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParserTernary, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/ternary_chemical_activation/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - auto& process_vector = mechanism.reactions.ternary_chemical_activation; - - EXPECT_EQ(process_vector.size(), 2); - - // first reaction - EXPECT_EQ(process_vector[0].reactants.size(), 2); - EXPECT_EQ(process_vector[0].reactants[0].name, "foo"); - EXPECT_EQ(process_vector[0].reactants[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].reactants[1].name, "quz"); - EXPECT_EQ(process_vector[0].reactants[1].coefficient, 2.0); - EXPECT_EQ(process_vector[0].products.size(), 2); - EXPECT_EQ(process_vector[0].products[0].name, "bar"); - EXPECT_EQ(process_vector[0].products[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].products[1].name, "baz"); - EXPECT_EQ(process_vector[0].products[1].coefficient, 3.2); - EXPECT_EQ(process_vector[0].k0_A, 1.0); - EXPECT_EQ(process_vector[0].k0_B, 0.0); - EXPECT_EQ(process_vector[0].k0_C, 0.0); - EXPECT_EQ(process_vector[0].kinf_A, 1.0); - EXPECT_EQ(process_vector[0].kinf_B, 0.0); - EXPECT_EQ(process_vector[0].kinf_C, 0.0); - EXPECT_EQ(process_vector[0].Fc, 0.6); - EXPECT_EQ(process_vector[0].N, 1.0); - - // second reaction - EXPECT_EQ(process_vector[1].unknown_properties.size(), 1); - EXPECT_EQ(process_vector[1].unknown_properties["__optional thing"], "hello"); - EXPECT_EQ(process_vector[1].reactants.size(), 2); - EXPECT_EQ(process_vector[1].reactants[0].name, "bar"); - EXPECT_EQ(process_vector[1].reactants[1].name, "baz"); - EXPECT_EQ(process_vector[1].products.size(), 2); - EXPECT_EQ(process_vector[1].products[0].name, "bar"); - EXPECT_EQ(process_vector[1].products[0].coefficient, 0.5); - EXPECT_EQ(process_vector[1].products[1].name, "foo"); - EXPECT_EQ(process_vector[1].products[1].coefficient, 0.0); - EXPECT_EQ(process_vector[1].k0_A, 32.1); - EXPECT_EQ(process_vector[1].k0_B, -2.3); - EXPECT_EQ(process_vector[1].k0_C, 102.3); - EXPECT_EQ(process_vector[1].kinf_A, 63.4); - EXPECT_EQ(process_vector[1].kinf_B, -1.3); - EXPECT_EQ(process_vector[1].kinf_C, 908.5); - EXPECT_EQ(process_vector[1].Fc, 1.3); - EXPECT_EQ(process_vector[1].N, 32.1); - EXPECT_EQ(process_vector[1].name, "my ternary chemical activation"); - } -} - -TEST(ParserTernary, DetectsNonStandardKey) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/ternary_chemical_activation/contains_nonstandard_key"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 12); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey, - ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey, - ConfigParseStatus::InvalidKey, ConfigParseStatus::InvalidKey, - ConfigParseStatus::InvalidKey, ConfigParseStatus::InvalidKey, - ConfigParseStatus::InvalidKey, ConfigParseStatus::InvalidKey, - ConfigParseStatus::InvalidKey, ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParserTernary, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/ternary_chemical_activation/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParserTernary, DetectsMissingProducts) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/ternary_chemical_activation/missing_products"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParserTernary, DetectsMissingReactants) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/ternary_chemical_activation/missing_reactants"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateTernary, UnknownSpeciesAndUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, - types::Species{ .name = "bar" }, - types::Species{ .name = "quiz" } }; - - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "TERNARY_CHEMICAL_ACTIVATION"; - reaction_node["products"] = YAML::Load("[{ name: quiz }]"); - - // Unknown species triggers validation error - reaction_node["reactants"] = YAML::Load("[{ name: bar }, { name: ABC }]"); - - // Unknown gas phase name triggers validation error - reaction_node["gas phase"] = "Gaseous Phase"; - - TernaryChemicalActivationParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_troe.cpp b/test/unit/development/reactions/test_parse_troe.cpp deleted file mode 100644 index aeeb76c6..00000000 --- a/test/unit/development/reactions/test_parse_troe.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParserTroe, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/troe/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.troe.size(), 2); - - EXPECT_EQ(mechanism.reactions.troe[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.troe[0].k0_A, 1.0); - EXPECT_EQ(mechanism.reactions.troe[0].k0_B, 0.0); - EXPECT_EQ(mechanism.reactions.troe[0].k0_C, 0.0); - EXPECT_EQ(mechanism.reactions.troe[0].kinf_A, 1.0); - EXPECT_EQ(mechanism.reactions.troe[0].kinf_B, 0.0); - EXPECT_EQ(mechanism.reactions.troe[0].kinf_C, 0.0); - EXPECT_EQ(mechanism.reactions.troe[0].Fc, 0.6); - EXPECT_EQ(mechanism.reactions.troe[0].N, 1.0); - EXPECT_EQ(mechanism.reactions.troe[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.troe[0].reactants[0].name, "A"); - EXPECT_EQ(mechanism.reactions.troe[0].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.troe[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.troe[0].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.troe[0].products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.troe[0].unknown_properties.size(), 1); - if (extension == ".json") - { - EXPECT_EQ(mechanism.reactions.troe[0].unknown_properties["__my object"], "{a: 1.0}"); - } - else - { - EXPECT_EQ(mechanism.reactions.troe[0].unknown_properties["__my object"], "a: 1.0"); - } - - EXPECT_EQ(mechanism.reactions.troe[1].name, "my troe"); - EXPECT_EQ(mechanism.reactions.troe[1].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.troe[1].k0_A, 32.1); - EXPECT_EQ(mechanism.reactions.troe[1].k0_B, -2.3); - EXPECT_EQ(mechanism.reactions.troe[1].k0_C, 102.3); - EXPECT_EQ(mechanism.reactions.troe[1].kinf_A, 63.4); - EXPECT_EQ(mechanism.reactions.troe[1].kinf_B, -1.3); - EXPECT_EQ(mechanism.reactions.troe[1].kinf_C, 908.5); - EXPECT_EQ(mechanism.reactions.troe[1].Fc, 1.3); - EXPECT_EQ(mechanism.reactions.troe[1].N, 32.1); - EXPECT_EQ(mechanism.reactions.troe[1].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.troe[1].reactants[0].name, "C"); - EXPECT_EQ(mechanism.reactions.troe[1].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.troe[1].products.size(), 2); - EXPECT_EQ(mechanism.reactions.troe[1].products[0].name, "A"); - EXPECT_EQ(mechanism.reactions.troe[1].products[0].coefficient, 0.2); - EXPECT_EQ(mechanism.reactions.troe[1].products[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.troe[1].products[0].unknown_properties["__optional thing"], "hello"); - EXPECT_EQ(mechanism.reactions.troe[1].products[1].name, "B"); - EXPECT_EQ(mechanism.reactions.troe[1].products[1].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.troe[1].products[1].unknown_properties.size(), 0); - } -} - -TEST(ParserTroe, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/troe/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParserTroe, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/troe/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParserTroe, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/troe/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateTroe, UnknownSpeciesAndUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, - types::Species{ .name = "bar" }, - types::Species{ .name = "quiz" } }; - - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "TROE"; - reaction_node["products"] = YAML::Load("[{ name: quiz }]"); - - // Unknown species triggers validation error - reaction_node["reactants"] = YAML::Load("[{ name: bar }, { name: ABC }]"); - - // Unknown gas phase name triggers validation error - reaction_node["gas phase"] = "Gaseous Phase"; - - TroeParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_tunneling.cpp b/test/unit/development/reactions/test_parse_tunneling.cpp deleted file mode 100644 index a91e8a20..00000000 --- a/test/unit/development/reactions/test_parse_tunneling.cpp +++ /dev/null @@ -1,166 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseTunneling, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/tunneling/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.tunneling.size(), 2); - - EXPECT_EQ(mechanism.reactions.tunneling[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.tunneling[0].A, 123.45); - EXPECT_EQ(mechanism.reactions.tunneling[0].B, 1200.0); - EXPECT_EQ(mechanism.reactions.tunneling[0].C, 1.0e8); - EXPECT_EQ(mechanism.reactions.tunneling[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.tunneling[0].reactants[0].name, "B"); - EXPECT_EQ(mechanism.reactions.tunneling[0].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.tunneling[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.tunneling[0].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.tunneling[0].products[0].coefficient, 1); - - EXPECT_EQ(mechanism.reactions.tunneling[1].name, "my tunneling"); - EXPECT_EQ(mechanism.reactions.tunneling[1].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.tunneling[1].A, 1.0); - EXPECT_EQ(mechanism.reactions.tunneling[1].B, 0); - EXPECT_EQ(mechanism.reactions.tunneling[1].C, 0); - EXPECT_EQ(mechanism.reactions.tunneling[1].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.tunneling[1].reactants[0].name, "B"); - EXPECT_EQ(mechanism.reactions.tunneling[1].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.tunneling[1].products.size(), 2); - EXPECT_EQ(mechanism.reactions.tunneling[1].products[0].name, "A"); - EXPECT_EQ(mechanism.reactions.tunneling[1].products[0].coefficient, 0.2); - EXPECT_EQ(mechanism.reactions.tunneling[1].products[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.tunneling[1].products[0].unknown_properties["__optional thing"], "hello"); - EXPECT_EQ(mechanism.reactions.tunneling[1].products[1].name, "B"); - EXPECT_EQ(mechanism.reactions.tunneling[1].products[1].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.tunneling[1].products[1].unknown_properties.size(), 0); - } -} - -TEST(ParseTunneling, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/tunneling/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseTunneling, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/tunneling/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseTunneling, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/tunneling/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateTunneling, UnknownSpeciesAndUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, - types::Species{ .name = "bar" }, - types::Species{ .name = "quiz" } }; - - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "TUNNELING"; - reaction_node["products"] = YAML::Load("[{ name: quiz }]"); - - // Unknown species triggers validation error - reaction_node["reactants"] = YAML::Load("[{ name: bar }, { name: ABC }]"); - - // Unknown gas phase name triggers validation error - reaction_node["gas phase"] = "Gaseous Phase"; - - TunnelingParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_user_defined.cpp b/test/unit/development/reactions/test_parse_user_defined.cpp deleted file mode 100644 index 0c06ebc4..00000000 --- a/test/unit/development/reactions/test_parse_user_defined.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseUserDefined, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/user_defined/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.user_defined.size(), 2); - - EXPECT_EQ(mechanism.reactions.user_defined[0].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.user_defined[0].name, "my user defined"); - EXPECT_EQ(mechanism.reactions.user_defined[0].scaling_factor, 12.3); - EXPECT_EQ(mechanism.reactions.user_defined[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.user_defined[0].reactants[0].name, "B"); - EXPECT_EQ(mechanism.reactions.user_defined[0].reactants[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.user_defined[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.user_defined[0].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.user_defined[0].products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.user_defined[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.user_defined[0].unknown_properties["__comment"], "hi"); - - EXPECT_EQ(mechanism.reactions.user_defined[1].gas_phase, "gas"); - EXPECT_EQ(mechanism.reactions.user_defined[1].scaling_factor, 1); - EXPECT_EQ(mechanism.reactions.user_defined[1].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.user_defined[1].reactants[0].name, "B"); - EXPECT_EQ(mechanism.reactions.user_defined[1].reactants[0].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.user_defined[1].reactants[1].name, "A"); - EXPECT_EQ(mechanism.reactions.user_defined[1].reactants[1].coefficient, 0.5); - EXPECT_EQ(mechanism.reactions.user_defined[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.user_defined[1].products[0].name, "C"); - EXPECT_EQ(mechanism.reactions.user_defined[1].products[0].coefficient, 0.2); - } -} - -TEST(ParseUserDefined, DetectsUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/user_defined/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::RequestedSpeciesNotRegisteredInPhase }; - ; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseUserDefined, DetectsBadReactionComponent) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/user_defined/bad_reaction_component"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 3); - - std::multiset expected = { ConfigParseStatus::InvalidKey, - ConfigParseStatus::InvalidKey, - ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseUserDefined, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/user_defined/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateUserDefined, UnknownSpeciesAndUnknownPhaseFailsValidation) -{ - using namespace development; - - std::vector existing_species = { types::Species{ .name = "foo" }, - types::Species{ .name = "bar" }, - types::Species{ .name = "quiz" } }; - - std::vector existing_phases = { types::Phase{ .name = "gas" } }; - - YAML::Node reaction_node; - reaction_node["type"] = "USER_DEFINED"; - reaction_node["products"] = YAML::Load("[{ name: quiz }]"); - - // Unknown species triggers validation error - reaction_node["reactants"] = YAML::Load("[{ name: bar }, { name: ABC }]"); - - // Unknown gas phase name triggers validation error - reaction_node["gas phase"] = "Gaseous Phase"; - - UserDefinedParser parser; - Errors errors = parser.Validate(reaction_node, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::ReactionRequiresUnknownSpecies, - ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} \ No newline at end of file diff --git a/test/unit/development/reactions/test_parse_wet_deposition.cpp b/test/unit/development/reactions/test_parse_wet_deposition.cpp deleted file mode 100644 index 015c4338..00000000 --- a/test/unit/development/reactions/test_parse_wet_deposition.cpp +++ /dev/null @@ -1,159 +0,0 @@ -#include -#include - -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseWetDeposition, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/wet_deposition/valid"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.reactions.wet_deposition.size(), 2); - - EXPECT_EQ(mechanism.reactions.wet_deposition[0].name, "rxn cloud"); - EXPECT_EQ(mechanism.reactions.wet_deposition[0].condensed_phase, "cloud"); - EXPECT_EQ(mechanism.reactions.wet_deposition[0].scaling_factor, 12.3); - EXPECT_EQ(mechanism.reactions.wet_deposition[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.reactions.wet_deposition[0].unknown_properties["__comment"], "Tuxedo cats are the best"); - - EXPECT_EQ(mechanism.reactions.wet_deposition[1].name, "rxn cloud2"); - EXPECT_EQ(mechanism.reactions.wet_deposition[1].condensed_phase, "cloud"); - EXPECT_EQ(mechanism.reactions.wet_deposition[1].scaling_factor, 1); - } -} - -TEST(ParseWetDeposition, DetectsUnknownPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/reactions/wet_deposition/missing_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::UnknownPhase }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateWetDeposition, ReturnsEmptyErrorsForValidReaction) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "A"; - existing_species.emplace_back(species1); - - std::vector existing_phases; - development::types::Phase phase1; - phase1.name = "cloud"; - existing_phases.emplace_back(phase1); - - YAML::Node reaction = YAML::Load(R"( - type: "WET_DEPOSITION" - "condensed phase": "cloud" - name: "rxn cloud" - "scaling factor": 12.3 - )"); - - development::WetDepositionParser parser; - auto errors = parser.Validate(reaction, existing_species, existing_phases); - EXPECT_TRUE(errors.empty()); -} - -TEST(ValidateWetDeposition, DetectsMissingRequiredType) -{ - std::vector existing_species; - std::vector existing_phases; - development::types::Phase phase1; - phase1.name = "cloud"; - existing_phases.emplace_back(phase1); - - YAML::Node reaction = YAML::Load(R"( - "condensed phase": "cloud" - name: "rxn cloud" - )"); - - development::WetDepositionParser parser; - auto errors = parser.Validate(reaction, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateWetDeposition, DetectsMissingRequiredCondensedPhase) -{ - std::vector existing_species; - std::vector existing_phases; - development::types::Phase phase1; - phase1.name = "cloud"; - existing_phases.emplace_back(phase1); - - YAML::Node reaction = YAML::Load(R"( - type: "WET_DEPOSITION" - name: "rxn cloud" - )"); - - development::WetDepositionParser parser; - auto errors = parser.Validate(reaction, existing_species, existing_phases); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateWetDeposition, ValidatesWithOptionalScalingFactor) -{ - std::vector existing_species; - std::vector existing_phases; - development::types::Phase phase1; - phase1.name = "cloud"; - existing_phases.emplace_back(phase1); - - YAML::Node reaction = YAML::Load(R"( - type: "WET_DEPOSITION" - "condensed phase": "cloud" - "scaling factor": 5.7 - )"); - - development::WetDepositionParser parser; - auto errors = parser.Validate(reaction, existing_species, existing_phases); - EXPECT_TRUE(errors.empty()); -} diff --git a/test/unit/development/test_parse_phases.cpp b/test/unit/development/test_parse_phases.cpp deleted file mode 100644 index 9b4f52c4..00000000 --- a/test/unit/development/test_parse_phases.cpp +++ /dev/null @@ -1,501 +0,0 @@ -#include -#include - -#include -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParsePhases, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/phases/valid_phases"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.species.size(), 3); - EXPECT_EQ(mechanism.phases.size(), 2); - - EXPECT_EQ(mechanism.phases[0].name, "gas"); - EXPECT_EQ(mechanism.phases[0].species.size(), 2); - EXPECT_EQ(mechanism.phases[0].species[0].name, "A"); - EXPECT_TRUE(mechanism.phases[0].species[0].diffusion_coefficient.has_value()); - EXPECT_DOUBLE_EQ(mechanism.phases[0].species[0].diffusion_coefficient.value(), 4.23e-7); - EXPECT_EQ(mechanism.phases[0].species[1].name, "B"); - EXPECT_FALSE(mechanism.phases[0].species[1].diffusion_coefficient.has_value()); - EXPECT_EQ(mechanism.phases[0].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.phases[0].unknown_properties["__other"], "This is a comment."); - - EXPECT_EQ(mechanism.phases[1].name, "aqueous"); - EXPECT_EQ(mechanism.phases[1].species.size(), 1); - EXPECT_EQ(mechanism.phases[1].species[0].name, "C"); - EXPECT_TRUE(mechanism.phases[1].species[0].diffusion_coefficient.has_value()); - EXPECT_DOUBLE_EQ(mechanism.phases[1].species[0].diffusion_coefficient.value(), 4.23e-7); - EXPECT_EQ(mechanism.phases[1].unknown_properties.size(), 2); - EXPECT_EQ(mechanism.phases[1].unknown_properties["__other1"], "This is another comment."); - EXPECT_EQ(mechanism.phases[1].unknown_properties["__other2"], "This is again a comment."); - } -} - -TEST(ParsePhases, DetectsDuplicatePhases) -{ - development::Parser parser; - - std::string path = "development_unit_configs/phases/duplicate_phases"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - for (const auto& [status, message] : validation_errors) - { - EXPECT_EQ(status, ConfigParseStatus::DuplicatePhasesDetected); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - } -} - -TEST(ParsePhases, DetectsMissingRequiredKeys) -{ - development::Parser parser; - - std::string path = "development_unit_configs/phases/missing_required_key"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParsePhases, DetectsInvalidKeys) -{ - development::Parser parser; - - std::string path = "development_unit_configs/phases/invalid_key"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParsePhases, DetectsPhaseRequestingUnknownSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/phases/unknown_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::PhaseRequiresUnknownSpecies }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParsePhases, DetectsDuplicateSpeciesInPhase) -{ - development::Parser parser; - - std::string path = "development_unit_configs/phases/duplicate_species_in_phase"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - for (const auto& [status, message] : validation_errors) - { - EXPECT_EQ(status, ConfigParseStatus::DuplicateSpeciesInPhaseDetected); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - } -} - -TEST(ParsePhases, DetectsInvalidSpeciesObject) -{ - development::Parser parser; - - std::string path = "development_unit_configs/phases/invalid_species_object"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParsePhases, CanParsePhaseSpeciesProperties) -{ - development::Parser parser; - - std::string path = "development_unit_configs/phases/phase_species_properties"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.species.size(), 3); - EXPECT_EQ(mechanism.phases.size(), 1); - - const auto& phase = mechanism.phases[0]; - EXPECT_EQ(phase.name, "my phase"); - EXPECT_EQ(phase.species.size(), 3); - EXPECT_EQ(phase.unknown_properties.size(), 1); - EXPECT_EQ(phase.unknown_properties.at("__my custom phase property"), "custom value"); - - // Check first species with diffusion coefficient - EXPECT_EQ(phase.species[0].name, "foo"); - EXPECT_TRUE(phase.species[0].diffusion_coefficient.has_value()); - EXPECT_EQ(phase.species[0].diffusion_coefficient.value(), 4.23e-7); - EXPECT_EQ(phase.species[0].unknown_properties.size(), 0); - - // Check second species with custom properties - EXPECT_EQ(phase.species[1].name, "bar"); - EXPECT_FALSE(phase.species[1].diffusion_coefficient.has_value()); - EXPECT_EQ(phase.species[1].unknown_properties.size(), 2); - EXPECT_EQ(phase.species[1].unknown_properties.at("__custom property"), "0.5"); - EXPECT_EQ(phase.species[1].unknown_properties.at("__another custom property"), "value"); - - // Check third species (simple string format) - EXPECT_EQ(phase.species[2].name, "baz"); - EXPECT_FALSE(phase.species[2].diffusion_coefficient.has_value()); - EXPECT_EQ(phase.species[2].unknown_properties.size(), 0); - } -} - -TEST(ValidatePhases, ReturnsEmptyErrorsForValidPhases) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "A"; - existing_species.emplace_back(species1); - - development::types::Species species2; - species2.name = "B"; - existing_species.emplace_back(species2); - - YAML::Node phases_list = YAML::Load(R"( - - name: "gas" - species: - - name: "A" - - name: "B" - "diffusion coefficient [m2 s-1]": 1.5e-05 - - name: "aqueous" - species: - - name: "A" - "diffusion coefficient [m2 s-1]": 2.3e-06 - )"); - - auto errors = development::ValidatePhases(phases_list, existing_species); - EXPECT_TRUE(errors.empty()); -} - -TEST(ValidatePhases, DetectsMissingPhaseName) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "A"; - existing_species.emplace_back(species1); - - YAML::Node phases_list = YAML::Load(R"( - - species: - - name: "A" - - name: "aqueous" - species: - - name: "A" - )"); - - auto errors = development::ValidatePhases(phases_list, existing_species); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidatePhases, DetectsMissingSpeciesList) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "A"; - existing_species.emplace_back(species1); - - YAML::Node phases_list = YAML::Load(R"( - - name: "gas" - - name: "aqueous" - species: - - name: "A" - )"); - - auto errors = development::ValidatePhases(phases_list, existing_species); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidatePhases, DetectsInvalidKeysInPhase) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "A"; - existing_species.emplace_back(species1); - - YAML::Node phases_list = YAML::Load(R"( - - name: "gas" - SPECIES: - - name: "A" - )"); - - auto errors = development::ValidatePhases(phases_list, existing_species); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::InvalidKey, ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidatePhases, DetectsMissingSpeciesNameInPhase) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "A"; - existing_species.emplace_back(species1); - - YAML::Node phases_list = YAML::Load(R"( - - name: "gas" - species: - - "diffusion coefficient [m2 s-1]": 1.5e-05 - - name: "A" - )"); - - auto errors = development::ValidatePhases(phases_list, existing_species); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidatePhases, DetectsInvalidKeysInSpecies) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "A"; - existing_species.emplace_back(species1); - - YAML::Node phases_list = YAML::Load(R"( - - name: "gas" - species: - - name: "A" - Coefficient: 4.23e-5 - )"); - - auto errors = development::ValidatePhases(phases_list, existing_species); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidatePhases, DetectsDuplicateSpeciesInPhase) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "FOO"; - existing_species.emplace_back(species1); - - YAML::Node phases_list = YAML::Load(R"( - - name: "gas" - species: - - name: "FOO" - - name: "FOO" - "diffusion coefficient [m2 s-1]": 1.5e-05 - )"); - - auto errors = development::ValidatePhases(phases_list, existing_species); - EXPECT_EQ(errors.size(), 2); // Two entries for the duplicate species - - for (const auto& [status, message] : errors) - { - EXPECT_EQ(status, ConfigParseStatus::DuplicateSpeciesInPhaseDetected); - EXPECT_NE(message.find("FOO"), std::string::npos); // Error message should contain species name - } -} - -TEST(ValidatePhases, DetectsUnknownSpeciesInPhase) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "A"; - existing_species.emplace_back(species1); - - YAML::Node phases_list = YAML::Load(R"( - - name: "gas" - species: - - name: "A" - - name: "FOO" - )"); - - auto errors = development::ValidatePhases(phases_list, existing_species); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::PhaseRequiresUnknownSpecies }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidatePhases, DetectsDuplicatePhaseNames) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "A"; - existing_species.emplace_back(species1); - - development::types::Species species2; - species2.name = "B"; - existing_species.emplace_back(species2); - - YAML::Node phases_list = YAML::Load(R"( - - name: "gas" - species: - - name: "A" - - name: "aqueous" - species: - - name: "B" - - name: "gas" - species: - - name: "B" - )"); - - auto errors = development::ValidatePhases(phases_list, existing_species); - EXPECT_EQ(errors.size(), 2); // Two entries for the duplicate phase - - for (const auto& [status, message] : errors) - { - EXPECT_EQ(status, ConfigParseStatus::DuplicatePhasesDetected); - EXPECT_NE(message.find("gas"), std::string::npos); // Error message should contain phase name - } -} - -TEST(ValidatePhases, ValidatesAllSpeciesOptionalKeys) -{ - std::vector existing_species; - development::types::Species species1; - species1.name = "FOO"; - existing_species.emplace_back(species1); - - YAML::Node phases_list = YAML::Load(R"( - - name: "organic" - species: - - name: "FOO" - "diffusion coefficient [m2 s-1]": 1.46e-05 - )"); - - auto errors = development::ValidatePhases(phases_list, existing_species); - EXPECT_TRUE(errors.empty()); -} \ No newline at end of file diff --git a/test/unit/development/test_parse_species.cpp b/test/unit/development/test_parse_species.cpp deleted file mode 100644 index e6661a0c..00000000 --- a/test/unit/development/test_parse_species.cpp +++ /dev/null @@ -1,262 +0,0 @@ -#include -#include - -#include -#include - -#include - -using namespace mechanism_configuration; - -TEST(ParseSpecies, ParseValidConfig) -{ - development::Parser parser; - - std::string path = "development_unit_configs/species/valid_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 0) << "Validation errors were: " << validation_errors.size(); - - auto mechanism = parser.Parse(object); - EXPECT_EQ(mechanism.species.size(), 3); - EXPECT_EQ(mechanism.species[0].name, "A"); - EXPECT_EQ(mechanism.species[0].unknown_properties.size(), 2); - EXPECT_EQ(mechanism.species[0].unknown_properties["__absolute tolerance"], "1.0e-30"); - EXPECT_EQ(mechanism.species[0].unknown_properties["__long name"], "ozone"); - EXPECT_EQ(mechanism.species[0].tracer_type.has_value(), false); - EXPECT_EQ(mechanism.species[0].is_third_body.has_value(), true); - EXPECT_EQ(mechanism.species[0].is_third_body.value(), true); - - EXPECT_EQ(mechanism.species[1].name, "H2O2"); - EXPECT_EQ(mechanism.species[1].henrys_law_constant_298.has_value(), true); - EXPECT_EQ(mechanism.species[1].henrys_law_constant_298.value(), 1.011596348); - EXPECT_EQ(mechanism.species[1].henrys_law_constant_exponential_factor.has_value(), true); - EXPECT_EQ(mechanism.species[1].henrys_law_constant_exponential_factor.value(), 6340); - EXPECT_EQ(mechanism.species[1].diffusion_coefficient.has_value(), true); - EXPECT_EQ(mechanism.species[1].diffusion_coefficient.value(), 1.46e-05); - EXPECT_EQ(mechanism.species[1].n_star.has_value(), true); - EXPECT_EQ(mechanism.species[1].n_star.value(), 1.74); - EXPECT_EQ(mechanism.species[1].molecular_weight.has_value(), true); - EXPECT_EQ(mechanism.species[1].molecular_weight.value(), 0.0340147); - EXPECT_EQ(mechanism.species[1].density.has_value(), true); - EXPECT_EQ(mechanism.species[1].density.value(), 1000.0); - EXPECT_EQ(mechanism.species[1].constant_concentration.has_value(), true); - EXPECT_EQ(mechanism.species[1].constant_concentration.value(), 2.5e19); - EXPECT_EQ(mechanism.species[1].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.species[1].unknown_properties["__absolute tolerance"], "1.0e-10"); - - EXPECT_EQ(mechanism.species[2].name, "aerosol stuff"); - EXPECT_EQ(mechanism.species[2].molecular_weight.has_value(), true); - EXPECT_EQ(mechanism.species[2].molecular_weight.value(), 0.5); - EXPECT_EQ(mechanism.species[2].density.has_value(), true); - EXPECT_EQ(mechanism.species[2].density.value(), 1000.0); - EXPECT_EQ(mechanism.species[2].constant_mixing_ratio.has_value(), true); - EXPECT_EQ(mechanism.species[2].constant_mixing_ratio.value(), 1.0e-6); - EXPECT_EQ(mechanism.species[2].unknown_properties.size(), 1); - EXPECT_EQ(mechanism.species[2].unknown_properties["__absolute tolerance"], "1.0e-20"); - } -} - -TEST(ParseSpecies, DetectsDuplicateSpecies) -{ - development::Parser parser; - - std::string path = "development_unit_configs/species/duplicate_species"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 4); - - for (const auto& [status, message] : validation_errors) - { - EXPECT_EQ(status, ConfigParseStatus::DuplicateSpeciesDetected); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - } -} - -TEST(ParseSpecies, DetectsMissingRequiredKeys) -{ - development::Parser parser; - - std::string path = "development_unit_configs/species/missing_required_key"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound, ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ParseSpecies, DetectsInvalidKeys) -{ - development::Parser parser; - - std::string path = "development_unit_configs/species/invalid_key"; - std::vector extensions = { ".json", ".yaml" }; - - for (auto& extension : extensions) - { - YAML::Node object = parser.FileToYaml(path + extension); - - auto validation_errors = parser.Validate(object); - EXPECT_EQ(validation_errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : validation_errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); - } -} - -TEST(ValidateSpecies, ReturnsEmptyErrorsForValidSpecies) -{ - YAML::Node species_list = YAML::Load(R"( - - "name": "A" - "absolute tolerance": "1.0e-30" - "is third body": true - - "name": "B" - "molecular weight [kg mol-1]": 0.034 - "density [kg m-3]": 1000.0 - )"); - - auto errors = development::ValidateSpecies(species_list); - EXPECT_TRUE(errors.empty()); -} - -TEST(ValidateSpecies, DetectsMissingNameKey) -{ - YAML::Node species_list = YAML::Load(R"( - - "absolute tolerance": "1.0e-30" - "is third body": true - - "name": "B" - "molecular weight [kg mol-1]": 0.034 - )"); - - auto errors = development::ValidateSpecies(species_list); - EXPECT_FALSE(errors.empty()); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::RequiredKeyNotFound }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateSpecies, DetectsInvalidKeysInSpecies) -{ - YAML::Node species_list = YAML::Load(R"( - - "name": "A" - "Absolute Tolerance": 1.0e-30 - - "name": "B" - "absolute tolerance": 1.0e-30 - )"); - - auto errors = development::ValidateSpecies(species_list); - EXPECT_EQ(errors.size(), 1); - - std::multiset expected = { ConfigParseStatus::InvalidKey }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateSpecies, DetectsDuplicateSpeciesNames) -{ - YAML::Node species_list = YAML::Load(R"( - - "name": "A" - "absolute tolerance": "1.0e-30" - - "name": "B" - "molecular weight [kg mol-1]": 0.034 - - "name": "A" - "density [kg m-3]": 1000.0 - )"); - - auto errors = development::ValidateSpecies(species_list); - EXPECT_EQ(errors.size(), 2); - - std::multiset expected = { ConfigParseStatus::DuplicateSpeciesDetected, - ConfigParseStatus::DuplicateSpeciesDetected }; - std::multiset actual; - for (const auto& [status, message] : errors) - { - actual.insert(status); - EXPECT_NE(message.find("A"), std::string::npos); // Error message should contain species "name" - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } - EXPECT_EQ(actual, expected); -} - -TEST(ValidateSpecies, DetectsMultipleDuplicateSpecies) -{ - YAML::Node species_list = YAML::Load(R"( - - "name": "A" - - "name": "B" - - "name": "A" - - "name": "C" - - "name": "B" - )"); - - auto errors = development::ValidateSpecies(species_list); - EXPECT_EQ(errors.size(), 4); // 2 for "A" duplicates + 2 for "B" duplicates - - for (const auto& [status, message] : errors) - { - EXPECT_EQ(status, ConfigParseStatus::DuplicateSpeciesDetected); - std::cout << message << " " << configParseStatusToString(status) << std::endl; - } -} - -TEST(ValidateSpecies, ValidatesAllOptionalKeys) -{ - YAML::Node species_list = YAML::Load(R"( - - "name": "CompleteSpecies" - "absolute tolerance": "1.0e-30" - "diffusion coefficient [m2 s-1]": 1.46e-05 - "molecular weight [kg mol-1]": 0.0340147 - "HLC(298K) [mol m-3 Pa-1]": 1.011596348 - "HLC exponential factor [K]": 6340 - "N star": 1.74 - "density [kg m-3]": 1000.0 - "tracer type": "CHEM" - "constant concentration [mol m-3]": 2.5e19 - "constant mixing ratio [mol mol-1]": 1.0e-6 - "is third body": true - )"); - - auto errors = development::ValidateSpecies(species_list); - EXPECT_TRUE(errors.empty()); -} \ No newline at end of file diff --git a/test/unit/test_validate.cpp b/test/unit/test_validate.cpp new file mode 100644 index 00000000..583913c8 --- /dev/null +++ b/test/unit/test_validate.cpp @@ -0,0 +1,123 @@ +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include + +#include + +using namespace mechanism_configuration; + +namespace +{ + types::Species species(const std::string& name) + { + types::Species s; + s.name = name; + return s; + } + types::PhaseSpecies phase_species(const std::string& name) + { + types::PhaseSpecies ps; + ps.name = name; + return ps; + } + types::ReactionComponent component(const std::string& name) + { + types::ReactionComponent c; + c.name = name; + return c; + } + + // gas phase {A, B}, aqueous phase {C}; species A, B, C. + Mechanism BaseMechanism() + { + Mechanism m; + m.species = { species("A"), species("B"), species("C") }; + types::Phase gas; + gas.name = "gas"; + gas.species = { phase_species("A"), phase_species("B") }; + types::Phase aqueous; + aqueous.name = "aqueous"; + aqueous.species = { phase_species("C") }; + m.phases = { gas, aqueous }; + return m; + } + + bool HasCode(const Errors& errors, ErrorCode code) + { + for (const auto& [c, m] : errors) + if (c == code) + return true; + return false; + } +} // namespace + +// An in-code mechanism (never parsed from a file) can be validated. +TEST(Validate, AcceptsValidInCodeMechanism) +{ + Mechanism m = BaseMechanism(); + types::Arrhenius rxn; + rxn.gas_phase = "gas"; + rxn.reactants = { component("A") }; + rxn.products = { component("B") }; + m.reactions.arrhenius = { rxn }; + + EXPECT_TRUE(Validate(m).empty()); +} + +TEST(Validate, DetectsUnknownSpeciesInReaction) +{ + Mechanism m = BaseMechanism(); + types::Arrhenius rxn; + rxn.gas_phase = "gas"; + rxn.reactants = { component("Z") }; // not in the species list + m.reactions.arrhenius = { rxn }; + + auto errors = Validate(m); + EXPECT_TRUE(HasCode(errors, ErrorCode::ReactionRequiresUnknownSpecies)); +} + +TEST(Validate, DetectsReactantNotInReactionPhase) +{ + Mechanism m = BaseMechanism(); + types::Arrhenius rxn; + rxn.gas_phase = "gas"; + rxn.reactants = { component("C") }; // C is known, but only in the aqueous phase + m.reactions.arrhenius = { rxn }; + + auto errors = Validate(m); + EXPECT_TRUE(HasCode(errors, ErrorCode::RequestedSpeciesNotRegisteredInPhase)); +} + +// Products may reference species from any phase. +TEST(Validate, AllowsCrossPhaseProduct) +{ + Mechanism m = BaseMechanism(); + types::Arrhenius rxn; + rxn.gas_phase = "gas"; + rxn.reactants = { component("A") }; + rxn.products = { component("C") }; // C lives in aqueous; allowed as a product + m.reactions.arrhenius = { rxn }; + + EXPECT_TRUE(Validate(m).empty()); +} + +TEST(Validate, DetectsDuplicateSpecies) +{ + Mechanism m = BaseMechanism(); + m.species.push_back(species("A")); // duplicate + + EXPECT_TRUE(HasCode(Validate(m), ErrorCode::DuplicateSpeciesDetected)); +} + +TEST(Validate, DetectsUnknownPhase) +{ + Mechanism m = BaseMechanism(); + types::Arrhenius rxn; + rxn.gas_phase = "stratosphere"; // no such phase + rxn.reactants = { component("A") }; + m.reactions.arrhenius = { rxn }; + + EXPECT_TRUE(HasCode(Validate(m), ErrorCode::UnknownPhase)); +} diff --git a/test/unit/v0/test_arrhenius_config.cpp b/test/unit/v0/test_arrhenius_config.cpp index d3f2267e..f32fa65d 100644 --- a/test/unit/v0/test_arrhenius_config.cpp +++ b/test/unit/v0/test_arrhenius_config.cpp @@ -1,6 +1,10 @@ -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" #include @@ -15,31 +19,31 @@ TEST(ArrheniusConfig, DetectsInvalidConfig) std::string file = "./v0_unit_configs/arrhenius/missing_reactants/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/arrhenius/missing_products/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/arrhenius/mutually_exclusive/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::MutuallyExclusiveOption); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::MutuallyExclusiveOption); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -54,17 +58,17 @@ TEST(ArrheniusConfig, ParseConfig) std::string file = "./v0_unit_configs/arrhenius/valid/config" + extension; auto parsed = parser.Parse(file); EXPECT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; // first reaction { EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants[0].species_name, "foo"); - EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants[1].species_name, "quz"); + EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants[0].name, "foo"); + EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants[1].name, "quz"); EXPECT_EQ(mechanism.reactions.arrhenius[0].products.size(), 2); - EXPECT_EQ(mechanism.reactions.arrhenius[0].products[0].species_name, "bar"); + EXPECT_EQ(mechanism.reactions.arrhenius[0].products[0].name, "bar"); EXPECT_EQ(mechanism.reactions.arrhenius[0].products[0].coefficient, 1.0); - EXPECT_EQ(mechanism.reactions.arrhenius[0].products[1].species_name, "baz"); + EXPECT_EQ(mechanism.reactions.arrhenius[0].products[1].name, "baz"); EXPECT_EQ(mechanism.reactions.arrhenius[0].products[1].coefficient, 3.2); EXPECT_EQ( mechanism.reactions.arrhenius[0].A, 1.0 * conversions::MolesM3ToMoleculesCm3 * conversions::MolesM3ToMoleculesCm3); @@ -77,12 +81,12 @@ TEST(ArrheniusConfig, ParseConfig) // second reaction { EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[0].species_name, "bar"); - EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[1].species_name, "baz"); + EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[0].name, "bar"); + EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[1].name, "baz"); EXPECT_EQ(mechanism.reactions.arrhenius[1].products.size(), 2); - EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].species_name, "bar"); + EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].name, "bar"); EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].coefficient, 0.5); - EXPECT_EQ(mechanism.reactions.arrhenius[1].products[1].species_name, "foo"); + EXPECT_EQ(mechanism.reactions.arrhenius[1].products[1].name, "foo"); EXPECT_EQ(mechanism.reactions.arrhenius[1].products[1].coefficient, 1.0); EXPECT_EQ(mechanism.reactions.arrhenius[1].A, 32.1 * conversions::MolesM3ToMoleculesCm3); EXPECT_EQ(mechanism.reactions.arrhenius[1].B, -2.3); @@ -94,12 +98,12 @@ TEST(ArrheniusConfig, ParseConfig) // third reaction { EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants[0].species_name, "bar"); - EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants[1].species_name, "baz"); + EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants[0].name, "bar"); + EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants[1].name, "baz"); EXPECT_EQ(mechanism.reactions.arrhenius[2].products.size(), 2); - EXPECT_EQ(mechanism.reactions.arrhenius[2].products[0].species_name, "bar"); + EXPECT_EQ(mechanism.reactions.arrhenius[2].products[0].name, "bar"); EXPECT_EQ(mechanism.reactions.arrhenius[2].products[0].coefficient, 0.5); - EXPECT_EQ(mechanism.reactions.arrhenius[2].products[1].species_name, "foo"); + EXPECT_EQ(mechanism.reactions.arrhenius[2].products[1].name, "foo"); EXPECT_EQ(mechanism.reactions.arrhenius[2].products[1].coefficient, 1.0); EXPECT_EQ(mechanism.reactions.arrhenius[2].A, 32.1 * conversions::MolesM3ToMoleculesCm3); EXPECT_EQ(mechanism.reactions.arrhenius[2].B, -2.3); @@ -119,13 +123,13 @@ TEST(ArrheniusConfig, DetectsNonstandardKeys) std::string file = "./v0_unit_configs/arrhenius/contains_nonstandard_key/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 3); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[2].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 3); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[2].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -139,11 +143,11 @@ TEST(ArrheniusConfig, DetectsNonstandardProductCoefficient) std::string file = "./v0_unit_configs/arrhenius/nonstandard_product_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -157,11 +161,11 @@ TEST(ArrheniusConfig, DetectsNonstandardReactantCoefficient) std::string file = "./v0_unit_configs/arrhenius/nonstandard_reactant_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } diff --git a/test/unit/v0/test_branched_config.cpp b/test/unit/v0/test_branched_config.cpp index 507d55d2..574f5df0 100644 --- a/test/unit/v0/test_branched_config.cpp +++ b/test/unit/v0/test_branched_config.cpp @@ -1,6 +1,10 @@ -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" #include @@ -15,43 +19,43 @@ TEST(BranchedConfig, DetectsInvalidConfig) std::string file = "./v0_unit_configs/branched/missing_reactants/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 5); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[2].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[3].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[4].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 5); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[2].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[3].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[4].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/branched/missing_alkoxy_products/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 5); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[2].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[3].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[4].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 5); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[2].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[3].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[4].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/branched/missing_nitrate_products/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 5); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[2].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[3].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[4].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 5); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[2].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[3].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[4].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -66,28 +70,28 @@ TEST(BranchedConfig, ParseConfig) std::string file = "./v0_unit_configs/branched/valid/config" + extension; auto parsed = parser.Parse(file); EXPECT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& process_vector = mechanism.reactions.branched; EXPECT_EQ(process_vector.size(), 2); // first reaction EXPECT_EQ(process_vector[0].reactants.size(), 2); - EXPECT_EQ(process_vector[0].reactants[0].species_name, "foo"); + EXPECT_EQ(process_vector[0].reactants[0].name, "foo"); EXPECT_EQ(process_vector[0].reactants[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].reactants[1].species_name, "quz"); + EXPECT_EQ(process_vector[0].reactants[1].name, "quz"); EXPECT_EQ(process_vector[0].reactants[1].coefficient, 2.0); EXPECT_EQ(process_vector[0].X, 12.3 * std::pow(conversions::MolesM3ToMoleculesCm3, 2)); EXPECT_EQ(process_vector[0].Y, 42.3); EXPECT_EQ(process_vector[0].a0, 1.0e-5); EXPECT_EQ(process_vector[0].n, 3); EXPECT_EQ(process_vector[0].alkoxy_products.size(), 2); - EXPECT_EQ(process_vector[0].alkoxy_products[0].species_name, "bar"); + EXPECT_EQ(process_vector[0].alkoxy_products[0].name, "bar"); EXPECT_EQ(process_vector[0].alkoxy_products[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].alkoxy_products[1].species_name, "baz"); + EXPECT_EQ(process_vector[0].alkoxy_products[1].name, "baz"); EXPECT_EQ(process_vector[0].alkoxy_products[1].coefficient, 3.2); EXPECT_EQ(process_vector[0].nitrate_products.size(), 1); - EXPECT_EQ(process_vector[0].nitrate_products[0].species_name, "quz"); + EXPECT_EQ(process_vector[0].nitrate_products[0].name, "quz"); EXPECT_EQ(process_vector[0].nitrate_products[0].coefficient, 1.0); // second reaction @@ -96,17 +100,17 @@ TEST(BranchedConfig, ParseConfig) EXPECT_EQ(process_vector[1].a0, 0.423); EXPECT_EQ(process_vector[1].alkoxy_products.size(), 1); EXPECT_EQ(process_vector[1].alkoxy_products[0].coefficient, 1.0); - EXPECT_EQ(process_vector[1].alkoxy_products[0].species_name, "baz"); + EXPECT_EQ(process_vector[1].alkoxy_products[0].name, "baz"); EXPECT_EQ(process_vector[1].n, 6); EXPECT_EQ(process_vector[1].nitrate_products.size(), 2); EXPECT_EQ(process_vector[1].nitrate_products[0].coefficient, 0.5); - EXPECT_EQ(process_vector[1].nitrate_products[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].nitrate_products[0].name, "bar"); EXPECT_EQ(process_vector[1].nitrate_products[1].coefficient, 1.0); - EXPECT_EQ(process_vector[1].nitrate_products[1].species_name, "foo"); + EXPECT_EQ(process_vector[1].nitrate_products[1].name, "foo"); EXPECT_EQ(process_vector[1].reactants.size(), 2); - EXPECT_EQ(process_vector[1].reactants[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].reactants[0].name, "bar"); EXPECT_EQ(process_vector[1].reactants[0].coefficient, 1.0); - EXPECT_EQ(process_vector[1].reactants[1].species_name, "baz"); + EXPECT_EQ(process_vector[1].reactants[1].name, "baz"); EXPECT_EQ(process_vector[1].reactants[1].coefficient, 1.0); } } @@ -120,12 +124,12 @@ TEST(BranchedConfig, DetectsNonstandardKeys) std::string file = "./v0_unit_configs/branched/contains_nonstandard_key/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 2); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -139,21 +143,21 @@ TEST(BranchedConfig, DetectsNonstandardProductCoefficient) std::string file = "./v0_unit_configs/branched/nonstandard_alkoxy_product_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/branched/nonstandard_nitrate_product_coef/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -167,11 +171,11 @@ TEST(BranchedConfig, DetectsNonstandardReactantCoefficient) std::string file = "./v0_unit_configs/branched/nonstandard_reactant_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } \ No newline at end of file diff --git a/test/unit/v0/test_emission_config.cpp b/test/unit/v0/test_emission_config.cpp index 6096d466..c753ed68 100644 --- a/test/unit/v0/test_emission_config.cpp +++ b/test/unit/v0/test_emission_config.cpp @@ -1,5 +1,9 @@ -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" #include @@ -14,21 +18,21 @@ TEST(EmissionConfig, DetectsInvalidConfig) std::string file = "./v0_unit_configs/emission/missing_products/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/emission/missing_MUSICA_name/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -43,7 +47,7 @@ TEST(EmissionConfig, ParseConfig) std::string file = "./v0_unit_configs/emission/valid/config" + extension; auto parsed = parser.Parse(file); EXPECT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& process_vector = mechanism.reactions.user_defined; EXPECT_EQ(process_vector.size(), 2); @@ -52,7 +56,7 @@ TEST(EmissionConfig, ParseConfig) { EXPECT_EQ(process_vector[0].reactants.size(), 0); EXPECT_EQ(process_vector[0].products.size(), 1); - EXPECT_EQ(process_vector[0].products[0].species_name, "foo"); + EXPECT_EQ(process_vector[0].products[0].name, "foo"); EXPECT_EQ(process_vector[0].products[0].coefficient, 1.0); EXPECT_EQ(process_vector[0].name, "EMIS.foo"); EXPECT_EQ(process_vector[0].scaling_factor, 1.0); @@ -62,7 +66,7 @@ TEST(EmissionConfig, ParseConfig) { EXPECT_EQ(process_vector[1].reactants.size(), 0); EXPECT_EQ(process_vector[1].products.size(), 1); - EXPECT_EQ(process_vector[1].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].products[0].name, "bar"); EXPECT_EQ(process_vector[1].products[0].coefficient, 1.0); EXPECT_EQ(process_vector[1].name, "EMIS.bar"); EXPECT_EQ(process_vector[1].scaling_factor, 2.5); @@ -79,11 +83,11 @@ TEST(EmissionConfig, DetectsNonstandardKeys) std::string file = "./v0_unit_configs/emission/contains_nonstandard_key/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } \ No newline at end of file diff --git a/test/unit/v0/test_first_order_loss_config.cpp b/test/unit/v0/test_first_order_loss_config.cpp index d24f42cd..60fab0a5 100644 --- a/test/unit/v0/test_first_order_loss_config.cpp +++ b/test/unit/v0/test_first_order_loss_config.cpp @@ -1,5 +1,9 @@ -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" #include @@ -14,21 +18,21 @@ TEST(FirstOrderLossConfig, DetectsInvalidConfig) std::string file = "./v0_unit_configs/first_order_loss/missing_reactants/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/first_order_loss/missing_MUSICA_name/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -43,7 +47,7 @@ TEST(FirstOrderLossConfig, ParseConfig) std::string file = "./v0_unit_configs/first_order_loss/valid/config" + extension; auto parsed = parser.Parse(file); EXPECT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& process_vector = mechanism.reactions.user_defined; EXPECT_EQ(process_vector.size(), 2); @@ -52,7 +56,7 @@ TEST(FirstOrderLossConfig, ParseConfig) { EXPECT_EQ(process_vector[0].reactants.size(), 1); EXPECT_EQ(process_vector[0].products.size(), 0); - EXPECT_EQ(process_vector[0].reactants[0].species_name, "foo"); + EXPECT_EQ(process_vector[0].reactants[0].name, "foo"); EXPECT_EQ(process_vector[0].name, "LOSS.foo"); EXPECT_EQ(process_vector[0].scaling_factor, 1.0); } @@ -61,7 +65,7 @@ TEST(FirstOrderLossConfig, ParseConfig) { EXPECT_EQ(process_vector[1].reactants.size(), 1); EXPECT_EQ(process_vector[1].products.size(), 0); - EXPECT_EQ(process_vector[1].reactants[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].reactants[0].name, "bar"); EXPECT_EQ(process_vector[1].name, "LOSS.bar"); EXPECT_EQ(process_vector[1].scaling_factor, 2.5); } @@ -77,11 +81,11 @@ TEST(FirstOrderLossConfig, DetectsNonstandardKeys) std::string file = "./v0_unit_configs/first_order_loss/contains_nonstandard_key/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } \ No newline at end of file diff --git a/test/unit/v0/test_photolysis_config.cpp b/test/unit/v0/test_photolysis_config.cpp index a5a0d47f..afb82a3f 100644 --- a/test/unit/v0/test_photolysis_config.cpp +++ b/test/unit/v0/test_photolysis_config.cpp @@ -1,5 +1,9 @@ -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" #include @@ -14,31 +18,31 @@ TEST(PhotolysisConfig, DetectsInvalidConfig) std::string file = "./v0_unit_configs/photolysis/missing_reactants/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/photolysis/missing_products/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/photolysis/missing_MUSICA_name/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -53,7 +57,7 @@ TEST(PhotolysisConfig, ParseConfig) std::string file = "./v0_unit_configs/photolysis/valid/config" + extension; auto parsed = parser.Parse(file); EXPECT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& process_vector = mechanism.reactions.user_defined; EXPECT_EQ(process_vector.size(), 2); @@ -61,11 +65,11 @@ TEST(PhotolysisConfig, ParseConfig) // first reaction { EXPECT_EQ(process_vector[0].reactants.size(), 1); - EXPECT_EQ(process_vector[0].reactants[0].species_name, "foo"); + EXPECT_EQ(process_vector[0].reactants[0].name, "foo"); EXPECT_EQ(process_vector[0].products.size(), 2); - EXPECT_EQ(process_vector[0].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[0].products[0].name, "bar"); EXPECT_EQ(process_vector[0].products[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].products[1].species_name, "baz"); + EXPECT_EQ(process_vector[0].products[1].name, "baz"); EXPECT_EQ(process_vector[0].products[1].coefficient, 3.2); EXPECT_EQ(process_vector[0].name, "PHOTO.jfoo"); EXPECT_EQ(process_vector[0].scaling_factor, 1.0); @@ -74,11 +78,11 @@ TEST(PhotolysisConfig, ParseConfig) // second reaction { EXPECT_EQ(process_vector[1].reactants.size(), 1); - EXPECT_EQ(process_vector[1].reactants[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].reactants[0].name, "bar"); EXPECT_EQ(process_vector[1].products.size(), 2); - EXPECT_EQ(process_vector[1].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].products[0].name, "bar"); EXPECT_EQ(process_vector[1].products[0].coefficient, 0.5); - EXPECT_EQ(process_vector[1].products[1].species_name, "foo"); + EXPECT_EQ(process_vector[1].products[1].name, "foo"); EXPECT_EQ(process_vector[1].products[1].coefficient, 1.0); EXPECT_EQ(process_vector[1].name, "PHOTO.jbar"); EXPECT_EQ(process_vector[1].scaling_factor, 2.5); @@ -95,11 +99,11 @@ TEST(PhotolysisConfig, DetectsNonstandardKeys) std::string file = "./v0_unit_configs/photolysis/contains_nonstandard_key/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -113,11 +117,11 @@ TEST(PhotolysisConfig, DetectsNonstandardProductCoefficient) std::string file = "./v0_unit_configs/photolysis/nonstandard_product_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -131,11 +135,11 @@ TEST(PhotolysisConfig, DetectsNonstandardReactantCoefficient) std::string file = "./v0_unit_configs/photolysis/nonstandard_reactant_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } \ No newline at end of file diff --git a/test/unit/v0/test_species_config.cpp b/test/unit/v0/test_species_config.cpp index 7cbd29dc..04e936bf 100644 --- a/test/unit/v0/test_species_config.cpp +++ b/test/unit/v0/test_species_config.cpp @@ -1,5 +1,9 @@ -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" #include @@ -17,12 +21,12 @@ TEST(SpeciesConfig, ValidSpeciesConfig) EXPECT_TRUE(parsed); if (!parsed) { - for (auto& error : parsed.errors) + for (auto& error : parsed.error()) { std::cerr << error.second << std::endl; } } - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& species_vector = mechanism.species; EXPECT_EQ(species_vector.size(), 4); diff --git a/test/unit/v0/test_surface_config.cpp b/test/unit/v0/test_surface_config.cpp index d9cdf227..bff6b80d 100644 --- a/test/unit/v0/test_surface_config.cpp +++ b/test/unit/v0/test_surface_config.cpp @@ -1,5 +1,9 @@ -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" #include @@ -14,31 +18,31 @@ TEST(SurfaceConfig, DetectsInvalidConfig) std::string file = "./v0_unit_configs/surface/missing_reactants/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/surface/missing_products/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/surface/missing_MUSICA_name/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -53,43 +57,43 @@ TEST(SurfaceConfig, ParseConfig) std::string file = "./v0_unit_configs/surface/valid/config" + extension; auto parsed = parser.Parse(file); EXPECT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& process_vector = mechanism.reactions.surface; EXPECT_EQ(process_vector.size(), 2); // first reaction { - EXPECT_EQ(process_vector[0].gas_phase_species.species_name, "foo"); + EXPECT_EQ(process_vector[0].gas_phase_species.name, "foo"); EXPECT_EQ(process_vector[0].gas_phase_products.size(), 2); - EXPECT_EQ(process_vector[0].gas_phase_products[0].species_name, "bar"); + EXPECT_EQ(process_vector[0].gas_phase_products[0].name, "bar"); EXPECT_EQ(process_vector[0].gas_phase_products[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].gas_phase_products[1].species_name, "baz"); + EXPECT_EQ(process_vector[0].gas_phase_products[1].name, "baz"); EXPECT_EQ(process_vector[0].gas_phase_products[1].coefficient, 3.2); EXPECT_EQ(process_vector[0].name, "SURF.kfoo"); EXPECT_EQ(process_vector[0].reaction_probability, 1.0); auto it = std::find_if( mechanism.species.begin(), mechanism.species.end(), - [](const v0::types::Species& species) { return species.name == "foo"; }); + [](const types::Species& species) { return species.name == "foo"; }); ASSERT_NE(it, mechanism.species.end()); EXPECT_EQ(it->diffusion_coefficient, 2.3e-4); } // second reaction { - EXPECT_EQ(process_vector[1].gas_phase_species.species_name, "bar"); + EXPECT_EQ(process_vector[1].gas_phase_species.name, "bar"); EXPECT_EQ(process_vector[1].gas_phase_products.size(), 2); - EXPECT_EQ(process_vector[1].gas_phase_products[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].gas_phase_products[0].name, "bar"); EXPECT_EQ(process_vector[1].gas_phase_products[0].coefficient, 0.5); - EXPECT_EQ(process_vector[1].gas_phase_products[1].species_name, "foo"); + EXPECT_EQ(process_vector[1].gas_phase_products[1].name, "foo"); EXPECT_EQ(process_vector[1].gas_phase_products[1].coefficient, 1.0); EXPECT_EQ(process_vector[1].name, "SURF.kbar"); EXPECT_EQ(process_vector[1].reaction_probability, 0.5); auto it = std::find_if( mechanism.species.begin(), mechanism.species.end(), - [](const v0::types::Species& species) { return species.name == "bar"; }); + [](const types::Species& species) { return species.name == "bar"; }); ASSERT_NE(it, mechanism.species.end()); EXPECT_EQ(it->diffusion_coefficient, 0.4e-5); } @@ -105,11 +109,11 @@ TEST(SurfaceConfig, DetectsNonstandardKeys) std::string file = "./v0_unit_configs/surface/contains_nonstandard_key/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -123,11 +127,11 @@ TEST(SurfaceConfig, DetectsNonstandardProductCoefficient) std::string file = "./v0_unit_configs/surface/nonstandard_product_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } \ No newline at end of file diff --git a/test/unit/v0/test_ternary_chemical_activation_config.cpp b/test/unit/v0/test_ternary_chemical_activation_config.cpp index 5d3dcb9e..c85edf72 100644 --- a/test/unit/v0/test_ternary_chemical_activation_config.cpp +++ b/test/unit/v0/test_ternary_chemical_activation_config.cpp @@ -1,6 +1,10 @@ -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" #include @@ -15,21 +19,21 @@ TEST(TernaryChemicalActivationConfig, DetectsInvalidConfig) std::string file = "./v0_unit_configs/ternary_chemical_activation/missing_reactants/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/ternary_chemical_activation/missing_products/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -44,7 +48,7 @@ TEST(TernaryChemicalActivationConfig, ParseConfig) std::string file = "./v0_unit_configs/ternary_chemical_activation/valid/config" + extension; auto parsed = parser.Parse(file); EXPECT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& process_vector = mechanism.reactions.ternary_chemical_activation; EXPECT_EQ(process_vector.size(), 2); @@ -52,14 +56,14 @@ TEST(TernaryChemicalActivationConfig, ParseConfig) // first reaction { EXPECT_EQ(process_vector[0].reactants.size(), 2); - EXPECT_EQ(process_vector[0].reactants[0].species_name, "foo"); + EXPECT_EQ(process_vector[0].reactants[0].name, "foo"); EXPECT_EQ(process_vector[0].reactants[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].reactants[1].species_name, "quz"); + EXPECT_EQ(process_vector[0].reactants[1].name, "quz"); EXPECT_EQ(process_vector[0].reactants[1].coefficient, 2.0); EXPECT_EQ(process_vector[0].products.size(), 2); - EXPECT_EQ(process_vector[0].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[0].products[0].name, "bar"); EXPECT_EQ(process_vector[0].products[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].products[1].species_name, "baz"); + EXPECT_EQ(process_vector[0].products[1].name, "baz"); EXPECT_EQ(process_vector[0].products[1].coefficient, 3.2); EXPECT_EQ(process_vector[0].k0_A, 1.0 * std::pow(conversions::MolesM3ToMoleculesCm3, 3)); EXPECT_EQ(process_vector[0].k0_B, 0.0); @@ -74,12 +78,12 @@ TEST(TernaryChemicalActivationConfig, ParseConfig) // second reaction { EXPECT_EQ(process_vector[1].reactants.size(), 2); - EXPECT_EQ(process_vector[1].reactants[0].species_name, "bar"); - EXPECT_EQ(process_vector[1].reactants[1].species_name, "baz"); + EXPECT_EQ(process_vector[1].reactants[0].name, "bar"); + EXPECT_EQ(process_vector[1].reactants[1].name, "baz"); EXPECT_EQ(process_vector[1].products.size(), 2); - EXPECT_EQ(process_vector[1].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].products[0].name, "bar"); EXPECT_EQ(process_vector[1].products[0].coefficient, 0.5); - EXPECT_EQ(process_vector[1].products[1].species_name, "foo"); + EXPECT_EQ(process_vector[1].products[1].name, "foo"); EXPECT_EQ(process_vector[1].products[1].coefficient, 1.0); EXPECT_EQ(process_vector[1].k0_A, 32.1 * std::pow(conversions::MolesM3ToMoleculesCm3, 2)); EXPECT_EQ(process_vector[1].k0_B, -2.3); @@ -102,18 +106,18 @@ TEST(TernaryChemicalActivationConfig, DetectsNonstandardKeys) std::string file = "./v0_unit_configs/ternary_chemical_activation/contains_nonstandard_key/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 8); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[2].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[3].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[4].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[5].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[6].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[7].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 8); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[2].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[3].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[4].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[5].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[6].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[7].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -127,11 +131,11 @@ TEST(TernaryChemicalActivationConfig, DetectsNonstandardProductCoefficient) std::string file = "./v0_unit_configs/ternary_chemical_activation/nonstandard_product_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -145,11 +149,11 @@ TEST(TernaryChemicalActivationConfig, DetectsNonstandardReactantCoefficient) std::string file = "./v0_unit_configs/ternary_chemical_activation/nonstandard_reactant_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } \ No newline at end of file diff --git a/test/unit/v0/test_troe_config.cpp b/test/unit/v0/test_troe_config.cpp index b854955a..e26c8b74 100644 --- a/test/unit/v0/test_troe_config.cpp +++ b/test/unit/v0/test_troe_config.cpp @@ -1,6 +1,10 @@ -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" #include @@ -15,21 +19,21 @@ TEST(TroeConfig, DetectsInvalidConfig) std::string file = "./v0_unit_configs/troe/missing_reactants/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/troe/missing_products/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -44,7 +48,7 @@ TEST(TroeConfig, ParseConfig) std::string file = "./v0_unit_configs/troe/valid/config" + extension; auto parsed = parser.Parse(file); EXPECT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& process_vector = mechanism.reactions.troe; EXPECT_EQ(process_vector.size(), 2); @@ -52,14 +56,14 @@ TEST(TroeConfig, ParseConfig) // first reaction { EXPECT_EQ(process_vector[0].reactants.size(), 2); - EXPECT_EQ(process_vector[0].reactants[0].species_name, "foo"); + EXPECT_EQ(process_vector[0].reactants[0].name, "foo"); EXPECT_EQ(process_vector[0].reactants[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].reactants[1].species_name, "quz"); + EXPECT_EQ(process_vector[0].reactants[1].name, "quz"); EXPECT_EQ(process_vector[0].reactants[1].coefficient, 2.0); EXPECT_EQ(process_vector[0].products.size(), 2); - EXPECT_EQ(process_vector[0].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[0].products[0].name, "bar"); EXPECT_EQ(process_vector[0].products[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].products[1].species_name, "baz"); + EXPECT_EQ(process_vector[0].products[1].name, "baz"); EXPECT_EQ(process_vector[0].products[1].coefficient, 3.2); EXPECT_EQ(process_vector[0].k0_A, 1.0 * std::pow(conversions::MolesM3ToMoleculesCm3, 3)); EXPECT_EQ(process_vector[0].k0_B, 0.0); @@ -74,12 +78,12 @@ TEST(TroeConfig, ParseConfig) // second reaction { EXPECT_EQ(process_vector[1].reactants.size(), 2); - EXPECT_EQ(process_vector[1].reactants[0].species_name, "bar"); - EXPECT_EQ(process_vector[1].reactants[1].species_name, "baz"); + EXPECT_EQ(process_vector[1].reactants[0].name, "bar"); + EXPECT_EQ(process_vector[1].reactants[1].name, "baz"); EXPECT_EQ(process_vector[1].products.size(), 2); - EXPECT_EQ(process_vector[1].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].products[0].name, "bar"); EXPECT_EQ(process_vector[1].products[0].coefficient, 0.5); - EXPECT_EQ(process_vector[1].products[1].species_name, "foo"); + EXPECT_EQ(process_vector[1].products[1].name, "foo"); EXPECT_EQ(process_vector[1].products[1].coefficient, 1.0); EXPECT_EQ(process_vector[1].k0_A, 32.1 * std::pow(conversions::MolesM3ToMoleculesCm3, 2)); EXPECT_EQ(process_vector[1].k0_B, -2.3); @@ -102,18 +106,18 @@ TEST(TroeConfig, DetectsNonstandardKeys) std::string file = "./v0_unit_configs/troe/contains_nonstandard_key/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 8); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[2].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[3].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[4].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[5].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[6].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[7].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 8); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[2].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[3].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[4].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[5].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[6].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[7].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -127,11 +131,11 @@ TEST(TroeConfig, DetectsNonstandardProductCoefficient) std::string file = "./v0_unit_configs/troe/nonstandard_product_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -145,11 +149,11 @@ TEST(TroeConfig, DetectsNonstandardReactantCoefficient) std::string file = "./v0_unit_configs/troe/nonstandard_reactant_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } \ No newline at end of file diff --git a/test/unit/v0/test_tunneling_config.cpp b/test/unit/v0/test_tunneling_config.cpp index e9bfbb4c..c2b86f63 100644 --- a/test/unit/v0/test_tunneling_config.cpp +++ b/test/unit/v0/test_tunneling_config.cpp @@ -1,6 +1,10 @@ -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/conversions.hpp" +#include "detail/v0/parser.hpp" #include @@ -15,21 +19,21 @@ TEST(TunnelingConfig, DetectsInvalidConfig) std::string file = "./v0_unit_configs/tunneling/missing_reactants/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/tunneling/missing_products/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -44,7 +48,7 @@ TEST(TunnelingConfig, ParseConfig) std::string file = "./v0_unit_configs/tunneling/valid/config" + extension; auto parsed = parser.Parse(file); EXPECT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& process_vector = mechanism.reactions.tunneling; EXPECT_EQ(process_vector.size(), 2); @@ -52,14 +56,14 @@ TEST(TunnelingConfig, ParseConfig) // first reaction { EXPECT_EQ(process_vector[0].reactants.size(), 2); - EXPECT_EQ(process_vector[0].reactants[0].species_name, "foo"); + EXPECT_EQ(process_vector[0].reactants[0].name, "foo"); EXPECT_EQ(process_vector[0].reactants[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].reactants[1].species_name, "quz"); + EXPECT_EQ(process_vector[0].reactants[1].name, "quz"); EXPECT_EQ(process_vector[0].reactants[1].coefficient, 2.0); EXPECT_EQ(process_vector[0].products.size(), 2); - EXPECT_EQ(process_vector[0].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[0].products[0].name, "bar"); EXPECT_EQ(process_vector[0].products[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].products[1].species_name, "baz"); + EXPECT_EQ(process_vector[0].products[1].name, "baz"); EXPECT_EQ(process_vector[0].products[1].coefficient, 3.2); EXPECT_EQ(process_vector[0].A, 1.0 * std::pow(conversions::MolesM3ToMoleculesCm3, 2)); EXPECT_EQ(process_vector[0].B, 0.0); @@ -69,12 +73,12 @@ TEST(TunnelingConfig, ParseConfig) // second reaction { EXPECT_EQ(process_vector[1].reactants.size(), 2); - EXPECT_EQ(process_vector[1].reactants[0].species_name, "bar"); - EXPECT_EQ(process_vector[1].reactants[1].species_name, "baz"); + EXPECT_EQ(process_vector[1].reactants[0].name, "bar"); + EXPECT_EQ(process_vector[1].reactants[1].name, "baz"); EXPECT_EQ(process_vector[1].products.size(), 2); - EXPECT_EQ(process_vector[1].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].products[0].name, "bar"); EXPECT_EQ(process_vector[1].products[0].coefficient, 0.5); - EXPECT_EQ(process_vector[1].products[1].species_name, "foo"); + EXPECT_EQ(process_vector[1].products[1].name, "foo"); EXPECT_EQ(process_vector[1].products[1].coefficient, 1.0); EXPECT_EQ(process_vector[1].A, 32.1 * conversions::MolesM3ToMoleculesCm3); EXPECT_EQ(process_vector[1].B, -2.3); @@ -92,11 +96,11 @@ TEST(TunnelingConfig, DetectsNonstandardKeys) std::string file = "./v0_unit_configs/tunneling/contains_nonstandard_key/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -110,11 +114,11 @@ TEST(TunnelingConfig, DetectsNonstandardProductCoefficient) std::string file = "./v0_unit_configs/tunneling/nonstandard_product_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -128,11 +132,11 @@ TEST(TunnelingConfig, DetectsNonstandardReactantCoefficient) std::string file = "./v0_unit_configs/tunneling/nonstandard_reactant_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } \ No newline at end of file diff --git a/test/unit/v0/test_user_defined_config.cpp b/test/unit/v0/test_user_defined_config.cpp index e72803ad..7cf1d13c 100644 --- a/test/unit/v0/test_user_defined_config.cpp +++ b/test/unit/v0/test_user_defined_config.cpp @@ -1,5 +1,9 @@ -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/v0/parser.hpp" #include @@ -14,31 +18,31 @@ TEST(UserDefinedConfig, DetectsInvalidConfig) std::string file = "./v0_unit_configs/user_defined/missing_reactants/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/user_defined/missing_products/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } file = "./v0_unit_configs/user_defined/missing_MUSICA_name/config" + extension; parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -53,7 +57,7 @@ TEST(UserDefinedConfig, ParseConfig) std::string file = "./v0_unit_configs/user_defined/valid/config" + extension; auto parsed = parser.Parse(file); EXPECT_TRUE(parsed); - v0::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& process_vector = mechanism.reactions.user_defined; EXPECT_EQ(process_vector.size(), 2); @@ -63,14 +67,14 @@ TEST(UserDefinedConfig, ParseConfig) // first reaction { EXPECT_EQ(process_vector[0].reactants.size(), 2); - EXPECT_EQ(process_vector[0].reactants[0].species_name, "foo"); + EXPECT_EQ(process_vector[0].reactants[0].name, "foo"); EXPECT_EQ(process_vector[0].reactants[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].reactants[1].species_name, "bar"); + EXPECT_EQ(process_vector[0].reactants[1].name, "bar"); EXPECT_EQ(process_vector[0].reactants[1].coefficient, 2.0); EXPECT_EQ(process_vector[0].products.size(), 2); - EXPECT_EQ(process_vector[0].products[0].species_name, "baz"); + EXPECT_EQ(process_vector[0].products[0].name, "baz"); EXPECT_EQ(process_vector[0].products[0].coefficient, 1.4); - EXPECT_EQ(process_vector[0].products[1].species_name, "foo"); + EXPECT_EQ(process_vector[0].products[1].name, "foo"); EXPECT_EQ(process_vector[0].products[1].coefficient, 1.0); EXPECT_EQ(process_vector[0].name, "USER.foo"); EXPECT_EQ(process_vector[0].scaling_factor, 1.0); @@ -79,10 +83,10 @@ TEST(UserDefinedConfig, ParseConfig) // second reaction { EXPECT_EQ(process_vector[1].reactants.size(), 1); - EXPECT_EQ(process_vector[1].reactants[0].species_name, "foo"); + EXPECT_EQ(process_vector[1].reactants[0].name, "foo"); EXPECT_EQ(process_vector[1].reactants[0].coefficient, 2.0); EXPECT_EQ(process_vector[1].products.size(), 1); - EXPECT_EQ(process_vector[1].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].products[0].name, "bar"); EXPECT_EQ(process_vector[1].products[0].coefficient, 1.0); EXPECT_EQ(process_vector[1].name, "USER.bar"); EXPECT_EQ(process_vector[1].scaling_factor, 2.5); @@ -99,11 +103,11 @@ TEST(UserDefinedConfig, DetectsNonstandardKeys) std::string file = "./v0_unit_configs/user_defined/contains_nonstandard_key/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -117,11 +121,11 @@ TEST(UserDefinedConfig, DetectsNonstandardProductCoefficient) std::string file = "./v0_unit_configs/user_defined/nonstandard_product_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } @@ -135,11 +139,11 @@ TEST(UserDefinedConfig, DetectsNonstandardReactantCoefficient) std::string file = "./v0_unit_configs/user_defined/nonstandard_reactant_coef/config" + extension; auto parsed = parser.Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } diff --git a/test/unit/v1/file_configs/test_parse_from_file_configs.cpp b/test/unit/v1/file_configs/test_parse_from_file_configs.cpp index 65581477..dd0be2c9 100644 --- a/test/unit/v1/file_configs/test_parse_from_file_configs.cpp +++ b/test/unit/v1/file_configs/test_parse_from_file_configs.cpp @@ -2,8 +2,8 @@ // University of Illinois at Urbana-Champaign // SPDX-License-Identifier: Apache-2.0 -#include -#include +#include +#include #include @@ -21,8 +21,7 @@ const std::string configBase = "test/unit/v1/file_configs/configs/"; TEST(ParseFromFileConfigs, TwoSpeciesSets) { - v1::Parser parser; - auto parsed = parser.Parse(configBase + "two_species_sets/main.json"); + auto parsed = Parse(configBase + "two_species_sets/main.json"); ASSERT_TRUE(parsed); auto& mechanism = *parsed; @@ -49,8 +48,7 @@ TEST(ParseFromFileConfigs, TwoSpeciesSets) TEST(ParseFromFileConfigs, TwoPhasesSets) { - v1::Parser parser; - auto parsed = parser.Parse(configBase + "two_phases_sets/main.json"); + auto parsed = Parse(configBase + "two_phases_sets/main.json"); ASSERT_TRUE(parsed); auto& mechanism = *parsed; @@ -70,14 +68,13 @@ TEST(ParseFromFileConfigs, TwoPhasesSets) TEST(ParseFromFileConfigs, MissingPhaseSet) { - v1::Parser parser; - auto parsed = parser.Parse(configBase + "missing_phase_set/main.json"); + auto parsed = Parse(configBase + "missing_phase_set/main.json"); EXPECT_FALSE(parsed); - ASSERT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (const auto& error : parsed.errors) - std::cout << error.second << " " << configParseStatusToString(error.first) << "\n"; + ASSERT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (const auto& error : parsed.error()) + std::cout << error.second << " " << ErrorCodeToString(error.first) << "\n"; } // ── missing_reaction_set ────────────────────────────────────────────────────── @@ -85,8 +82,7 @@ TEST(ParseFromFileConfigs, MissingPhaseSet) TEST(ParseFromFileConfigs, MissingReactionSet) { - v1::Parser parser; - auto parsed = parser.Parse(configBase + "missing_reaction_set/main.json"); + auto parsed = Parse(configBase + "missing_reaction_set/main.json"); ASSERT_TRUE(parsed); auto& mechanism = *parsed; @@ -95,33 +91,31 @@ TEST(ParseFromFileConfigs, MissingReactionSet) } // ── missing_species_set ─────────────────────────────────────────────────────── -// "species" key absent from main.json : RequiredKeyNotFound from ValidateSchema +// "species" key absent from main.json : RequiredKeyNotFound from CheckSchema TEST(ParseFromFileConfigs, MissingSpeciesSet) { - v1::Parser parser; - auto parsed = parser.Parse(configBase + "missing_species_set/main.json"); + auto parsed = Parse(configBase + "missing_species_set/main.json"); EXPECT_FALSE(parsed); - ASSERT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (const auto& error : parsed.errors) - std::cout << error.second << " " << configParseStatusToString(error.first) << "\n"; + ASSERT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (const auto& error : parsed.error()) + std::cout << error.second << " " << ErrorCodeToString(error.first) << "\n"; } // ── version_mismatch ────────────────────────────────────────────────────────── -// version "1.3.0" : minor != 1 for file-list format : InvalidVersion +// version "1.0.0" : file-list layout requires minor >= 1 (v1.1+) : InvalidVersion TEST(ParseFromFileConfigs, VersionMismatch) { - v1::Parser parser; - auto parsed = parser.Parse(configBase + "version_mismatch/main.json"); + auto parsed = Parse(configBase + "version_mismatch/main.json"); EXPECT_FALSE(parsed); - ASSERT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidVersion); - for (const auto& error : parsed.errors) - std::cout << error.second << " " << configParseStatusToString(error.first) << "\n"; + ASSERT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidVersion); + for (const auto& error : parsed.error()) + std::cout << error.second << " " << ErrorCodeToString(error.first) << "\n"; } // ── mixed_inline_species ────────────────────────────────────────────────────── @@ -129,8 +123,7 @@ TEST(ParseFromFileConfigs, VersionMismatch) TEST(ParseFromFileConfigs, MixedInlineSpecies) { - v1::Parser parser; - auto parsed = parser.Parse(configBase + "mixed_inline_species/main.json"); + auto parsed = Parse(configBase + "mixed_inline_species/main.json"); ASSERT_TRUE(parsed); auto& mechanism = *parsed; @@ -152,8 +145,7 @@ TEST(ParseFromFileConfigs, MixedInlineSpecies) TEST(ParseFromFileConfigs, MixedInlineReactions) { - v1::Parser parser; - auto parsed = parser.Parse(configBase + "mixed_inline_reactions/main.json"); + auto parsed = Parse(configBase + "mixed_inline_reactions/main.json"); ASSERT_TRUE(parsed); auto& mechanism = *parsed; @@ -173,14 +165,13 @@ TEST(ParseFromFileConfigs, MixedInlineReactions) TEST(ParseFromFileConfigs, DuplicateSpeciesSet) { - v1::Parser parser; - auto parsed = parser.Parse(configBase + "duplicate_species_set/main.json"); + auto parsed = Parse(configBase + "duplicate_species_set/main.json"); EXPECT_FALSE(parsed); - ASSERT_EQ(parsed.errors.size(), 6); - for (const auto& error : parsed.errors) + ASSERT_EQ(parsed.error().size(), 6); + for (const auto& error : parsed.error()) { - EXPECT_EQ(error.first, ConfigParseStatus::DuplicateSpeciesDetected); - std::cout << error.second << " " << configParseStatusToString(error.first) << "\n"; + EXPECT_EQ(error.first, ErrorCode::DuplicateSpeciesDetected); + std::cout << error.second << " " << ErrorCodeToString(error.first) << "\n"; } } diff --git a/test/unit/v1/reactions/test_parse_arrhenius.cpp b/test/unit/v1/reactions/test_parse_arrhenius.cpp index 0ae897ae..44261204 100644 --- a/test/unit/v1/reactions/test_parse_arrhenius.cpp +++ b/test/unit/v1/reactions/test_parse_arrhenius.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,13 +10,12 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidArrheniusReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/arrhenius/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/arrhenius/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.arrhenius.size(), 3); @@ -24,12 +27,12 @@ TEST(ParserBase, CanParseValidArrheniusReaction) EXPECT_EQ(mechanism.reactions.arrhenius[0].D, 63.4); EXPECT_EQ(mechanism.reactions.arrhenius[0].E, -1.3); EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants[0].name, "A"); EXPECT_EQ(mechanism.reactions.arrhenius[0].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.arrhenius[0].products.size(), 2); - EXPECT_EQ(mechanism.reactions.arrhenius[0].products[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.arrhenius[0].products[0].name, "B"); EXPECT_EQ(mechanism.reactions.arrhenius[0].products[0].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.arrhenius[0].products[1].species_name, "C"); + EXPECT_EQ(mechanism.reactions.arrhenius[0].products[1].name, "C"); EXPECT_EQ(mechanism.reactions.arrhenius[0].products[1].coefficient, 0.3); EXPECT_EQ(mechanism.reactions.arrhenius[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.arrhenius[0].unknown_properties["__solver_param"], "0.1"); @@ -42,12 +45,12 @@ TEST(ParserBase, CanParseValidArrheniusReaction) EXPECT_EQ(mechanism.reactions.arrhenius[1].D, 6.4); EXPECT_EQ(mechanism.reactions.arrhenius[1].E, -0.3); EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[0].name, "A"); EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[0].coefficient, 2); - EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[1].species_name, "B"); + EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[1].name, "B"); EXPECT_EQ(mechanism.reactions.arrhenius[1].reactants[1].coefficient, 0.1); EXPECT_EQ(mechanism.reactions.arrhenius[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].coefficient, 0.5); EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.arrhenius[1].products[0].unknown_properties["__optional thing"], "hello"); @@ -60,83 +63,79 @@ TEST(ParserBase, CanParseValidArrheniusReaction) EXPECT_EQ(mechanism.reactions.arrhenius[2].D, 300); EXPECT_EQ(mechanism.reactions.arrhenius[2].E, 0); EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants[0].name, "A"); EXPECT_EQ(mechanism.reactions.arrhenius[2].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.arrhenius[2].products.size(), 1); - EXPECT_EQ(mechanism.reactions.arrhenius[2].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.arrhenius[2].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.arrhenius[2].products[0].coefficient, 1); } } TEST(ParserBase, ArrheniusDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/arrhenius/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, ArrheniusDetectsMutuallyExclusiveOptions) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/arrhenius/mutually_exclusive") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::MutuallyExclusiveOption); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::MutuallyExclusiveOption); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, ArrheniusDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/arrhenius/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 2); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, ArrheniusDetectsUnknownPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/arrhenius/missing_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } -} \ No newline at end of file +} diff --git a/test/unit/v1/reactions/test_parse_branched.cpp b/test/unit/v1/reactions/test_parse_branched.cpp index ec8de691..ea201cbf 100644 --- a/test/unit/v1/reactions/test_parse_branched.cpp +++ b/test/unit/v1/reactions/test_parse_branched.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,13 +10,12 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidBranchedReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/branched/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/branched/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.branched.size(), 1); @@ -23,17 +26,17 @@ TEST(ParserBase, CanParseValidBranchedReaction) EXPECT_EQ(mechanism.reactions.branched[0].a0, 0.15); EXPECT_EQ(mechanism.reactions.branched[0].n, 9); EXPECT_EQ(mechanism.reactions.branched[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.branched[0].reactants[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.branched[0].reactants[0].name, "A"); EXPECT_EQ(mechanism.reactions.branched[0].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products.size(), 1); - EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products[0].name, "C"); EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products[0].coefficient, 1.2); EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.branched[0].nitrate_products[0].unknown_properties["__thing"], "hi"); EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products.size(), 2); - EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products[0].name, "B"); EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products[0].coefficient, 0.2); - EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products[1].species_name, "A"); + EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products[1].name, "A"); EXPECT_EQ(mechanism.reactions.branched[0].alkoxy_products[1].coefficient, 1.2); EXPECT_EQ(mechanism.reactions.branched[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.branched[0].unknown_properties["__comment"], "thing"); @@ -42,56 +45,52 @@ TEST(ParserBase, CanParseValidBranchedReaction) TEST(ParserBase, BranchedDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/branched/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, BranchedDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/branched/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 3); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[2].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, BranchedDetectsUnknownPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/branched/missing_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } -} \ No newline at end of file +} diff --git a/test/unit/v1/reactions/test_parse_emission.cpp b/test/unit/v1/reactions/test_parse_emission.cpp index 8a27759d..6f1cde84 100644 --- a/test/unit/v1/reactions/test_parse_emission.cpp +++ b/test/unit/v1/reactions/test_parse_emission.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,13 +10,12 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidEmissionReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/emission/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/emission/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.emission.size(), 2); @@ -20,7 +23,7 @@ TEST(ParserBase, CanParseValidEmissionReaction) EXPECT_EQ(mechanism.reactions.emission[0].name, "my emission"); EXPECT_EQ(mechanism.reactions.emission[0].scaling_factor, 12.3); EXPECT_EQ(mechanism.reactions.emission[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.emission[0].products[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.emission[0].products[0].name, "B"); EXPECT_EQ(mechanism.reactions.emission[0].products[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.emission[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.emission[0].unknown_properties["__comment"], "Dr. Pepper outranks any other soda"); @@ -28,62 +31,59 @@ TEST(ParserBase, CanParseValidEmissionReaction) EXPECT_EQ(mechanism.reactions.emission[1].gas_phase, "gas"); EXPECT_EQ(mechanism.reactions.emission[1].scaling_factor, 1); EXPECT_EQ(mechanism.reactions.emission[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.emission[1].products[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.emission[1].products[0].name, "B"); EXPECT_EQ(mechanism.reactions.emission[1].products[0].coefficient, 1); } } TEST(ParserBase, EmissionDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/emission/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, EmissionDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/emission/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 2); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, EmissionDetectsUnknownPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/emission/missing_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } -} \ No newline at end of file +} diff --git a/test/unit/v1/reactions/test_parse_first_order_loss.cpp b/test/unit/v1/reactions/test_parse_first_order_loss.cpp index 52df3133..de8f2238 100644 --- a/test/unit/v1/reactions/test_parse_first_order_loss.cpp +++ b/test/unit/v1/reactions/test_parse_first_order_loss.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,129 +10,120 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidFirstOrderLossReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/first_order_loss/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/first_order_loss/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.first_order_loss.size(), 2); EXPECT_EQ(mechanism.reactions.first_order_loss[0].gas_phase, "gas"); EXPECT_EQ(mechanism.reactions.first_order_loss[0].name, "my first order loss"); EXPECT_EQ(mechanism.reactions.first_order_loss[0].scaling_factor, 12.3); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants[0].species_name, "C"); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants[0].coefficient, 1); + EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants.name, "C"); + EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants.coefficient, 1); EXPECT_EQ(mechanism.reactions.first_order_loss[0].unknown_properties.size(), 1); EXPECT_EQ( mechanism.reactions.first_order_loss[0].unknown_properties["__comment"], "Strawberries are the superior fruit"); EXPECT_EQ(mechanism.reactions.first_order_loss[1].gas_phase, "gas"); EXPECT_EQ(mechanism.reactions.first_order_loss[1].scaling_factor, 1); - EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants[0].species_name, "C"); - EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants[0].coefficient, 1); + EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants.name, "C"); + EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants.coefficient, 1); } } TEST(ParserBase, FirstOrderLossDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/first_order_loss/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, FirstOrderLossDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/first_order_loss/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 2); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, FirstOrderLossDetectsUnknownPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/first_order_loss/missing_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, FirstOrderLossDetectsMoreThanOneSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/first_order_loss/too_many_reactants") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::TooManyReactionComponents); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::TooManyReactionComponents); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, CanParseValidFirstOrderLossReactionWithProducts) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/first_order_loss/products") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/first_order_loss/products") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.first_order_loss.size(), 2); EXPECT_EQ(mechanism.reactions.first_order_loss[0].gas_phase, "gas"); EXPECT_EQ(mechanism.reactions.first_order_loss[0].name, "my first order loss"); EXPECT_EQ(mechanism.reactions.first_order_loss[0].scaling_factor, 12.3); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants[0].species_name, "C"); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants[0].coefficient, 1); + EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants.name, "C"); + EXPECT_EQ(mechanism.reactions.first_order_loss[0].reactants.coefficient, 1); EXPECT_EQ(mechanism.reactions.first_order_loss[0].products.size(), 2); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].products[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.first_order_loss[0].products[0].name, "A"); EXPECT_EQ(mechanism.reactions.first_order_loss[0].products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.first_order_loss[0].products[1].species_name, "B"); + EXPECT_EQ(mechanism.reactions.first_order_loss[0].products[1].name, "B"); EXPECT_EQ(mechanism.reactions.first_order_loss[0].products[1].coefficient, 2); EXPECT_EQ(mechanism.reactions.first_order_loss[0].unknown_properties.size(), 1); EXPECT_EQ( @@ -136,8 +131,7 @@ TEST(ParserBase, CanParseValidFirstOrderLossReactionWithProducts) EXPECT_EQ(mechanism.reactions.first_order_loss[1].gas_phase, "gas"); EXPECT_EQ(mechanism.reactions.first_order_loss[1].scaling_factor, 1); - EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants[0].species_name, "C"); - EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants[0].coefficient, 1); + EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants.name, "C"); + EXPECT_EQ(mechanism.reactions.first_order_loss[1].reactants.coefficient, 1); } -} \ No newline at end of file +} diff --git a/test/unit/v1/reactions/test_parse_lambda_rate_constant.cpp b/test/unit/v1/reactions/test_parse_lambda_rate_constant.cpp index 57ebfba0..b39a32a8 100644 --- a/test/unit/v1/reactions/test_parse_lambda_rate_constant.cpp +++ b/test/unit/v1/reactions/test_parse_lambda_rate_constant.cpp @@ -2,7 +2,7 @@ // University of Illinois at Urbana-Champaign // SPDX-License-Identifier: Apache-2.0 -#include +#include #include @@ -10,13 +10,12 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidLambdaRateConstantReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/lambda_rate_constant/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/lambda_rate_constant/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.lambda_rate_constant.size(), 2); @@ -26,10 +25,10 @@ TEST(ParserBase, CanParseValidLambdaRateConstantReaction) mechanism.reactions.lambda_rate_constant[0].lambda_function, "[](double T, double P) { return 1.2e-5 * exp(-500.0 / T); }"); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.lambda_rate_constant[0].reactants[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.lambda_rate_constant[0].reactants[0].name, "B"); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[0].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.lambda_rate_constant[0].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.lambda_rate_constant[0].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[0].products[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[0].unknown_properties["__comment"], "hi"); @@ -38,66 +37,63 @@ TEST(ParserBase, CanParseValidLambdaRateConstantReaction) EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].name, ""); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].lambda_function, "[](double T) { return 3.0e-4 * T; }"); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].reactants[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].reactants[0].name, "B"); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].reactants[0].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].reactants[1].species_name, "A"); + EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].reactants[1].name, "A"); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].reactants[1].coefficient, 0.5); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.lambda_rate_constant[1].products[0].coefficient, 0.2); } } TEST(ParserBase, LambdaRateConstantDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/lambda_rate_constant/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, LambdaRateConstantDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/lambda_rate_constant/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, LambdaRateConstantDetectsUnknownPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/lambda_rate_constant/missing_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } diff --git a/test/unit/v1/reactions/test_parse_photolysis.cpp b/test/unit/v1/reactions/test_parse_photolysis.cpp index ed7a4fb0..c36e91cc 100644 --- a/test/unit/v1/reactions/test_parse_photolysis.cpp +++ b/test/unit/v1/reactions/test_parse_photolysis.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,107 +10,100 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidPhotolysisReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/photolysis/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/photolysis/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.photolysis.size(), 2); EXPECT_EQ(mechanism.reactions.photolysis[0].gas_phase, "gas"); EXPECT_EQ(mechanism.reactions.photolysis[0].name, "my photolysis"); EXPECT_EQ(mechanism.reactions.photolysis[0].scaling_factor, 12.3); - EXPECT_EQ(mechanism.reactions.photolysis[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.photolysis[0].reactants[0].species_name, "B"); - EXPECT_EQ(mechanism.reactions.photolysis[0].reactants[0].coefficient, 1); + EXPECT_EQ(mechanism.reactions.photolysis[0].reactants.name, "B"); + EXPECT_EQ(mechanism.reactions.photolysis[0].reactants.coefficient, 1); EXPECT_EQ(mechanism.reactions.photolysis[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.photolysis[0].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.photolysis[0].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.photolysis[0].products[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.photolysis[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.photolysis[0].unknown_properties["__comment"], "hi"); EXPECT_EQ(mechanism.reactions.photolysis[1].gas_phase, "gas"); EXPECT_EQ(mechanism.reactions.photolysis[1].scaling_factor, 1); - EXPECT_EQ(mechanism.reactions.photolysis[1].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.photolysis[1].reactants[0].species_name, "B"); - EXPECT_EQ(mechanism.reactions.photolysis[1].reactants[0].coefficient, 1.2); + EXPECT_EQ(mechanism.reactions.photolysis[1].reactants.name, "B"); + EXPECT_EQ(mechanism.reactions.photolysis[1].reactants.coefficient, 1.2); EXPECT_EQ(mechanism.reactions.photolysis[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.photolysis[1].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.photolysis[1].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.photolysis[1].products[0].coefficient, 0.2); } } TEST(ParserBase, PhotolysisDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/photolysis/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, PhotolysisDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/photolysis/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, PhotolysisDetectsUnknownPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/photolysis/missing_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, PhotolysisDoesNotAcceptMoreThanOneReactant) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/photolysis/more_than_one_reactant") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::TooManyReactionComponents); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::TooManyReactionComponents); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } -} \ No newline at end of file +} diff --git a/test/unit/v1/reactions/test_parse_surface.cpp b/test/unit/v1/reactions/test_parse_surface.cpp index a3380dd5..57262b67 100644 --- a/test/unit/v1/reactions/test_parse_surface.cpp +++ b/test/unit/v1/reactions/test_parse_surface.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,94 +10,90 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidSurfaceReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/surface/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/surface/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.surface.size(), 2); EXPECT_EQ(mechanism.reactions.surface[0].gas_phase, "gas"); EXPECT_EQ(mechanism.reactions.surface[0].name, "my surface"); EXPECT_EQ(mechanism.reactions.surface[0].reaction_probability, 2.0e-2); - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_species.species_name, "A"); + EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_species.name, "A"); EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_species.coefficient, 1); EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products.size(), 2); - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products[0].name, "B"); EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products[0].coefficient, 1); - EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products[1].species_name, "C"); + EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products[1].name, "C"); EXPECT_EQ(mechanism.reactions.surface[0].gas_phase_products[1].coefficient, 1); EXPECT_EQ(mechanism.reactions.surface[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.surface[0].unknown_properties["__comment"], "key lime pie is superior to all other pies"); EXPECT_EQ(mechanism.reactions.surface[1].gas_phase, "gas"); EXPECT_EQ(mechanism.reactions.surface[1].reaction_probability, 1.0); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_species.species_name, "A"); + EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_species.name, "A"); EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_species.coefficient, 1); EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products.size(), 2); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[0].name, "B"); EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[0].unknown_properties["__optional thing"], "hello"); - EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[1].species_name, "C"); + EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[1].name, "C"); EXPECT_EQ(mechanism.reactions.surface[1].gas_phase_products[1].coefficient, 1); } } TEST(ParserBase, SurfaceDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/surface/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, SurfaceDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/surface/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 2); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, SurfaceDetectsUnknownGasPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/surface/missing_gas_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } -} \ No newline at end of file +} diff --git a/test/unit/v1/reactions/test_parse_taylor_series.cpp b/test/unit/v1/reactions/test_parse_taylor_series.cpp index b1a5f3c9..0f9c28b7 100644 --- a/test/unit/v1/reactions/test_parse_taylor_series.cpp +++ b/test/unit/v1/reactions/test_parse_taylor_series.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,13 +10,12 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidTaylorSeriesReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/taylor_series/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/taylor_series/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.taylor_series.size(), 3); @@ -28,12 +31,12 @@ TEST(ParserBase, CanParseValidTaylorSeriesReaction) EXPECT_EQ(mechanism.reactions.taylor_series[0].taylor_coefficients[1], 2.0); EXPECT_EQ(mechanism.reactions.taylor_series[0].taylor_coefficients[2], 3.0); EXPECT_EQ(mechanism.reactions.taylor_series[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[0].reactants[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.taylor_series[0].reactants[0].name, "A"); EXPECT_EQ(mechanism.reactions.taylor_series[0].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.taylor_series[0].products.size(), 2); - EXPECT_EQ(mechanism.reactions.taylor_series[0].products[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.taylor_series[0].products[0].name, "B"); EXPECT_EQ(mechanism.reactions.taylor_series[0].products[0].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.taylor_series[0].products[1].species_name, "C"); + EXPECT_EQ(mechanism.reactions.taylor_series[0].products[1].name, "C"); EXPECT_EQ(mechanism.reactions.taylor_series[0].products[1].coefficient, 0.3); EXPECT_EQ(mechanism.reactions.taylor_series[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.taylor_series[0].unknown_properties["__solver_param"], "0.1"); @@ -48,12 +51,12 @@ TEST(ParserBase, CanParseValidTaylorSeriesReaction) EXPECT_EQ(mechanism.reactions.taylor_series[1].taylor_coefficients.size(), 1); EXPECT_EQ(mechanism.reactions.taylor_series[1].taylor_coefficients[0], 10.5); EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants[0].name, "A"); EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants[0].coefficient, 2); - EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants[1].species_name, "B"); + EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants[1].name, "B"); EXPECT_EQ(mechanism.reactions.taylor_series[1].reactants[1].coefficient, 0.1); EXPECT_EQ(mechanism.reactions.taylor_series[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[1].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.taylor_series[1].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.taylor_series[1].products[0].coefficient, 0.5); EXPECT_EQ(mechanism.reactions.taylor_series[1].products[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.taylor_series[1].products[0].unknown_properties["__optional thing"], "hello"); @@ -68,83 +71,79 @@ TEST(ParserBase, CanParseValidTaylorSeriesReaction) EXPECT_EQ(mechanism.reactions.taylor_series[2].taylor_coefficients.size(), 1); EXPECT_EQ(mechanism.reactions.taylor_series[2].taylor_coefficients[0], 1.0); EXPECT_EQ(mechanism.reactions.taylor_series[2].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[2].reactants[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.taylor_series[2].reactants[0].name, "A"); EXPECT_EQ(mechanism.reactions.taylor_series[2].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.taylor_series[2].products.size(), 1); - EXPECT_EQ(mechanism.reactions.taylor_series[2].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.taylor_series[2].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.taylor_series[2].products[0].coefficient, 1); } } TEST(ParserBase, TaylorSeriesDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/taylor_series/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, TaylorSeriesDetectsMutuallyExclusiveOptions) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/taylor_series/mutually_exclusive") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::MutuallyExclusiveOption); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::MutuallyExclusiveOption); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, TaylorSeriesDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/taylor_series/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 2); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, TaylorSeriesDetectsUnknownPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/taylor_series/missing_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } -} \ No newline at end of file +} diff --git a/test/unit/v1/reactions/test_parse_ternary_chemical_activation.cpp b/test/unit/v1/reactions/test_parse_ternary_chemical_activation.cpp index c01ab4ae..f079b9ed 100644 --- a/test/unit/v1/reactions/test_parse_ternary_chemical_activation.cpp +++ b/test/unit/v1/reactions/test_parse_ternary_chemical_activation.cpp @@ -1,6 +1,10 @@ -#include -#include -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include "detail/constants.hpp" +#include "detail/conversions.hpp" +#include #include @@ -8,22 +12,21 @@ using namespace mechanism_configuration; TEST(TernaryChemicalActivationConfig, ParseValidConfig) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = "./v1_unit_configs/reactions/ternary_chemical_activation/valid/config" + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); if (!parsed) { - for (auto& error : parsed.errors) + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; auto& process_vector = mechanism.reactions.ternary_chemical_activation; EXPECT_EQ(process_vector.size(), 2); @@ -31,14 +34,14 @@ TEST(TernaryChemicalActivationConfig, ParseValidConfig) // first reaction { EXPECT_EQ(process_vector[0].reactants.size(), 2); - EXPECT_EQ(process_vector[0].reactants[0].species_name, "foo"); + EXPECT_EQ(process_vector[0].reactants[0].name, "foo"); EXPECT_EQ(process_vector[0].reactants[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].reactants[1].species_name, "quz"); + EXPECT_EQ(process_vector[0].reactants[1].name, "quz"); EXPECT_EQ(process_vector[0].reactants[1].coefficient, 2.0); EXPECT_EQ(process_vector[0].products.size(), 2); - EXPECT_EQ(process_vector[0].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[0].products[0].name, "bar"); EXPECT_EQ(process_vector[0].products[0].coefficient, 1.0); - EXPECT_EQ(process_vector[0].products[1].species_name, "baz"); + EXPECT_EQ(process_vector[0].products[1].name, "baz"); EXPECT_EQ(process_vector[0].products[1].coefficient, 3.2); EXPECT_EQ(process_vector[0].k0_A, 1.0); EXPECT_EQ(process_vector[0].k0_B, 0.0); @@ -55,12 +58,12 @@ TEST(TernaryChemicalActivationConfig, ParseValidConfig) EXPECT_EQ(process_vector[1].unknown_properties.size(), 1); EXPECT_EQ(process_vector[1].unknown_properties["__optional thing"], "hello"); EXPECT_EQ(process_vector[1].reactants.size(), 2); - EXPECT_EQ(process_vector[1].reactants[0].species_name, "bar"); - EXPECT_EQ(process_vector[1].reactants[1].species_name, "baz"); + EXPECT_EQ(process_vector[1].reactants[0].name, "bar"); + EXPECT_EQ(process_vector[1].reactants[1].name, "baz"); EXPECT_EQ(process_vector[1].products.size(), 2); - EXPECT_EQ(process_vector[1].products[0].species_name, "bar"); + EXPECT_EQ(process_vector[1].products[0].name, "bar"); EXPECT_EQ(process_vector[1].products[0].coefficient, 0.5); - EXPECT_EQ(process_vector[1].products[1].species_name, "foo"); + EXPECT_EQ(process_vector[1].products[1].name, "foo"); EXPECT_EQ(process_vector[1].products[1].coefficient, 0.0); EXPECT_EQ(process_vector[1].k0_A, 32.1); EXPECT_EQ(process_vector[1].k0_B, -2.3); @@ -77,62 +80,59 @@ TEST(TernaryChemicalActivationConfig, ParseValidConfig) TEST(TernaryChemicalActivationConfig, DetectsNonStandardKey) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = "./v1_unit_configs/reactions/ternary_chemical_activation/contains_nonstandard_key/config" + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 12); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[2].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[3].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[4].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[5].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[6].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[7].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[8].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[9].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[10].first, ConfigParseStatus::InvalidKey); - EXPECT_EQ(parsed.errors[11].first, ConfigParseStatus::InvalidKey); + EXPECT_EQ(parsed.error().size(), 12); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[2].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[3].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[4].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[5].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[6].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[7].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[8].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[9].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[10].first, ErrorCode::InvalidKey); + EXPECT_EQ(parsed.error()[11].first, ErrorCode::InvalidKey); - for (auto& error : parsed.errors) + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(TernaryChemicalActivationConfig, DetectsMissingProducts) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = "./v1_unit_configs/reactions/ternary_chemical_activation/missing_products/config" + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - for (auto& error : parsed.errors) + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(TernaryChemicalActivationConfig, DetectsMissingReactants) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = "./v1_unit_configs/reactions/ternary_chemical_activation/missing_reactants/config" + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - for (auto& error : parsed.errors) + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } \ No newline at end of file diff --git a/test/unit/v1/reactions/test_parse_troe.cpp b/test/unit/v1/reactions/test_parse_troe.cpp index c2f3cc6f..8054e9d4 100644 --- a/test/unit/v1/reactions/test_parse_troe.cpp +++ b/test/unit/v1/reactions/test_parse_troe.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,13 +10,12 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidTroeReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/troe/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/troe/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.troe.size(), 2); @@ -26,10 +29,10 @@ TEST(ParserBase, CanParseValidTroeReaction) EXPECT_EQ(mechanism.reactions.troe[0].Fc, 0.6); EXPECT_EQ(mechanism.reactions.troe[0].N, 1.0); EXPECT_EQ(mechanism.reactions.troe[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.troe[0].reactants[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.troe[0].reactants[0].name, "A"); EXPECT_EQ(mechanism.reactions.troe[0].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.troe[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.troe[0].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.troe[0].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.troe[0].products[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.troe[0].unknown_properties.size(), 1); if (extension == ".json") @@ -52,14 +55,14 @@ TEST(ParserBase, CanParseValidTroeReaction) EXPECT_EQ(mechanism.reactions.troe[1].Fc, 1.3); EXPECT_EQ(mechanism.reactions.troe[1].N, 32.1); EXPECT_EQ(mechanism.reactions.troe[1].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.troe[1].reactants[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.troe[1].reactants[0].name, "C"); EXPECT_EQ(mechanism.reactions.troe[1].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.troe[1].products.size(), 2); - EXPECT_EQ(mechanism.reactions.troe[1].products[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.troe[1].products[0].name, "A"); EXPECT_EQ(mechanism.reactions.troe[1].products[0].coefficient, 0.2); EXPECT_EQ(mechanism.reactions.troe[1].products[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.troe[1].products[0].unknown_properties["__optional thing"], "hello"); - EXPECT_EQ(mechanism.reactions.troe[1].products[1].species_name, "B"); + EXPECT_EQ(mechanism.reactions.troe[1].products[1].name, "B"); EXPECT_EQ(mechanism.reactions.troe[1].products[1].coefficient, 1.2); EXPECT_EQ(mechanism.reactions.troe[1].products[1].unknown_properties.size(), 0); } @@ -67,55 +70,52 @@ TEST(ParserBase, CanParseValidTroeReaction) TEST(ParserBase, TroeDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/troe/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, TroeDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/troe/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 2); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, TroeDetectsUnknownPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/troe/missing_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } -} \ No newline at end of file +} diff --git a/test/unit/v1/reactions/test_parse_tunneling.cpp b/test/unit/v1/reactions/test_parse_tunneling.cpp index 3c84fab2..ec142d1f 100644 --- a/test/unit/v1/reactions/test_parse_tunneling.cpp +++ b/test/unit/v1/reactions/test_parse_tunneling.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,13 +10,12 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidTunnelingReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/tunneling/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/tunneling/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.tunneling.size(), 2); @@ -21,10 +24,10 @@ TEST(ParserBase, CanParseValidTunnelingReaction) EXPECT_EQ(mechanism.reactions.tunneling[0].B, 1200.0); EXPECT_EQ(mechanism.reactions.tunneling[0].C, 1.0e8); EXPECT_EQ(mechanism.reactions.tunneling[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.tunneling[0].reactants[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.tunneling[0].reactants[0].name, "B"); EXPECT_EQ(mechanism.reactions.tunneling[0].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.tunneling[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.tunneling[0].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.tunneling[0].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.tunneling[0].products[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.tunneling[1].name, "my tunneling"); @@ -33,14 +36,14 @@ TEST(ParserBase, CanParseValidTunnelingReaction) EXPECT_EQ(mechanism.reactions.tunneling[1].B, 0); EXPECT_EQ(mechanism.reactions.tunneling[1].C, 0); EXPECT_EQ(mechanism.reactions.tunneling[1].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.tunneling[1].reactants[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.tunneling[1].reactants[0].name, "B"); EXPECT_EQ(mechanism.reactions.tunneling[1].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.tunneling[1].products.size(), 2); - EXPECT_EQ(mechanism.reactions.tunneling[1].products[0].species_name, "A"); + EXPECT_EQ(mechanism.reactions.tunneling[1].products[0].name, "A"); EXPECT_EQ(mechanism.reactions.tunneling[1].products[0].coefficient, 0.2); EXPECT_EQ(mechanism.reactions.tunneling[1].products[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.tunneling[1].products[0].unknown_properties["__optional thing"], "hello"); - EXPECT_EQ(mechanism.reactions.tunneling[1].products[1].species_name, "B"); + EXPECT_EQ(mechanism.reactions.tunneling[1].products[1].name, "B"); EXPECT_EQ(mechanism.reactions.tunneling[1].products[1].coefficient, 1.2); EXPECT_EQ(mechanism.reactions.tunneling[1].products[1].unknown_properties.size(), 0); } @@ -48,55 +51,52 @@ TEST(ParserBase, CanParseValidTunnelingReaction) TEST(ParserBase, TunnelingDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/tunneling/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, TunnelingDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/tunneling/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 2); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, TunnelingDetectsUnknownPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/tunneling/missing_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } -} \ No newline at end of file +} diff --git a/test/unit/v1/reactions/test_parse_user_defined.cpp b/test/unit/v1/reactions/test_parse_user_defined.cpp index d561ec34..98bc7e2b 100644 --- a/test/unit/v1/reactions/test_parse_user_defined.cpp +++ b/test/unit/v1/reactions/test_parse_user_defined.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,13 +10,12 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidUserDefinedReaction) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/reactions/user_defined/valid") + extension); + auto parsed = Parse(std::string("v1_unit_configs/reactions/user_defined/valid") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.reactions.user_defined.size(), 2); @@ -20,10 +23,10 @@ TEST(ParserBase, CanParseValidUserDefinedReaction) EXPECT_EQ(mechanism.reactions.user_defined[0].name, "my user defined"); EXPECT_EQ(mechanism.reactions.user_defined[0].scaling_factor, 12.3); EXPECT_EQ(mechanism.reactions.user_defined[0].reactants.size(), 1); - EXPECT_EQ(mechanism.reactions.user_defined[0].reactants[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.user_defined[0].reactants[0].name, "B"); EXPECT_EQ(mechanism.reactions.user_defined[0].reactants[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.user_defined[0].products.size(), 1); - EXPECT_EQ(mechanism.reactions.user_defined[0].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.user_defined[0].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.user_defined[0].products[0].coefficient, 1); EXPECT_EQ(mechanism.reactions.user_defined[0].unknown_properties.size(), 1); EXPECT_EQ(mechanism.reactions.user_defined[0].unknown_properties["__comment"], "hi"); @@ -31,66 +34,63 @@ TEST(ParserBase, CanParseValidUserDefinedReaction) EXPECT_EQ(mechanism.reactions.user_defined[1].gas_phase, "gas"); EXPECT_EQ(mechanism.reactions.user_defined[1].scaling_factor, 1); EXPECT_EQ(mechanism.reactions.user_defined[1].reactants.size(), 2); - EXPECT_EQ(mechanism.reactions.user_defined[1].reactants[0].species_name, "B"); + EXPECT_EQ(mechanism.reactions.user_defined[1].reactants[0].name, "B"); EXPECT_EQ(mechanism.reactions.user_defined[1].reactants[0].coefficient, 1.2); - EXPECT_EQ(mechanism.reactions.user_defined[1].reactants[1].species_name, "A"); + EXPECT_EQ(mechanism.reactions.user_defined[1].reactants[1].name, "A"); EXPECT_EQ(mechanism.reactions.user_defined[1].reactants[1].coefficient, 0.5); EXPECT_EQ(mechanism.reactions.user_defined[1].products.size(), 1); - EXPECT_EQ(mechanism.reactions.user_defined[1].products[0].species_name, "C"); + EXPECT_EQ(mechanism.reactions.user_defined[1].products[0].name, "C"); EXPECT_EQ(mechanism.reactions.user_defined[1].products[0].coefficient, 0.2); } } TEST(ParserBase, UserDefinedDetectsUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/user_defined/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::ReactionRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::ReactionRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, UserDefinedDetectsBadReactionComponent) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/user_defined/bad_reaction_component") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, UserDefinedDetectsUnknownPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/reactions/user_defined/missing_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::UnknownPhase); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::UnknownPhase); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } diff --git a/test/unit/v1/test_parse_phases.cpp b/test/unit/v1/test_parse_phases.cpp index e10f08ae..57364e5c 100644 --- a/test/unit/v1/test_parse_phases.cpp +++ b/test/unit/v1/test_parse_phases.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,13 +10,12 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidPhases) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/phases/valid_phases") + extension); + auto parsed = Parse(std::string("v1_unit_configs/phases/valid_phases") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.species.size(), 3); EXPECT_EQ(mechanism.phases.size(), 2); @@ -34,103 +37,97 @@ TEST(ParserBase, CanParseValidPhases) TEST(ParserBase, DetectsDuplicatePhases) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/phases/duplicate_phases") + extension; - auto parsed = parser.Parse(file); - EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 2); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::DuplicatePhasesDetected); - for (auto& error : parsed.errors) + auto parsed = Parse(file); + EXPECT_FALSE(parsed) << "Parsing should have failed due to duplicate phases, but it succeeded."; + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::DuplicatePhasesDetected); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, DetectsMissingRequiredKeys) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/phases/missing_required_key") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, DetectsInvalidKeys) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/phases/invalid_key") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, DetectsPhaseRequestingUnknownSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/phases/unknown_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::PhaseRequiresUnknownSpecies); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::PhaseRequiresUnknownSpecies); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, DetectsDuplicateSpeciesInPhase) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/phases/duplicate_species_in_phase") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::DuplicateSpeciesInPhaseDetected); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::DuplicateSpeciesInPhaseDetected); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, CanParsePhaseSpeciesProperties) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/phases/phase_species_properties") + extension); + auto parsed = Parse(std::string("v1_unit_configs/phases/phase_species_properties") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.species.size(), 3); EXPECT_EQ(mechanism.phases.size(), 1); @@ -162,18 +159,17 @@ TEST(ParserBase, CanParsePhaseSpeciesProperties) TEST(ParserBase, DetectsInvalidSpeciesObject) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/phases/invalid_species_object") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_GE(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - for (auto& error : parsed.errors) + EXPECT_GE(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } -} \ No newline at end of file +} diff --git a/test/unit/v1/test_parse_species.cpp b/test/unit/v1/test_parse_species.cpp index a0110d81..e3827a4b 100644 --- a/test/unit/v1/test_parse_species.cpp +++ b/test/unit/v1/test_parse_species.cpp @@ -1,4 +1,8 @@ -#include +// Copyright (C) 2023–2026 University Corporation for Atmospheric Research +// University of Illinois at Urbana-Champaign +// SPDX-License-Identifier: Apache-2.0 + +#include #include @@ -6,13 +10,12 @@ using namespace mechanism_configuration; TEST(ParserBase, CanParseValidSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { - auto parsed = parser.Parse(std::string("v1_unit_configs/species/valid_species") + extension); + auto parsed = Parse(std::string("v1_unit_configs/species/valid_species") + extension); EXPECT_TRUE(parsed); - v1::types::Mechanism mechanism = *parsed; + Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.species.size(), 3); EXPECT_EQ(mechanism.species[0].name, "A"); @@ -42,58 +45,55 @@ TEST(ParserBase, CanParseValidSpecies) TEST(ParserBase, DetectsDuplicateSpecies) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/species/duplicate_species") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 4); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::DuplicateSpeciesDetected); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::DuplicateSpeciesDetected); - EXPECT_EQ(parsed.errors[2].first, ConfigParseStatus::DuplicateSpeciesDetected); - EXPECT_EQ(parsed.errors[3].first, ConfigParseStatus::DuplicateSpeciesDetected); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 4); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::DuplicateSpeciesDetected); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::DuplicateSpeciesDetected); + EXPECT_EQ(parsed.error()[2].first, ErrorCode::DuplicateSpeciesDetected); + EXPECT_EQ(parsed.error()[3].first, ErrorCode::DuplicateSpeciesDetected); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, DetectsMissingRequiredKeys) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/species/missing_required_key") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 2); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::RequiredKeyNotFound); - EXPECT_EQ(parsed.errors[1].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 2); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::RequiredKeyNotFound); + EXPECT_EQ(parsed.error()[1].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } TEST(ParserBase, DetectsInvalidKeys) { - v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; for (auto& extension : extensions) { std::string file = std::string("v1_unit_configs/species/invalid_key") + extension; - auto parsed = parser.Parse(file); + auto parsed = Parse(file); EXPECT_FALSE(parsed); - EXPECT_EQ(parsed.errors.size(), 1); - EXPECT_EQ(parsed.errors[0].first, ConfigParseStatus::InvalidKey); - for (auto& error : parsed.errors) + EXPECT_EQ(parsed.error().size(), 1); + EXPECT_EQ(parsed.error()[0].first, ErrorCode::InvalidKey); + for (auto& error : parsed.error()) { - std::cout << error.second << " " << configParseStatusToString(error.first) << std::endl; + std::cout << error.second << " " << ErrorCodeToString(error.first) << std::endl; } } } diff --git a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.json b/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.json deleted file mode 100644 index 7dc11217..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "version": "1.0.0", - "name": "Bad reaction component", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - "A", - "B", - "C", - "H2O" - ] - } - ], - "reactions": [ - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "k_reverse": 0.32, - "reactants": [ - { - "Species name": "A", - "coefficient": 2 - } - ], - "products": [ - { - "Species name": "B", - "coefficient": 1 - }, - { - "Species name": "C", - "coefficient": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.yaml b/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.yaml deleted file mode 100644 index bb52eae7..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/bad_reaction_component.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: Bad reaction component -phases: -- name: aqueous - species: - - A - - B - - C - - H2O -reactions: -- condensed phase: aqueous - condensed-phase water: H2O - k_reverse: 0.32 - products: - - Species name: B - coefficient: 1 - - Species name: C - coefficient: 1 - reactants: - - Species name: A - coefficient: 2 - type: AQUEOUS_EQUILIBRIUM -species: -- name: A -- name: B -- name: C -- name: H2O -version: 1.0.0 diff --git a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/missing_phase.json b/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/missing_phase.json deleted file mode 100644 index 98306c2c..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/missing_phase.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "version": "1.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [], - "reactions": [ - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "k_reverse": 0.32, - "reactants": [ - { - "species name": "A", - "coefficient": 2 - } - ], - "products": [ - { - "species name": "B", - "coefficient": 1 - }, - { - "species name": "C", - "coefficient": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/missing_phase.yaml b/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/missing_phase.yaml deleted file mode 100644 index 8af9b72f..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/missing_phase.yaml +++ /dev/null @@ -1,21 +0,0 @@ -name: Missing phase -phases: [] -reactions: -- condensed phase: aqueous - condensed-phase water: H2O - k_reverse: 0.32 - products: - - coefficient: 1 - species name: B - - coefficient: 1 - species name: C - reactants: - - coefficient: 2 - species name: A - type: AQUEOUS_EQUILIBRIUM -species: -- name: A -- name: B -- name: C -- name: H2O -version: 1.0.0 diff --git a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/unknown_species.json b/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/unknown_species.json deleted file mode 100644 index 9e4f8a94..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/unknown_species.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "version": "1.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - "A", - "B" - ] - } - ], - "reactions": [ - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "k_reverse": 0.32, - "reactants": [ - { - "species name": "A", - "coefficient": 2 - } - ], - "products": [ - { - "species name": "B", - "coefficient": 1 - }, - { - "species name": "C", - "coefficient": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/unknown_species.yaml b/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/unknown_species.yaml deleted file mode 100644 index bf2108c1..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/unknown_species.yaml +++ /dev/null @@ -1,23 +0,0 @@ -name: Unknown species -phases: -- name: aqueous - species: - - A - - B -reactions: -- condensed phase: aqueous - condensed-phase water: H2O - k_reverse: 0.32 - products: - - coefficient: 1 - species name: B - - coefficient: 1 - species name: C - reactants: - - coefficient: 2 - species name: A - type: AQUEOUS_EQUILIBRIUM -species: -- name: A -- name: B -version: 1.0.0 diff --git a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/valid.json b/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/valid.json deleted file mode 100644 index 829b06f3..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/valid.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "version": "1.0.0", - "name": "Valid aqueous equilibrium", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "aqueous", - "species": [ - "A", - "B", - "C", - "H2O" - ] - } - ], - "reactions": [ - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "A": 1.14e-2, - "C": 2300.0, - "k_reverse": 0.32, - "reactants": [ - { - "species name": "A", - "coefficient": 2 - } - ], - "products": [ - { - "species name": "B", - "coefficient": 1 - }, - { - "species name": "C", - "coefficient": 1 - } - ], - "name": "my aqueous eq", - "__comment": "GIF is pronounced with a hard g" - }, - { - "type": "AQUEOUS_EQUILIBRIUM", - "condensed phase": "aqueous", - "condensed-phase water": "H2O", - "k_reverse": 0.32, - "reactants": [ - { - "species name": "A", - "coefficient": 2 - } - ], - "products": [ - { - "species name": "B", - "coefficient": 1 - }, - { - "species name": "C", - "coefficient": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/valid.yaml b/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/valid.yaml deleted file mode 100644 index e2dd002b..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/aqueous_equilibrium/valid.yaml +++ /dev/null @@ -1,43 +0,0 @@ -name: Valid aqueous equilibrium -phases: -- name: aqueous - species: - - A - - B - - C - - H2O -reactions: -- A: 0.0114 - C: 2300.0 - __comment: GIF is pronounced with a hard g - condensed phase: aqueous - condensed-phase water: H2O - k_reverse: 0.32 - name: my aqueous eq - products: - - coefficient: 1 - species name: B - - coefficient: 1 - species name: C - reactants: - - coefficient: 2 - species name: A - type: AQUEOUS_EQUILIBRIUM -- condensed phase: aqueous - condensed-phase water: H2O - k_reverse: 0.32 - products: - - coefficient: 1 - species name: B - - coefficient: 1 - species name: C - reactants: - - coefficient: 2 - species name: A - type: AQUEOUS_EQUILIBRIUM -species: -- name: A -- name: B -- name: C -- name: H2O -version: 1.0.0 diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/missing_phase.json b/test/unit/v1/v1_unit_configs/reactions/henrys_law/missing_phase.json deleted file mode 100644 index 6e9662f2..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/missing_phase.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "version": "1.0.0", - "name": "Missing phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - } - ], - "phases": [ ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": ["A"] - }, - "particle": { - "phase": "aqueous", - "solutes": ["B"], - "solvent": "H2O" - }, - "name": "my henry's law" - } - ] -} \ No newline at end of file diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/missing_phase.yaml b/test/unit/v1/v1_unit_configs/reactions/henrys_law/missing_phase.yaml deleted file mode 100644 index 16b37070..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/missing_phase.yaml +++ /dev/null @@ -1,19 +0,0 @@ -version: 1.0.0 -name: Missing phase -species: - - name: A - - name: B - - name: C -phases: [] -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - A - particle: - phase: aqueous - solutes: - - B - solvent: H2O - name: my henry's law diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.json b/test/unit/v1/v1_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.json deleted file mode 100644 index 8e2ea836..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "version": "1.0.0", - "name": "Solvent species in not registered in the corresponding phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "C" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - "A", - "B" - ] - }, - { - "name": "aqueous", - "species": [ - "H2O", - "C" - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": ["A"] - }, - "particle": { - "phase": "aqueous", - "solutes": ["C"], - "solvent": "B" - }, - "name": "my henry's law", - "__comment": "hi" - } - ] -} \ No newline at end of file diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.yaml b/test/unit/v1/v1_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.yaml deleted file mode 100644 index 2c07bbcf..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/solvent_species_not_registered_in_phase.yaml +++ /dev/null @@ -1,29 +0,0 @@ -version: "1.0.0" -name: "Solvent species in not registered in the corresponding phase" -species: - - name: "A" - - name: "B" - - name: "C" - - name: "H2O" -phases: - - name: "gas" - species: - - "A" - - "B" - - name: "aqueous" - species: - - "H2O" - - "C" -reactions: - - type: "HL_PHASE_TRANSFER" - gas: - name: "gas" - species: - - "A" - particle: - phase: "aqueous" - solutes: - - "C" - solvent: "B" - name: "my henry's law" - __comment: "hi" diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.json b/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.json deleted file mode 100644 index 1d803b0f..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "version": "1.0.0", - "name": "Gas species in reactions are not found in gas phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - "A" - ] - }, - { - "name": "aqueous", - "species": [ - "B", - "H2O" - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": ["H2O"] - }, - "particle": { - "phase": "aqueous", - "solutes": ["B"], - "solvent": "H2O" - } - } - ] -} \ No newline at end of file diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.yaml b/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.yaml deleted file mode 100644 index aecee3a8..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_found_in_gas_phase.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: "1.0.0" -name: "Gas species in reactions are not found in gas phase" -species: - - name: "A" - - name: "B" - - name: "H2O" -phases: - - name: "gas" - species: - - "A" - - name: "aqueous" - species: - - "B" - - "H2O" -reactions: - - type: "HL_PHASE_TRANSFER" - gas: - name: "gas" - species: - - "H2O" - particle: - phase: "aqueous" - solutes: - - "B" - solvent: "H2O" diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.json b/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.json deleted file mode 100644 index bef33e71..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "version": "1.0.0", - "name": "Condensed phase arrhenius using species not in its requested condensed phase", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - "A", - "B" - ] - }, - { - "name": "aqueous", - "species": [ - "H2O" - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - "A" - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - "B" - ], - "solvent": "H2O" - }, - "name": "my henry's law", - "__comment": "hi" - } - ] -} \ No newline at end of file diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.yaml b/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.yaml deleted file mode 100644 index e6e925ac..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/species_not_in_aqueous_phase.yaml +++ /dev/null @@ -1,27 +0,0 @@ -version: 1.0.0 -name: Condensed phase arrhenius using species not in its requested condensed phase -species: - - name: A - - name: B - - name: H2O -phases: - - name: gas - species: - - A - - B - - name: aqueous - species: - - H2O -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - A - particle: - phase: aqueous - solutes: - - B - solvent: H2O - name: my henry's law - __comment: hi diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/unknown_species.json b/test/unit/v1/v1_unit_configs/reactions/henrys_law/unknown_species.json deleted file mode 100644 index 0399c625..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/unknown_species.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "version": "1.0.0", - "name": "Unknown species", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - "A" - ] - }, - { - "name": "aqueous", - "species": [ - "B", - "H2O" - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": ["C"] - }, - "particle": { - "phase": "aqueous", - "solutes": ["B"], - "solvent": "H2O" - } - } - ] -} \ No newline at end of file diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/unknown_species.yaml b/test/unit/v1/v1_unit_configs/reactions/henrys_law/unknown_species.yaml deleted file mode 100644 index 308557e5..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/unknown_species.yaml +++ /dev/null @@ -1,25 +0,0 @@ -version: 1.0.0 -name: Unknown species -species: - - name: A - - name: B - - name: H2O -phases: - - name: gas - species: - - A - - name: aqueous - species: - - B - - H2O -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - C - particle: - phase: aqueous - solutes: - - B - solvent: H2O diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/valid.json b/test/unit/v1/v1_unit_configs/reactions/henrys_law/valid.json deleted file mode 100644 index 9e14c186..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/valid.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "version": "1.0.0", - "name": "Valid surface", - "species": [ - { - "name": "A" - }, - { - "name": "B" - }, - { - "name": "H2O" - }, - { - "name": "C" - } - ], - "phases": [ - { - "name": "gas", - "species": [ - "A" - ] - }, - { - "name": "aqueous", - "species": [ - "B", - "H2O", - "C" - ] - } - ], - "reactions": [ - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - "A" - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - "B" - ], - "solvent": "H2O" - }, - "name": "my henry's law", - "__comment": "B condensed phase production (kg/m2/s)" - }, - { - "type": "HL_PHASE_TRANSFER", - "gas": { - "name": "gas", - "species": [ - "A" - ] - }, - "particle": { - "phase": "aqueous", - "solutes": [ - "B", - "C" - ], - "solvent": "H2O" - } - } - ] -} \ No newline at end of file diff --git a/test/unit/v1/v1_unit_configs/reactions/henrys_law/valid.yaml b/test/unit/v1/v1_unit_configs/reactions/henrys_law/valid.yaml deleted file mode 100644 index 5aab6050..00000000 --- a/test/unit/v1/v1_unit_configs/reactions/henrys_law/valid.yaml +++ /dev/null @@ -1,40 +0,0 @@ -version: 1.0.0 -name: Valid surface -species: - - name: A - - name: B - - name: H2O - - name: C -phases: - - name: gas - species: - - A - - name: aqueous - species: - - B - - H2O - - C -reactions: - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - A - particle: - phase: aqueous - solutes: - - B - solvent: H2O - name: my henry's law - __comment: B condensed phase production (kg/m2/s) - - type: HL_PHASE_TRANSFER - gas: - name: gas - species: - - A - particle: - phase: aqueous - solutes: - - B - - C - solvent: H2O