diff --git a/examples/v1/full_configuration.json b/examples/v1/full_configuration.json index f19ea7cc..378b237c 100644 --- a/examples/v1/full_configuration.json +++ b/examples/v1/full_configuration.json @@ -115,13 +115,13 @@ "name": "aitken", "geometric mean diameter [m]": 2.6e-8, "geometric standard deviation": 1.6, - "phase": "aqueous" + "phases": "aqueous" }, { "name": "accumulation", "geometric mean diameter [m]": 1.1e-7, "geometric standard deviation": 1.8, - "phase": "aqueous" + "phases": ["aqueous", "organic"] } ] } diff --git a/examples/v1/full_configuration.yaml b/examples/v1/full_configuration.yaml index da6287a1..df41e6fd 100644 --- a/examples/v1/full_configuration.yaml +++ b/examples/v1/full_configuration.yaml @@ -65,6 +65,7 @@ phases: species: - B - C + models: - name: gas type: GAS_PHASE @@ -75,12 +76,16 @@ models: - name: aitken geometric mean diameter [m]: 2.6e-8 geometric standard deviation: 1.6 - phase: aqueous + phases: + - aqueous - name: accumulation geometric mean diameter [m]: 1.1e-7 geometric standard deviation: 1.8 - phase: aqueous + phases: + - aqueous + - cloud + reactions: - type: HL_PHASE_TRANSFER gas: diff --git a/include/mechanism_configuration/v1/model_types.hpp b/include/mechanism_configuration/v1/model_types.hpp index 9cc33637..d950d244 100644 --- a/include/mechanism_configuration/v1/model_types.hpp +++ b/include/mechanism_configuration/v1/model_types.hpp @@ -31,7 +31,7 @@ namespace mechanism_configuration std::string name; double geometric_mean_diameter; double geometric_standard_deviation; - std::string phase; + std::vector phases; /// @brief Unknown properties, prefixed with two underscores (__) std::unordered_map unknown_properties; }; diff --git a/include/mechanism_configuration/v1/validation.hpp b/include/mechanism_configuration/v1/validation.hpp index fbcc56f1..efcbf160 100644 --- a/include/mechanism_configuration/v1/validation.hpp +++ b/include/mechanism_configuration/v1/validation.hpp @@ -187,7 +187,7 @@ namespace mechanism_configuration static constexpr const char* geometric_standard_deviation = "geometric standard deviation"; // also // name - // phase + // phases } // namespace validation } // namespace v1 diff --git a/src/v1/models/modal_model_parser.cpp b/src/v1/models/modal_model_parser.cpp index ca2654cf..f43278b6 100644 --- a/src/v1/models/modal_model_parser.cpp +++ b/src/v1/models/modal_model_parser.cpp @@ -22,7 +22,7 @@ namespace mechanism_configuration 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 + validation::name, validation::geometric_mean_diameter, validation::geometric_standard_deviation, validation::phases }; std::vector optional_second_level_keys = {}; @@ -63,20 +63,24 @@ namespace mechanism_configuration 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.phases.reserve(mode_object[validation::phases].size()); // Check whether the phase for the mode is valid by comparing it to the initialized phases - std::string mode_phase = mode_object[validation::phase].as(); - auto it_found_phase = - std::find_if(existing_phases.begin(), existing_phases.end(), [&mode_phase](const auto& phase) { return phase.name == mode_phase; }); - if (it_found_phase == existing_phases.end()) + for (const auto& phase_object : mode_object[validation::phases]) { - std::string line = std::to_string(mode_object[validation::phase].Mark().line + 1); - std::string column = std::to_string(mode_object[validation::phase].Mark().column + 1); - errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + mode_phase }); - } - else - { - mode.phase = mode_phase; + std::string mode_phase = phase_object.as(); + auto it_found_phase = + std::find_if(existing_phases.begin(), existing_phases.end(), [&mode_phase](const auto& phase) { return phase.name == mode_phase; }); + if (it_found_phase == existing_phases.end()) + { + std::string line = std::to_string(phase_object.Mark().line + 1); + std::string column = std::to_string(phase_object.Mark().column + 1); + errors.push_back({ ConfigParseStatus::UnknownPhase, line + ":" + column + ": Unknown phase: " + mode_phase }); + } + else + { + mode.phases.emplace_back(mode_phase); + } } mode.unknown_properties = GetComments(mode_object); diff --git a/test/unit/v1/models/test_parse_modal.cpp b/test/unit/v1/models/test_parse_modal.cpp index 771e52b5..ae4b677c 100644 --- a/test/unit/v1/models/test_parse_modal.cpp +++ b/test/unit/v1/models/test_parse_modal.cpp @@ -8,10 +8,12 @@ TEST(ParserBase, CanParseValidModalModel) { v1::Parser parser; std::vector extensions = { ".json", ".yaml" }; + for (auto& extension : extensions) { auto parsed = parser.Parse(std::string("v1_unit_configs/models/modal/valid") + extension); EXPECT_TRUE(parsed); + v1::types::Mechanism mechanism = *parsed; EXPECT_EQ(mechanism.models.modal_model.type, "MODAL"); @@ -20,14 +22,17 @@ TEST(ParserBase, CanParseValidModalModel) 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].phases.size(), 1); + EXPECT_EQ(mechanism.models.modal_model.modes[0].phases[0], "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, "aqueous"); + EXPECT_EQ(mechanism.models.modal_model.modes[1].phases.size(), 2); + EXPECT_EQ(mechanism.models.modal_model.modes[1].phases[0], "aqueous"); + EXPECT_EQ(mechanism.models.modal_model.modes[1].phases[1], "organic"); EXPECT_EQ(mechanism.models.modal_model.modes[1].unknown_properties.size(), 0); } } diff --git a/test/unit/v1/v1_unit_configs/models/modal/missing_modal_variable.json b/test/unit/v1/v1_unit_configs/models/modal/missing_modal_variable.json index 3a0a4d5f..a3acb93a 100644 --- a/test/unit/v1/v1_unit_configs/models/modal/missing_modal_variable.json +++ b/test/unit/v1/v1_unit_configs/models/modal/missing_modal_variable.json @@ -79,13 +79,13 @@ { "name": "aitken", "geometric mean diameter [m]": 2.6e-8, - "phase": "aqueous", + "phases": ["aqueous"], "__comment": "Aitken mode" }, { "name": "accumulation", "geometric mean diameter [m]": 1.1e-7, - "phase": "aqueous" + "phases": ["aqueous"] } ] } diff --git a/test/unit/v1/v1_unit_configs/models/modal/missing_modal_variable.yaml b/test/unit/v1/v1_unit_configs/models/modal/missing_modal_variable.yaml index 90a6d62f..ba8f89df 100644 --- a/test/unit/v1/v1_unit_configs/models/modal/missing_modal_variable.yaml +++ b/test/unit/v1/v1_unit_configs/models/modal/missing_modal_variable.yaml @@ -64,12 +64,14 @@ models: modes: - name: aitken geometric mean diameter [m]: 2.6e-8 - phase: aqueous + phases: + - aqueous __comment: Aitken mode - name: accumulation geometric mean diameter [m]: 1.1e-7 - phase: aqueous + phases: + - aqueous reactions: - type: HL_PHASE_TRANSFER diff --git a/test/unit/v1/v1_unit_configs/models/modal/mode_phase_not_found_in_phases.json b/test/unit/v1/v1_unit_configs/models/modal/mode_phase_not_found_in_phases.json index 5ab1079c..a658a734 100644 --- a/test/unit/v1/v1_unit_configs/models/modal/mode_phase_not_found_in_phases.json +++ b/test/unit/v1/v1_unit_configs/models/modal/mode_phase_not_found_in_phases.json @@ -44,14 +44,14 @@ "name": "aitken", "geometric mean diameter [m]": 2.6e-8, "geometric standard deviation": 1.6, - "phase": "aqueous", + "phases": ["aqueous"], "__comment": "Aitken mode" }, { "name": "accumulation", "geometric mean diameter [m]": 1.1e-7, "geometric standard deviation": 1.6, - "phase": "organic" + "phases": ["organic"] } ] } diff --git a/test/unit/v1/v1_unit_configs/models/modal/mode_phase_not_found_in_phases.yaml b/test/unit/v1/v1_unit_configs/models/modal/mode_phase_not_found_in_phases.yaml index 74ce48b9..03b4fa0e 100644 --- a/test/unit/v1/v1_unit_configs/models/modal/mode_phase_not_found_in_phases.yaml +++ b/test/unit/v1/v1_unit_configs/models/modal/mode_phase_not_found_in_phases.yaml @@ -27,13 +27,15 @@ models: - name: aitken geometric mean diameter [m]: 2.6e-8 geometric standard deviation: 1.6 - phase: aqueous + phases: + - aqueous __comment: Aitken mode - name: accumulation geometric mean diameter [m]: 1.1e-7 geometric standard deviation: 1.6 - phase: organic + phases: + - organic reactions: - type: HL_PHASE_TRANSFER diff --git a/test/unit/v1/v1_unit_configs/models/modal/valid.json b/test/unit/v1/v1_unit_configs/models/modal/valid.json index f4f4867b..fbc8e7bb 100644 --- a/test/unit/v1/v1_unit_configs/models/modal/valid.json +++ b/test/unit/v1/v1_unit_configs/models/modal/valid.json @@ -69,6 +69,12 @@ "O3", "H2O2" ] + }, + { + "name": "organic", + "species": [ + "organic carbon" + ] } ], "models": [ @@ -85,14 +91,14 @@ "name": "aitken", "geometric mean diameter [m]": 2.6e-8, "geometric standard deviation": 1.6, - "phase": "aqueous", + "phases": ["aqueous"], "__comment": "Aitken mode" }, { "name": "accumulation", "geometric mean diameter [m]": 1.1e-7, "geometric standard deviation": 1.8, - "phase": "aqueous" + "phases": ["aqueous", "organic"] } ] } diff --git a/test/unit/v1/v1_unit_configs/models/modal/valid.yaml b/test/unit/v1/v1_unit_configs/models/modal/valid.yaml index bd188455..16797ec8 100644 --- a/test/unit/v1/v1_unit_configs/models/modal/valid.yaml +++ b/test/unit/v1/v1_unit_configs/models/modal/valid.yaml @@ -58,6 +58,10 @@ phases: - O3 - H2O2 + - name: organic + species: + - organic carbon + models: - name: gas type: GAS_PHASE @@ -69,13 +73,16 @@ models: - name: aitken geometric mean diameter [m]: 2.6e-8 geometric standard deviation: 1.6 - phase: aqueous + phases: + - aqueous __comment: Aitken mode - name: accumulation geometric mean diameter [m]: 1.1e-7 geometric standard deviation: 1.8 - phase: aqueous + phases: + - aqueous + - organic reactions: - type: HL_PHASE_TRANSFER