From 29fb30ea41b1aeafd6313e910b4ed19666ca6e82 Mon Sep 17 00:00:00 2001 From: Kyle Shores Date: Fri, 12 Jan 2024 09:29:50 -0600 Subject: [PATCH] checking duplicate species --- .../mechanism_configuration/parser.hpp | 3 +- .../mechanism_configuration/validation.hpp | 3 +- include/open_atmos/types.hpp | 4 +- src/parser.cpp | 34 +++++++++++++--- test/integration/test_json_parser.cpp | 2 + test/unit/test_parse_species.cpp | 39 ++++++++++++++++++- test/unit/unit_configs/duplicate_species.json | 16 ++++++++ .../{species.json => valid_species.json} | 2 + 8 files changed, 91 insertions(+), 12 deletions(-) create mode 100644 test/unit/unit_configs/duplicate_species.json rename test/unit/unit_configs/{species.json => valid_species.json} (94%) diff --git a/include/open_atmos/mechanism_configuration/parser.hpp b/include/open_atmos/mechanism_configuration/parser.hpp index 547b585..8f6ab7b 100644 --- a/include/open_atmos/mechanism_configuration/parser.hpp +++ b/include/open_atmos/mechanism_configuration/parser.hpp @@ -32,7 +32,8 @@ namespace open_atmos RequiredKeyNotFound, ContainsNonStandardKey, MutuallyExclusiveOption, - InvalidVersion + InvalidVersion, + DuplicateSpeciesDetected }; std::string configParseStatusToString(const ConfigParseStatus &status); diff --git a/include/open_atmos/mechanism_configuration/validation.hpp b/include/open_atmos/mechanism_configuration/validation.hpp index 51833f6..8913281 100644 --- a/include/open_atmos/mechanism_configuration/validation.hpp +++ b/include/open_atmos/mechanism_configuration/validation.hpp @@ -43,12 +43,11 @@ namespace open_atmos struct Species { - const std::vector required_keys{ keys.name }; + const std::vector required_keys{ keys.name, keys.phase }; const std::vector optional_keys{ keys.tracer_type, keys.absolute_tolerance, keys.diffusion_coefficient, keys.molecular_weight, - keys.phase, keys.henrys_law_constant_298, keys.henrys_law_constant_exponential_factor, keys.n_star, diff --git a/include/open_atmos/types.hpp b/include/open_atmos/types.hpp index 9f0e117..59c0436 100644 --- a/include/open_atmos/types.hpp +++ b/include/open_atmos/types.hpp @@ -14,8 +14,10 @@ namespace open_atmos struct Species { std::string name; + std::string phase; - std::map optional_properties; + std::map optional_numerical_properties; + std::map optional_string_properties; std::unordered_map unknown_properties; }; diff --git a/src/parser.cpp b/src/parser.cpp index 599b63b..67afb72 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -27,6 +27,7 @@ namespace open_atmos case ConfigParseStatus::RequiredKeyNotFound: return "RequiredKeyNotFound"; case ConfigParseStatus::ContainsNonStandardKey: return "ContainsNonStandardKey"; case ConfigParseStatus::MutuallyExclusiveOption: return "MutuallyExclusiveOption"; + case ConfigParseStatus::DuplicateSpeciesDetected: return "DuplicateSpeciesDetected"; default: return "Unknown"; } } @@ -155,35 +156,56 @@ namespace open_atmos break; } - std::cout << "object:\n" << object.dump(4) << std::endl; + // std::cout << "object:\n" << object.dump(4) << std::endl; std::string name = object[validation::keys.name].get(); - std::map properties{}; + std::string phase = object[validation::keys.phase].get(); + + std::map numerical_properties{}; + std::map string_properties{}; for (const auto& key : validation::species.optional_keys) { if (object.contains(key)) { - double val = object[key].get(); - properties[key] = val; + if (key == validation::keys.tracer_type) { + std::string val = object[key].get(); + string_properties[key] = val; + } + else { + double val = object[key].get(); + numerical_properties[key] = val; + } } } auto comments = GetComments(object, validation::species.required_keys, validation::species.optional_keys); std::unordered_map unknown_properties; - for (const auto& key : validation::species.optional_keys) + for (const auto& key : comments) { std::string val = object[key].dump(); unknown_properties[key] = val; } species.name = name; - species.optional_properties = properties; + species.phase = phase; + species.optional_numerical_properties = numerical_properties; + species.optional_string_properties = string_properties; species.unknown_properties = unknown_properties; all_species.push_back(species); } + for(size_t i = 0; i < all_species.size(); ++i) { + for(size_t j = i+1; j < all_species.size(); ++j) { + if (all_species[i].name == all_species[j].name) { + status = ConfigParseStatus::DuplicateSpeciesDetected; + } + break; + } + if (status != ConfigParseStatus::Success) break; + } + return { status, all_species }; } diff --git a/test/integration/test_json_parser.cpp b/test/integration/test_json_parser.cpp index fc963bd..c29a40a 100644 --- a/test/integration/test_json_parser.cpp +++ b/test/integration/test_json_parser.cpp @@ -7,4 +7,6 @@ using namespace open_atmos::mechanism_configuration; TEST(JsonParser, Returns) { JsonParser parser; + auto [status, mechanism] = parser.Parse(std::string("examples/full_configuration.json")); + EXPECT_EQ(status, ConfigParseStatus::Success); } \ No newline at end of file diff --git a/test/unit/test_parse_species.cpp b/test/unit/test_parse_species.cpp index 3076f5e..c814b68 100644 --- a/test/unit/test_parse_species.cpp +++ b/test/unit/test_parse_species.cpp @@ -4,11 +4,46 @@ using namespace open_atmos::mechanism_configuration; -TEST(JsonParser, CanParseSpecies) +TEST(JsonParser, CanParseValidSpecies) { JsonParser parser; - auto [status, mechanism] = parser.Parse(std::string("unit_configs/species.json")); + auto [status, mechanism] = parser.Parse(std::string("unit_configs/valid_species.json")); EXPECT_EQ(status, ConfigParseStatus::Success); EXPECT_EQ(mechanism.species.size(), 3); + + EXPECT_EQ(mechanism.species[0].name, "A"); + EXPECT_EQ(mechanism.species[0].phase, "gas"); + EXPECT_EQ(mechanism.species[0].unknown_properties.size(), 1); + EXPECT_EQ(mechanism.species[0].unknown_properties["__absolute tolerance"], "1e-30"); + + EXPECT_EQ(mechanism.species[1].name, "H2O2"); + EXPECT_EQ(mechanism.species[1].phase, "gas"); + EXPECT_EQ(mechanism.species[1].optional_numerical_properties.size(), 6); + EXPECT_EQ(mechanism.species[1].optional_numerical_properties["HLC(298K) [mol m-3 Pa-1]"], 1.011596348); + EXPECT_EQ(mechanism.species[1].optional_numerical_properties["HLC exponential factor [K]"], 6340); + EXPECT_EQ(mechanism.species[1].optional_numerical_properties["diffusion coefficient [m2 s-1]"], 1.46e-05); + EXPECT_EQ(mechanism.species[1].optional_numerical_properties["N star"], 1.74); + EXPECT_EQ(mechanism.species[1].optional_numerical_properties["molecular weight [kg mol-1]"], 0.0340147); + EXPECT_EQ(mechanism.species[1].optional_numerical_properties["density [kg m-3]"], 1000.0); + EXPECT_EQ(mechanism.species[1].unknown_properties.size(), 1); + EXPECT_EQ(mechanism.species[1].unknown_properties["__absolute tolerance"], "1e-10"); + + EXPECT_EQ(mechanism.species[2].name, "aerosol stuff"); + EXPECT_EQ(mechanism.species[2].phase, "AEROSOL"); + EXPECT_EQ(mechanism.species[2].optional_numerical_properties.size(), 2); + EXPECT_EQ(mechanism.species[2].optional_numerical_properties["molecular weight [kg mol-1]"], 0.5); + EXPECT_EQ(mechanism.species[2].optional_numerical_properties["density [kg m-3]"], 1000.0); + EXPECT_EQ(mechanism.species[2].optional_string_properties.size(), 1); + EXPECT_EQ(mechanism.species[2].optional_string_properties["tracer type"], "CONSTANT"); + EXPECT_EQ(mechanism.species[2].unknown_properties.size(), 1); + EXPECT_EQ(mechanism.species[2].unknown_properties["__absolute tolerance"], "1e-20"); +} + +TEST(JsonParser, DetectsDuplicateSpecies) +{ + JsonParser parser; + auto [status, mechanism] = parser.Parse(std::string("unit_configs/duplicate_species.json")); + + EXPECT_EQ(status, ConfigParseStatus::DuplicateSpeciesDetected); } \ No newline at end of file diff --git a/test/unit/unit_configs/duplicate_species.json b/test/unit/unit_configs/duplicate_species.json new file mode 100644 index 0000000..f65630e --- /dev/null +++ b/test/unit/unit_configs/duplicate_species.json @@ -0,0 +1,16 @@ +{ + "version": "1.0.0", + "name": "Full Configuration", + "species": [ + { + "name": "A", + "phase": "gas" + }, + { + "name": "A", + "phase": "gas" + } + ], + "phases": [ ], + "reactions": [ ] +} \ No newline at end of file diff --git a/test/unit/unit_configs/species.json b/test/unit/unit_configs/valid_species.json similarity index 94% rename from test/unit/unit_configs/species.json rename to test/unit/unit_configs/valid_species.json index 4acdbc2..a1bd5fe 100644 --- a/test/unit/unit_configs/species.json +++ b/test/unit/unit_configs/valid_species.json @@ -4,10 +4,12 @@ "species": [ { "name": "A", + "phase": "gas", "__absolute tolerance": 1.0e-30 }, { "name": "H2O2", + "phase": "gas", "HLC(298K) [mol m-3 Pa-1]": 1.011596348, "HLC exponential factor [K]": 6340, "diffusion coefficient [m2 s-1]": 1.46E-05,