From 07b0cf1d1ce7517dcbdd65ce438ea99b8ed80366 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Thu, 5 Dec 2024 07:41:46 +0100 Subject: [PATCH 01/22] migrate owning dataset to C++ wrapper Signed-off-by: Martijn Govers --- .../include/power_grid_model_cpp/dataset.hpp | 16 +++ .../power_grid_model_cpp/serialization.hpp | 29 ++++++ .../cpp_validation_tests/test_validation.cpp | 97 +++++-------------- 3 files changed, 69 insertions(+), 73 deletions(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index 4ac301688..b57ea091b 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -173,6 +173,22 @@ class DatasetConst { detail::UniquePtr dataset_; DatasetInfo info_; }; + +struct OwningMemory { + std::vector buffers; + std::vector> indptrs; +}; + +struct OwningDatasetMutable { + DatasetMutable dataset; + DatasetConst const_dataset; + OwningMemory storage{}; +}; + +struct OwningDatasetConst { + DatasetConst const_dataset; + OwningMemory storage{}; +}; } // namespace power_grid_model_cpp #endif // POWER_GRID_MODEL_CPP_DATASET_HPP diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp index bb08fec4b..749474a78 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp @@ -90,6 +90,35 @@ class Serializer { power_grid_model_cpp::Handle handle_{}; detail::UniquePtr serializer_; }; + +inline OwningDatasetConst create_owning_dataset(DatasetWritable& writable_dataset) { + auto const& info = writable_dataset.get_info(); + bool const is_batch = info.is_batch(); + Idx const batch_size = info.batch_size(); + auto const& dataset_name = info.name(); + DatasetMutable dataset_mutable{dataset_name, is_batch, batch_size}; + DatasetConst dataset_const{dataset_mutable}; + OwningDatasetConst owning_dataset{.const_dataset{writable_dataset}}; + + for (Idx component_idx{}; component_idx < info.n_components(); ++component_idx) { + auto const& component_name = info.component_name(component_idx); + auto const& component_meta = MetaData::get_component_by_name(dataset_name, component_name); + Idx const component_elements_per_scenario = info.component_elements_per_scenario(component_idx); + Idx const component_size = info.component_total_elements(component_idx); + + auto& current_indptr = owning_dataset.storage.indptrs.emplace_back( + info.component_elements_per_scenario(component_idx) < 0 ? batch_size + 1 : 0); + if (!current_indptr.empty()) { + current_indptr.at(0) = 0; + current_indptr.at(batch_size) = component_size; + } + Idx* const indptr = current_indptr.empty() ? nullptr : current_indptr.data(); + auto& current_buffer = owning_dataset.storage.buffers.emplace_back(component_meta, component_size); + writable_dataset.set_buffer(component_name, indptr, current_buffer); + } + owning_dataset.const_dataset = writable_dataset; + return owning_dataset; +} } // namespace power_grid_model_cpp #endif // POWER_GRID_MODEL_CPP_SERIALIZATION_HPP diff --git a/tests/cpp_validation_tests/test_validation.cpp b/tests/cpp_validation_tests/test_validation.cpp index 1102dbf26..86992d58c 100644 --- a/tests/cpp_validation_tests/test_validation.cpp +++ b/tests/cpp_validation_tests/test_validation.cpp @@ -4,7 +4,7 @@ #define PGM_ENABLE_EXPERIMENTAL -#include "power_grid_model_cpp.hpp" +#include #include #include @@ -60,56 +60,14 @@ auto read_json(std::filesystem::path const& path) { return j; } -struct OwningMemory { - std::vector buffers; - std::vector> indptrs; -}; - -struct OwningDataset { - std::optional dataset; - std::optional const_dataset; - OwningMemory storage{}; -}; +OwningDatasetMutable create_result_dataset(OwningDatasetConst const& input, std::string const& dataset_name, + bool is_batch = false, Idx batch_size = 1) { + DatasetMutable dataset_mutable{dataset_name, is_batch, batch_size}; + DatasetConst dataset_const{dataset_mutable}; + OwningDatasetMutable owning_dataset{.dataset{std::move(dataset_mutable)}, + .const_dataset = std::move(dataset_const)}; -OwningDataset create_owning_dataset(DatasetWritable& writable_dataset) { - auto const& info = writable_dataset.get_info(); - bool const is_batch = info.is_batch(); - Idx const batch_size = info.batch_size(); - auto const& dataset_name = info.name(); - OwningDataset owning_dataset{.dataset{DatasetMutable{dataset_name, is_batch, batch_size}}, - .const_dataset = std::nullopt}; - - for (Idx component_idx{}; component_idx < info.n_components(); ++component_idx) { - auto const& component_name = info.component_name(component_idx); - auto const& component_meta = MetaData::get_component_by_name(dataset_name, component_name); - Idx const component_elements_per_scenario = info.component_elements_per_scenario(component_idx); - Idx const component_size = info.component_total_elements(component_idx); - - auto& current_indptr = owning_dataset.storage.indptrs.emplace_back( - info.component_elements_per_scenario(component_idx) < 0 ? batch_size + 1 : 0); - if (!current_indptr.empty()) { - current_indptr.at(0) = 0; - current_indptr.at(batch_size) = component_size; - } - Idx* const indptr = current_indptr.empty() ? nullptr : current_indptr.data(); - auto& current_buffer = owning_dataset.storage.buffers.emplace_back(component_meta, component_size); - writable_dataset.set_buffer(component_name, indptr, current_buffer); - owning_dataset.dataset.value().add_buffer(component_name, component_elements_per_scenario, component_size, - indptr, current_buffer); - } - owning_dataset.const_dataset = writable_dataset; - return owning_dataset; -} - -OwningDataset create_result_dataset(OwningDataset const& input, std::string const& dataset_name, bool is_batch = false, - Idx batch_size = 1) { - OwningDataset owning_dataset{.dataset{DatasetMutable{dataset_name, is_batch, batch_size}}, - .const_dataset = std::nullopt}; - - if (!input.const_dataset.has_value()) { - throw OptionalNotInitialized("DatasetConst"); - } - DatasetInfo const& input_info = input.const_dataset.value().get_info(); + DatasetInfo const& input_info = input.const_dataset.get_info(); for (Idx component_idx{}; component_idx != input_info.n_components(); ++component_idx) { auto const& component_name = input_info.component_name(component_idx); @@ -121,14 +79,14 @@ OwningDataset create_result_dataset(OwningDataset const& input, std::string cons input_info.component_elements_per_scenario(component_idx) < 0 ? batch_size + 1 : 0); Idx const* const indptr = current_indptr.empty() ? nullptr : current_indptr.data(); auto& current_buffer = owning_dataset.storage.buffers.emplace_back(component_meta, component_size); - owning_dataset.dataset.value().add_buffer(component_name, component_elements_per_scenario, component_size, - indptr, current_buffer); + owning_dataset.dataset.add_buffer(component_name, component_elements_per_scenario, component_size, indptr, + current_buffer); } - owning_dataset.const_dataset = owning_dataset.dataset.value(); + owning_dataset.const_dataset = owning_dataset.dataset; return owning_dataset; } -OwningDataset load_dataset(std::filesystem::path const& path) { +OwningDatasetConst load_dataset(std::filesystem::path const& path) { // Issue in msgpack, reported in https://github.com/msgpack/msgpack-c/issues/1098 // May be a Clang Analyzer bug #ifndef __clang_analyzer__ // TODO(mgovers): re-enable this when issue in msgpack is fixed @@ -255,23 +213,17 @@ void check_individual_attribute(Buffer const& buffer, Buffer const& ref_buffer, } } -void assert_result(OwningDataset const& owning_result, OwningDataset const& owning_reference_result, +void assert_result(OwningDatasetMutable const& owning_result, OwningDatasetConst const& owning_reference_result, std::map> atol, double rtol) { using namespace std::string_literals; - if (!owning_result.const_dataset.has_value()) { - throw OptionalNotInitialized("DatasetConst"); - } - DatasetConst const& result = owning_result.const_dataset.value(); + DatasetConst const& result = owning_result.const_dataset; auto const& result_info = result.get_info(); auto const& result_name = result_info.name(); Idx const result_batch_size = result_info.batch_size(); auto const& storage = owning_result.storage; - if (!owning_reference_result.const_dataset.has_value()) { - throw OptionalNotInitialized("DatasetConst"); - } - DatasetConst const& reference_result = owning_reference_result.const_dataset.value(); + DatasetConst const& reference_result = owning_reference_result.const_dataset; auto const& reference_result_info = reference_result.get_info(); auto const& reference_result_name = reference_result_info.name(); auto const& reference_storage = owning_reference_result.storage; @@ -490,10 +442,10 @@ void add_cases(std::filesystem::path const& case_dir, std::string const& calcula // test case with parameter struct ValidationCase { CaseParam param; - OwningDataset input; - std::optional output; - std::optional update_batch; - std::optional output_batch; + OwningDatasetConst input; + std::optional output; + std::optional update_batch; + std::optional output_batch; }; ValidationCase create_validation_case(CaseParam const& param, std::string const& output_type) { @@ -574,8 +526,8 @@ void validate_single_case(CaseParam const& param) { // create and run model auto const& options = get_options(param); - Model model{50.0, validation_case.input.const_dataset.value()}; - model.calculate(options, result.dataset.value()); + Model model{50.0, validation_case.input.const_dataset}; + model.calculate(options, result.dataset); // check results assert_result(result, validation_case.output.value(), param.atol, param.rtol); @@ -586,21 +538,20 @@ void validate_batch_case(CaseParam const& param) { execute_test(param, [&]() { auto const output_prefix = get_output_type(param.calculation_type, param.sym); auto const validation_case = create_validation_case(param, output_prefix); - auto const& info = validation_case.update_batch.value().const_dataset.value().get_info(); + auto const& info = validation_case.update_batch.value().const_dataset.get_info(); Idx const batch_size = info.batch_size(); auto const batch_result = create_result_dataset(validation_case.output_batch.value(), output_prefix, true, batch_size); // create model - Model model{50.0, validation_case.input.const_dataset.value()}; + Model model{50.0, validation_case.input.const_dataset}; // check results after whole update is finished for (Idx const threading : {-1, 0, 1, 2}) { CAPTURE(threading); // set options and run auto const& options = get_options(param, threading); - model.calculate(options, batch_result.dataset.value(), - validation_case.update_batch.value().const_dataset.value()); + model.calculate(options, batch_result.dataset, validation_case.update_batch.value().const_dataset); // check results assert_result(batch_result, validation_case.output_batch.value(), param.atol, param.rtol); From ae78da56985f267a3cc71141f6608e90fca4f832 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Thu, 5 Dec 2024 07:51:20 +0100 Subject: [PATCH 02/22] reduce complexity Signed-off-by: Martijn Govers --- .../include/power_grid_model_cpp/dataset.hpp | 3 +- .../power_grid_model_cpp/serialization.hpp | 11 ++++--- .../cpp_validation_tests/test_validation.cpp | 30 ++++++++----------- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index b57ea091b..052b5d456 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -181,12 +181,11 @@ struct OwningMemory { struct OwningDatasetMutable { DatasetMutable dataset; - DatasetConst const_dataset; OwningMemory storage{}; }; struct OwningDatasetConst { - DatasetConst const_dataset; + DatasetConst dataset; OwningMemory storage{}; }; } // namespace power_grid_model_cpp diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp index 749474a78..185c768ec 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp @@ -98,7 +98,7 @@ inline OwningDatasetConst create_owning_dataset(DatasetWritable& writable_datase auto const& dataset_name = info.name(); DatasetMutable dataset_mutable{dataset_name, is_batch, batch_size}; DatasetConst dataset_const{dataset_mutable}; - OwningDatasetConst owning_dataset{.const_dataset{writable_dataset}}; + OwningMemory storage{}; for (Idx component_idx{}; component_idx < info.n_components(); ++component_idx) { auto const& component_name = info.component_name(component_idx); @@ -106,18 +106,17 @@ inline OwningDatasetConst create_owning_dataset(DatasetWritable& writable_datase Idx const component_elements_per_scenario = info.component_elements_per_scenario(component_idx); Idx const component_size = info.component_total_elements(component_idx); - auto& current_indptr = owning_dataset.storage.indptrs.emplace_back( - info.component_elements_per_scenario(component_idx) < 0 ? batch_size + 1 : 0); + auto& current_indptr = + storage.indptrs.emplace_back(info.component_elements_per_scenario(component_idx) < 0 ? batch_size + 1 : 0); if (!current_indptr.empty()) { current_indptr.at(0) = 0; current_indptr.at(batch_size) = component_size; } Idx* const indptr = current_indptr.empty() ? nullptr : current_indptr.data(); - auto& current_buffer = owning_dataset.storage.buffers.emplace_back(component_meta, component_size); + auto& current_buffer = storage.buffers.emplace_back(component_meta, component_size); writable_dataset.set_buffer(component_name, indptr, current_buffer); } - owning_dataset.const_dataset = writable_dataset; - return owning_dataset; + return OwningDatasetConst{.dataset = writable_dataset, .storage = std::move(storage)}; } } // namespace power_grid_model_cpp diff --git a/tests/cpp_validation_tests/test_validation.cpp b/tests/cpp_validation_tests/test_validation.cpp index 86992d58c..8688e0bda 100644 --- a/tests/cpp_validation_tests/test_validation.cpp +++ b/tests/cpp_validation_tests/test_validation.cpp @@ -62,12 +62,9 @@ auto read_json(std::filesystem::path const& path) { OwningDatasetMutable create_result_dataset(OwningDatasetConst const& input, std::string const& dataset_name, bool is_batch = false, Idx batch_size = 1) { - DatasetMutable dataset_mutable{dataset_name, is_batch, batch_size}; - DatasetConst dataset_const{dataset_mutable}; - OwningDatasetMutable owning_dataset{.dataset{std::move(dataset_mutable)}, - .const_dataset = std::move(dataset_const)}; + DatasetInfo const& input_info = input.dataset.get_info(); - DatasetInfo const& input_info = input.const_dataset.get_info(); + OwningDatasetMutable result{.dataset{dataset_name, is_batch, batch_size}, .storage{}}; for (Idx component_idx{}; component_idx != input_info.n_components(); ++component_idx) { auto const& component_name = input_info.component_name(component_idx); @@ -75,15 +72,14 @@ OwningDatasetMutable create_result_dataset(OwningDatasetConst const& input, std: Idx const component_elements_per_scenario = input_info.component_elements_per_scenario(component_idx); Idx const component_size = input_info.component_total_elements(component_idx); - auto& current_indptr = owning_dataset.storage.indptrs.emplace_back( + auto& current_indptr = result.storage.indptrs.emplace_back( input_info.component_elements_per_scenario(component_idx) < 0 ? batch_size + 1 : 0); Idx const* const indptr = current_indptr.empty() ? nullptr : current_indptr.data(); - auto& current_buffer = owning_dataset.storage.buffers.emplace_back(component_meta, component_size); - owning_dataset.dataset.add_buffer(component_name, component_elements_per_scenario, component_size, indptr, - current_buffer); + auto& current_buffer = result.storage.buffers.emplace_back(component_meta, component_size); + result.dataset.add_buffer(component_name, component_elements_per_scenario, component_size, indptr, + current_buffer); } - owning_dataset.const_dataset = owning_dataset.dataset; - return owning_dataset; + return result; } OwningDatasetConst load_dataset(std::filesystem::path const& path) { @@ -217,13 +213,13 @@ void assert_result(OwningDatasetMutable const& owning_result, OwningDatasetConst std::map> atol, double rtol) { using namespace std::string_literals; - DatasetConst const& result = owning_result.const_dataset; + DatasetConst const result{owning_result.dataset}; auto const& result_info = result.get_info(); auto const& result_name = result_info.name(); Idx const result_batch_size = result_info.batch_size(); auto const& storage = owning_result.storage; - DatasetConst const& reference_result = owning_reference_result.const_dataset; + DatasetConst const& reference_result = owning_reference_result.dataset; auto const& reference_result_info = reference_result.get_info(); auto const& reference_result_name = reference_result_info.name(); auto const& reference_storage = owning_reference_result.storage; @@ -526,7 +522,7 @@ void validate_single_case(CaseParam const& param) { // create and run model auto const& options = get_options(param); - Model model{50.0, validation_case.input.const_dataset}; + Model model{50.0, validation_case.input.dataset}; model.calculate(options, result.dataset); // check results @@ -538,20 +534,20 @@ void validate_batch_case(CaseParam const& param) { execute_test(param, [&]() { auto const output_prefix = get_output_type(param.calculation_type, param.sym); auto const validation_case = create_validation_case(param, output_prefix); - auto const& info = validation_case.update_batch.value().const_dataset.get_info(); + auto const& info = validation_case.update_batch.value().dataset.get_info(); Idx const batch_size = info.batch_size(); auto const batch_result = create_result_dataset(validation_case.output_batch.value(), output_prefix, true, batch_size); // create model - Model model{50.0, validation_case.input.const_dataset}; + Model model{50.0, validation_case.input.dataset}; // check results after whole update is finished for (Idx const threading : {-1, 0, 1, 2}) { CAPTURE(threading); // set options and run auto const& options = get_options(param, threading); - model.calculate(options, batch_result.dataset, validation_case.update_batch.value().const_dataset); + model.calculate(options, batch_result.dataset, validation_case.update_batch.value().dataset); // check results assert_result(batch_result, validation_case.output_batch.value(), param.atol, param.rtol); From 635e9261a09970d37a48994b56f775a6e64e4e05 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Thu, 5 Dec 2024 08:31:17 +0100 Subject: [PATCH 03/22] migrate API model - all updates test to JSON input Signed-off-by: Martijn Govers --- .../test_api_model_update.cpp | 191 +++++++++++++----- 1 file changed, 136 insertions(+), 55 deletions(-) diff --git a/tests/native_api_tests/test_api_model_update.cpp b/tests/native_api_tests/test_api_model_update.cpp index 0614b2535..cb21f3dbe 100644 --- a/tests/native_api_tests/test_api_model_update.cpp +++ b/tests/native_api_tests/test_api_model_update.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -255,6 +256,7 @@ TEST_CASE_TEMPLATE( } namespace { +using namespace std::string_literals; using std::numbers::sqrt3; enum class CalculationSymmetry : Idx { symmetric = PGM_symmetric, asymmetric = PGM_asymmetric }; @@ -284,6 +286,14 @@ Options get_default_options(PGM_SymmetryType calculation_symmetry, PGM_Calculati return opt; } +OwningDatasetConst load_dataset(std::string const& json_string) { + Deserializer deserializer{json_string, PGM_json}; + auto& writable_dataset = deserializer.get_dataset(); + auto owning_dataset = create_owning_dataset(writable_dataset); + deserializer.parse_to_buffer(); + return owning_dataset; +} + namespace test { constexpr double z_bus_2 = 1.0 / (0.015 + 0.5e6 / 10e3 / 10e3 * 2); constexpr double z_total = z_bus_2 + 10.0; @@ -293,6 +303,65 @@ constexpr double i_shunt = 0.015 / 0.025 * i; constexpr double i_load = 0.005 / 0.025 * i; } // namespace test +auto const state_json = R"json({ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 1, "u_rated": 10000}, + {"id": 2, "u_rated": 10000}, + {"id": 3, "u_rated": 10000} + ], + "line": [ + {"id": 4, "from_node": 1, "to_node": 2, "from_status": 1, "to_status": 1, "r1": 10, "x1": 0, "c1": 0, "tan1": 0, "r0": 10, "x0": 0, "c0": 0, "tan0": 0, "i_n": 1000} + ], + "link": [ + {"id": 5, "from_node": 2, "to_node": 3, "from_status": 1, "to_status": 1} + ], + "source": [ + {"id": 6, "node": 1, "status": 1, "u_ref": 1.05, "sk": 1000000000000}, + {"id": 10, "node": 3, "status": 0, "u_ref": 1.05, "u_ref_angle": 0, "sk": 1000000000000} + ], + "sym_load": [ + {"id": 7, "node": 3, "status": 1, "type": 1, "p_specified": 500000, "q_specified": 0} + ], + "asym_load": [ + {"id": 8, "node": 3, "status": 1, "type": 1, "p_specified": [166666.6666666667, 166666.6666666667, 166666.6666666667], "q_specified": [0, 0, 0]} + ], + "shunt": [ + {"id": 9, "node": 3, "status": 1, "g1": 0.015, "b1": 0, "g0": 0.015, "b0": 0} + ] + } +})json"s; + +auto const update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "sym_load": [ + {"id": 7, "status": 1, "p_specified": 2500000} + ], + "asym_load": [ + {"id": 8, "status": 0} + ], + "shunt": [ + {"id": 9, "status": 0, "b1": 0.02, "b0": 0.02} + ], + "source": [ + {"id": 10, "status": 1, "u_ref": 0.84} + ], + "link": [ + {"id": 5, "from_status": 1, "to_status": 0} + ] + } + ] +})json"; + struct State { std::vector node_id{1, 2, 3}; std::vector node_u_rated{10e3, 10e3, 10e3}; @@ -416,65 +485,77 @@ struct State { } // namespace TEST_CASE("API model - all updates") { - using namespace std::string_literals; + // TODO(mgovers): remove + // State const state; + // auto const input_dataset = state.get_input_dataset(); + // Serializer serializer{state.get_input_dataset(), PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const owning_input_dataset = load_dataset(state_json); + auto const& input_dataset = owning_input_dataset.dataset; - State const state; - auto const input_dataset = state.get_input_dataset(); auto const& input_info = input_dataset.get_info(); auto model = Model{50.0, input_dataset}; - // update vector - std::vector sym_load_update_id{7}; - std::vector sym_load_update_status{1}; - std::vector sym_load_update_p_specified{2.5e6}; - - std::vector asym_load_update_id{8}; - std::vector asym_load_update_status{0}; - - std::vector shunt_update_id{9}; - std::vector shunt_update_status{0}; - std::vector shunt_update_b1{0.02}; - std::vector shunt_update_b0{0.02}; - - // used for test case alternate compute mode - std::vector const shunt_update_2_id{6}; - std::vector const source_update_2_status{0}; - std::vector const shunt_update_2_b1{0.01}; - std::vector const shunt_update_2_b0{0.01}; - - std::vector source_update_id{10}; - std::vector source_update_status{1}; - std::vector source_update_u_ref{test::u1}; - - std::vector link_update_id{5}; - std::vector link_update_from_status{1}; - std::vector link_update_to_status{0}; - - DatasetConst update_data{"update", true, 1}; - update_data.add_buffer("sym_load", 1, 1, nullptr, nullptr); - update_data.add_attribute_buffer("sym_load", "id", sym_load_update_id.data()); - update_data.add_attribute_buffer("sym_load", "status", sym_load_update_status.data()); - update_data.add_attribute_buffer("sym_load", "p_specified", sym_load_update_p_specified.data()); - - update_data.add_buffer("asym_load", 1, 1, nullptr, nullptr); - update_data.add_attribute_buffer("asym_load", "id", asym_load_update_id.data()); - update_data.add_attribute_buffer("asym_load", "status", asym_load_update_status.data()); - - update_data.add_buffer("shunt", 1, 1, nullptr, nullptr); - update_data.add_attribute_buffer("shunt", "id", shunt_update_id.data()); - update_data.add_attribute_buffer("shunt", "status", shunt_update_status.data()); - update_data.add_attribute_buffer("shunt", "b1", shunt_update_b1.data()); - update_data.add_attribute_buffer("shunt", "b0", shunt_update_b0.data()); - - update_data.add_buffer("source", 1, 1, nullptr, nullptr); - update_data.add_attribute_buffer("source", "id", source_update_id.data()); - update_data.add_attribute_buffer("source", "status", source_update_status.data()); - update_data.add_attribute_buffer("source", "u_ref", source_update_u_ref.data()); - - update_data.add_buffer("link", 1, 1, nullptr, nullptr); - update_data.add_attribute_buffer("link", "id", link_update_id.data()); - update_data.add_attribute_buffer("link", "from_status", link_update_from_status.data()); - update_data.add_attribute_buffer("link", "to_status", link_update_to_status.data()); + // // update vector + // std::vector sym_load_update_id{7}; + // std::vector sym_load_update_status{1}; + // std::vector sym_load_update_p_specified{2.5e6}; + + // std::vector asym_load_update_id{8}; + // std::vector asym_load_update_status{0}; + + // std::vector shunt_update_id{9}; + // std::vector shunt_update_status{0}; + // std::vector shunt_update_b1{0.02}; + // std::vector shunt_update_b0{0.02}; + + // // used for test case alternate compute mode + // std::vector const shunt_update_2_id{6}; + // std::vector const source_update_2_status{0}; + // std::vector const shunt_update_2_b1{0.01}; + // std::vector const shunt_update_2_b0{0.01}; + + // std::vector source_update_id{10}; + // std::vector source_update_status{1}; + // std::vector source_update_u_ref{test::u1}; + + // std::vector link_update_id{5}; + // std::vector link_update_from_status{1}; + // std::vector link_update_to_status{0}; + + // DatasetConst update_data{"update", true, 1}; + // update_data.add_buffer("sym_load", 1, 1, nullptr, nullptr); + // update_data.add_attribute_buffer("sym_load", "id", sym_load_update_id.data()); + // update_data.add_attribute_buffer("sym_load", "status", sym_load_update_status.data()); + // update_data.add_attribute_buffer("sym_load", "p_specified", sym_load_update_p_specified.data()); + + // update_data.add_buffer("asym_load", 1, 1, nullptr, nullptr); + // update_data.add_attribute_buffer("asym_load", "id", asym_load_update_id.data()); + // update_data.add_attribute_buffer("asym_load", "status", asym_load_update_status.data()); + + // update_data.add_buffer("shunt", 1, 1, nullptr, nullptr); + // update_data.add_attribute_buffer("shunt", "id", shunt_update_id.data()); + // update_data.add_attribute_buffer("shunt", "status", shunt_update_status.data()); + // update_data.add_attribute_buffer("shunt", "b1", shunt_update_b1.data()); + // update_data.add_attribute_buffer("shunt", "b0", shunt_update_b0.data()); + + // update_data.add_buffer("source", 1, 1, nullptr, nullptr); + // update_data.add_attribute_buffer("source", "id", source_update_id.data()); + // update_data.add_attribute_buffer("source", "status", source_update_status.data()); + // update_data.add_attribute_buffer("source", "u_ref", source_update_u_ref.data()); + + // update_data.add_buffer("link", 1, 1, nullptr, nullptr); + // update_data.add_attribute_buffer("link", "id", link_update_id.data()); + // update_data.add_attribute_buffer("link", "from_status", link_update_from_status.data()); + // update_data.add_attribute_buffer("link", "to_status", link_update_to_status.data()); + + // TODO(mgovers): remove + // Serializer serializer{update_data, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const owning_update_dataset = load_dataset(update_json); + auto const& update_data = owning_update_dataset.dataset; auto const output_dataset_type = "sym_output"s; for (Idx comp_type_idx = 0; comp_type_idx < input_info.n_components(); ++comp_type_idx) { From df9878c7b2749473f19ef3c1312d1ded0a608075 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Thu, 5 Dec 2024 17:49:59 +0100 Subject: [PATCH 04/22] migrate update of update with alternating compute mode Signed-off-by: Martijn Govers --- .../test_api_model_update.cpp | 90 ++++++++++++------- 1 file changed, 59 insertions(+), 31 deletions(-) diff --git a/tests/native_api_tests/test_api_model_update.cpp b/tests/native_api_tests/test_api_model_update.cpp index cb21f3dbe..9e031d90b 100644 --- a/tests/native_api_tests/test_api_model_update.cpp +++ b/tests/native_api_tests/test_api_model_update.cpp @@ -360,7 +360,27 @@ auto const update_json = R"json({ ] } ] -})json"; +})json"s; + +auto const update_vector_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "sym_load": [ + {"id": 7, "status": 1, "p_specified": 2500000} + ], + "asym_load": [ + {"id": 8, "status": 0} + ], + "shunt": [ + {"id": 9, "status": 0, "b1": 0.02, "b0": 0.02} + ] + } + ] +})json"s; struct State { std::vector node_id{1, 2, 3}; @@ -605,8 +625,9 @@ TEST_CASE("API model - all updates") { } TEST_CASE("API model - updates w/ alternating compute mode") { - State const state; - auto const input_dataset = state.get_input_dataset(); + auto const owning_input_dataset = load_dataset(state_json); + auto const& input_dataset = owning_input_dataset.dataset; + auto model = Model{50.0, input_dataset}; auto const check_sym = [&model] { @@ -688,34 +709,41 @@ TEST_CASE("API model - updates w/ alternating compute mode") { CHECK(asym_shunt_output_i[2] == doctest::Approx(0.0)); }; - // update vector - std::vector sym_load_update_id{7}; - std::vector sym_load_update_status{1}; - std::vector sym_load_update_p_specified{2.5e6}; - - std::vector asym_load_update_id{8}; - std::vector asym_load_update_status{0}; - - std::vector shunt_update_id{9}; - std::vector shunt_update_status{0}; - std::vector shunt_update_b1{0.02}; - std::vector shunt_update_b0{0.02}; - - DatasetConst update_data{"update", true, 1}; - update_data.add_buffer("sym_load", 1, 1, nullptr, nullptr); - update_data.add_attribute_buffer("sym_load", "id", sym_load_update_id.data()); - update_data.add_attribute_buffer("sym_load", "status", sym_load_update_status.data()); - update_data.add_attribute_buffer("sym_load", "p_specified", sym_load_update_p_specified.data()); - - update_data.add_buffer("asym_load", 1, 1, nullptr, nullptr); - update_data.add_attribute_buffer("asym_load", "id", asym_load_update_id.data()); - update_data.add_attribute_buffer("asym_load", "status", asym_load_update_status.data()); - - update_data.add_buffer("shunt", 1, 1, nullptr, nullptr); - update_data.add_attribute_buffer("shunt", "id", shunt_update_id.data()); - update_data.add_attribute_buffer("shunt", "status", shunt_update_status.data()); - update_data.add_attribute_buffer("shunt", "b1", shunt_update_b1.data()); - update_data.add_attribute_buffer("shunt", "b0", shunt_update_b0.data()); + // // update vector + // std::vector sym_load_update_id{7}; + // std::vector sym_load_update_status{1}; + // std::vector sym_load_update_p_specified{2.5e6}; + + // std::vector asym_load_update_id{8}; + // std::vector asym_load_update_status{0}; + + // std::vector shunt_update_id{9}; + // std::vector shunt_update_status{0}; + // std::vector shunt_update_b1{0.02}; + // std::vector shunt_update_b0{0.02}; + + // DatasetConst update_data{"update", true, 1}; + // update_data.add_buffer("sym_load", 1, 1, nullptr, nullptr); + // update_data.add_attribute_buffer("sym_load", "id", sym_load_update_id.data()); + // update_data.add_attribute_buffer("sym_load", "status", sym_load_update_status.data()); + // update_data.add_attribute_buffer("sym_load", "p_specified", sym_load_update_p_specified.data()); + + // update_data.add_buffer("asym_load", 1, 1, nullptr, nullptr); + // update_data.add_attribute_buffer("asym_load", "id", asym_load_update_id.data()); + // update_data.add_attribute_buffer("asym_load", "status", asym_load_update_status.data()); + + // update_data.add_buffer("shunt", 1, 1, nullptr, nullptr); + // update_data.add_attribute_buffer("shunt", "id", shunt_update_id.data()); + // update_data.add_attribute_buffer("shunt", "status", shunt_update_status.data()); + // update_data.add_attribute_buffer("shunt", "b1", shunt_update_b1.data()); + // update_data.add_attribute_buffer("shunt", "b0", shunt_update_b0.data()); + + // // TODO(mgovers): remove + // Serializer serializer{update_data, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const owning_update_dataset = load_dataset(update_vector_json); + auto const& update_data = owning_update_dataset.dataset; // This will lead to no topo change but param change model.update(update_data); From c585b25b9cc683b420c7fedd64457f29b64d4d42 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 9 Dec 2024 17:37:51 +0100 Subject: [PATCH 05/22] migrate incomplete update tests to JSON input Signed-off-by: Martijn Govers --- .../test_api_model_update.cpp | 179 ++++++++++++++---- 1 file changed, 138 insertions(+), 41 deletions(-) diff --git a/tests/native_api_tests/test_api_model_update.cpp b/tests/native_api_tests/test_api_model_update.cpp index 9e031d90b..357c4871f 100644 --- a/tests/native_api_tests/test_api_model_update.cpp +++ b/tests/native_api_tests/test_api_model_update.cpp @@ -764,6 +764,81 @@ TEST_CASE("API model - updates w/ alternating compute mode") { } namespace { +auto const incomplete_state_json = R"json({ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 1, "u_rated": 10000}, + {"id": 2, "u_rated": 10000}, + {"id": 3, "u_rated": 10000} + ], + "line": [ + {"id": 4, "from_node": 1, "to_node": 2, "from_status": 1, "to_status": 1, "r1": 10, "x1": 0, "c1": 0, "tan1": 0, "r0": 10, "x0": 0, "c0": 0, "tan0": 0, "i_n": 1000} + ], + "link": [ + {"id": 5, "from_node": 2, "to_node": 3, "from_status": 1, "to_status": 1} + ], + "source": [ + {"id": 6, "node": 1, "status": 1, "sk": 1000000000000}, + {"id": 10, "node": 3, "status": 0, "sk": 1000000000000} + ], + "sym_load": [ + {"id": 7, "node": 3, "status": 1, "type": 1, "q_specified": 0} + ], + "asym_load": [ + {"id": 8, "node": 3, "status": 1, "type": 1, "q_specified": [0, 0, 0]} + ], + "shunt": [ + {"id": 9, "node": 3, "status": 1, "g1": 0.015, "b1": 0, "g0": 0.015, "b0": 0} + ] + } +})json"s; + +auto const incomplete_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "source": [ + {"id": 6}, + {"id": 10} + ], + "sym_load": [ + {"id": 7} + ], + "asym_load": [ + {"id": 8} + ] + } + ] +})json"s; + +auto const complete_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "source": [ + {"id": 6, "u_ref": 1.05}, + {"id": 10, "u_ref": 1.05, "u_ref_angle": 0} + ], + "sym_load": [ + {"id": 7, "p_specified": 500000} + ], + "asym_load": [ + {"id": 8, "p_specified": [166666.6666666667, 166666.6666666667, 166666.6666666667]} + ] + } + ] +})json"s; + auto get_incomplete_state() -> State { State result; @@ -777,10 +852,20 @@ auto get_incomplete_state() -> State { } // namespace TEST_CASE("API model - incomplete input") { - State const complete_state; - State const incomplete_state = get_incomplete_state(); + State const complete_state; // TODO(mgovers): also migrate + // State const incomplete_state = get_incomplete_state(); - auto test_model = Model{50.0, incomplete_state.get_input_dataset()}; + auto const owning_input_dataset = load_dataset(incomplete_state_json); + auto const& incomplete_input_data = owning_input_dataset.dataset; + + // // TODO(mgovers): remove + // Serializer serializer{update_data, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + // auto const owning_update_dataset = load_dataset(update_vector_json); + // auto const& update_data = owning_update_dataset.dataset; + + auto test_model = Model{50.0, incomplete_input_data}; for (auto symmetry : {PGM_symmetric, PGM_asymmetric}) { CAPTURE(symmetry); @@ -817,25 +902,31 @@ TEST_CASE("API model - incomplete input") { } } SUBCASE("Incomplete update dataset") { - DatasetConst incomplete_update_data{"update", true, 1}; - incomplete_update_data.add_buffer("source", std::ssize(incomplete_state.source_id), - std::ssize(incomplete_state.source_id), nullptr, nullptr); - incomplete_update_data.add_attribute_buffer("source", "id", incomplete_state.source_id.data()); - incomplete_update_data.add_attribute_buffer("source", "u_ref", incomplete_state.source_u_ref.data()); - incomplete_update_data.add_attribute_buffer("source", "u_ref_angle", - incomplete_state.source_u_ref_angle.data()); - - incomplete_update_data.add_buffer("sym_load", std::ssize(incomplete_state.sym_load_id), - std::ssize(incomplete_state.sym_load_id), nullptr, nullptr); - incomplete_update_data.add_attribute_buffer("sym_load", "id", incomplete_state.sym_load_id.data()); - incomplete_update_data.add_attribute_buffer("sym_load", "p_specified", - incomplete_state.sym_load_p_specified.data()); - - incomplete_update_data.add_buffer("asym_load", std::ssize(incomplete_state.asym_load_id), - std::ssize(incomplete_state.asym_load_id), nullptr, nullptr); - incomplete_update_data.add_attribute_buffer("asym_load", "id", incomplete_state.asym_load_id.data()); - incomplete_update_data.add_attribute_buffer("asym_load", "p_specified", - incomplete_state.asym_load_p_specified.data()); + // DatasetConst incomplete_update_data{"update", true, 1}; + // incomplete_update_data.add_buffer("source", std::ssize(incomplete_state.source_id), + // std::ssize(incomplete_state.source_id), nullptr, nullptr); + // incomplete_update_data.add_attribute_buffer("source", "id", incomplete_state.source_id.data()); + // incomplete_update_data.add_attribute_buffer("source", "u_ref", incomplete_state.source_u_ref.data()); + // incomplete_update_data.add_attribute_buffer("source", "u_ref_angle", + // incomplete_state.source_u_ref_angle.data()); + + // incomplete_update_data.add_buffer("sym_load", std::ssize(incomplete_state.sym_load_id), + // std::ssize(incomplete_state.sym_load_id), nullptr, nullptr); + // incomplete_update_data.add_attribute_buffer("sym_load", "id", incomplete_state.sym_load_id.data()); + // incomplete_update_data.add_attribute_buffer("sym_load", "p_specified", + // incomplete_state.sym_load_p_specified.data()); + + // incomplete_update_data.add_buffer("asym_load", std::ssize(incomplete_state.asym_load_id), + // std::ssize(incomplete_state.asym_load_id), nullptr, nullptr); + // incomplete_update_data.add_attribute_buffer("asym_load", "id", incomplete_state.asym_load_id.data()); + // incomplete_update_data.add_attribute_buffer("asym_load", "p_specified", + // incomplete_state.asym_load_p_specified.data()); + // // TODO(mgovers): remove + // Serializer serializer{incomplete_update_data, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const owning_update_dataset = load_dataset(incomplete_update_json); + auto const& incomplete_update_data = owning_update_dataset.dataset; SUBCASE("Single update") { CHECK_NOTHROW(test_model.update(incomplete_update_data)); @@ -850,25 +941,31 @@ TEST_CASE("API model - incomplete input") { } } SUBCASE("Complete update dataset") { - DatasetConst complete_update_data{"update", true, 1}; - complete_update_data.add_buffer("source", std::ssize(complete_state.source_id), - std::ssize(complete_state.source_id), nullptr, nullptr); - complete_update_data.add_attribute_buffer("source", "id", complete_state.source_id.data()); - complete_update_data.add_attribute_buffer("source", "u_ref", complete_state.source_u_ref.data()); - complete_update_data.add_attribute_buffer("source", "u_ref_angle", - complete_state.source_u_ref_angle.data()); - - complete_update_data.add_buffer("sym_load", std::ssize(complete_state.sym_load_id), - std::ssize(complete_state.sym_load_id), nullptr, nullptr); - complete_update_data.add_attribute_buffer("sym_load", "id", complete_state.sym_load_id.data()); - complete_update_data.add_attribute_buffer("sym_load", "p_specified", - complete_state.sym_load_p_specified.data()); - - complete_update_data.add_buffer("asym_load", std::ssize(complete_state.asym_load_id), - std::ssize(complete_state.asym_load_id), nullptr, nullptr); - complete_update_data.add_attribute_buffer("asym_load", "id", complete_state.asym_load_id.data()); - complete_update_data.add_attribute_buffer("asym_load", "p_specified", - complete_state.asym_load_p_specified.data()); + // DatasetConst complete_update_data{"update", true, 1}; + // complete_update_data.add_buffer("source", std::ssize(complete_state.source_id), + // std::ssize(complete_state.source_id), nullptr, nullptr); + // complete_update_data.add_attribute_buffer("source", "id", complete_state.source_id.data()); + // complete_update_data.add_attribute_buffer("source", "u_ref", complete_state.source_u_ref.data()); + // complete_update_data.add_attribute_buffer("source", "u_ref_angle", + // complete_state.source_u_ref_angle.data()); + + // complete_update_data.add_buffer("sym_load", std::ssize(complete_state.sym_load_id), + // std::ssize(complete_state.sym_load_id), nullptr, nullptr); + // complete_update_data.add_attribute_buffer("sym_load", "id", complete_state.sym_load_id.data()); + // complete_update_data.add_attribute_buffer("sym_load", "p_specified", + // complete_state.sym_load_p_specified.data()); + + // complete_update_data.add_buffer("asym_load", std::ssize(complete_state.asym_load_id), + // std::ssize(complete_state.asym_load_id), nullptr, nullptr); + // complete_update_data.add_attribute_buffer("asym_load", "id", complete_state.asym_load_id.data()); + // complete_update_data.add_attribute_buffer("asym_load", "p_specified", + // complete_state.asym_load_p_specified.data()); + // // // TODO(mgovers): remove + // Serializer serializer{complete_update_data, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const owning_update_dataset = load_dataset(complete_update_json); + auto const& complete_update_data = owning_update_dataset.dataset; auto ref_model = Model{50.0, complete_state.get_input_dataset()}; Buffer ref_node_output(node_output_meta, std::ssize(complete_state.node_id)); From e15d5fdb2628bb56b9edc0c416e7f87fd7bf6f37 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 9 Dec 2024 17:49:21 +0100 Subject: [PATCH 06/22] migrate incomplete followed by complete update tests to JSON input Signed-off-by: Martijn Govers --- .../test_api_model_update.cpp | 170 +++++++++++++----- 1 file changed, 124 insertions(+), 46 deletions(-) diff --git a/tests/native_api_tests/test_api_model_update.cpp b/tests/native_api_tests/test_api_model_update.cpp index 357c4871f..12a1f3d52 100644 --- a/tests/native_api_tests/test_api_model_update.cpp +++ b/tests/native_api_tests/test_api_model_update.cpp @@ -1013,12 +1013,76 @@ TEST_CASE("API model - incomplete input") { } } +auto const mixed_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "source": [ + {"id": 6, "status": 1}, + {"id": 10, "status": 1} + ], + "sym_load": [ + {"id": 7, "status": 1, "q_specified": 1} + ], + "asym_load": [ + {"id": 8, "status": 1, "q_specified": [1, 1, 1]} + ] + }, + { + "source": [ + {"id": 6, "status": 1, "u_ref": 1.05}, + {"id": 10, "status": 1, "u_ref": 1.05, "u_ref_angle": 0} + ], + "sym_load": [ + {"id": 7, "status": 0, "p_specified": 500000} + ], + "asym_load": [ + {"id": 8, "status": 0, "p_specified": [166666.6666666667, 166666.6666666667, 166666.6666666667]} + ] + } + ] +})json"s; + +auto const second_scenario_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "source": [ + {"id": 6, "status": 1, "u_ref": 1.05}, + {"id": 10, "status": 1, "u_ref": 1.05, "u_ref_angle": 0} + ], + "sym_load": [ + {"id": 7, "status": 1, "p_specified": 500000} + ], + "asym_load": [ + {"id": 8, "status": 1, "p_specified": [null, null, 166666.6666666667], "q_specified": [1, 1, null]} + ] + } + ] +})json"s; + TEST_CASE("API model - Incomplete scenario update followed by complete") { State const complete_state; State const incomplete_state = get_incomplete_state(); - auto ref_model = Model{50.0, complete_state.get_input_dataset()}; - auto test_model = Model{50.0, incomplete_state.get_input_dataset()}; + // TODO(mgovers): remove + // auto ref_model = Model{50.0, complete_state.get_input_dataset()}; + // auto test_model = Model{50.0, incomplete_state.get_input_dataset()}; + + auto const complete_owning_input_dataset = load_dataset(state_json); + auto const incomplete_owning_input_dataset = load_dataset(incomplete_state_json); + + auto const& complete_input_data = complete_owning_input_dataset.dataset; + auto const& incomplete_input_data = incomplete_owning_input_dataset.dataset; + + auto ref_model = Model{50.0, complete_input_data}; + auto test_model = Model{50.0, incomplete_input_data}; constexpr Idx batch_size = 2; auto const n_nodes = static_cast(complete_state.node_id.size()); @@ -1042,50 +1106,64 @@ TEST_CASE("API model - Incomplete scenario update followed by complete") { REQUIRE(source_indptr.size() == batch_size + 1); - DatasetConst mixed_update_data{"update", true, batch_size}; - - mixed_update_data.add_buffer("source", 2, 4, nullptr, nullptr); - mixed_update_data.add_attribute_buffer("source", "id", mixed_source_update_id.data()); - mixed_update_data.add_attribute_buffer("source", "status", mixed_source_update_status.data()); - mixed_update_data.add_attribute_buffer("source", "u_ref", mixed_source_update_u_ref.data()); - mixed_update_data.add_attribute_buffer("source", "u_ref_angle", mixed_source_update_u_ref_angle.data()); - - mixed_update_data.add_buffer("sym_load", 1, 2, nullptr, nullptr); - mixed_update_data.add_attribute_buffer("sym_load", "id", mixed_sym_load_update_id.data()); - mixed_update_data.add_attribute_buffer("sym_load", "status", mixed_sym_load_update_status.data()); - mixed_update_data.add_attribute_buffer("sym_load", "p_specified", mixed_sym_load_update_p_specified.data()); - mixed_update_data.add_attribute_buffer("sym_load", "q_specified", mixed_sym_load_update_q_specified.data()); - - mixed_update_data.add_buffer("asym_load", 1, 2, nullptr, nullptr); - mixed_update_data.add_attribute_buffer("asym_load", "id", mixed_asym_load_update_id.data()); - mixed_update_data.add_attribute_buffer("asym_load", "status", mixed_asym_load_update_status.data()); - mixed_update_data.add_attribute_buffer("asym_load", "p_specified", mixed_asym_load_update_p_specified.data()); - mixed_update_data.add_attribute_buffer("asym_load", "q_specified", mixed_asym_load_update_q_specified.data()); - - DatasetConst second_scenario_update_data{"update", true, 1}; - - second_scenario_update_data.add_buffer("source", 2, 2, nullptr, nullptr); - second_scenario_update_data.add_attribute_buffer("source", "id", mixed_source_update_id.data() + 2); - second_scenario_update_data.add_attribute_buffer("source", "status", mixed_source_update_status.data() + 2); - second_scenario_update_data.add_attribute_buffer("source", "u_ref", mixed_source_update_u_ref.data() + 2); - second_scenario_update_data.add_attribute_buffer("source", "u_ref_angle", - mixed_source_update_u_ref_angle.data() + 2); - - second_scenario_update_data.add_buffer("sym_load", 1, 1, nullptr, nullptr); - second_scenario_update_data.add_attribute_buffer("sym_load", "id", mixed_sym_load_update_id.data() + 1); - second_scenario_update_data.add_attribute_buffer("sym_load", "status", mixed_sym_load_update_status.data() + 1); - second_scenario_update_data.add_attribute_buffer("sym_load", "p_specified", - mixed_sym_load_update_p_specified.data() + 1); - second_scenario_update_data.add_attribute_buffer("sym_load", "q_specified", - mixed_sym_load_update_q_specified.data() + 1); - - second_scenario_update_data.add_buffer("asym_load", 1, 1, nullptr, nullptr); - second_scenario_update_data.add_attribute_buffer("asym_load", "id", mixed_asym_load_update_id.data() + 1); - second_scenario_update_data.add_attribute_buffer("asym_load", "status", mixed_asym_load_update_status.data() + 1); - second_scenario_update_data.add_attribute_buffer("asym_load", "p_specified", - mixed_asym_load_update_p_specified.data() + 1); - second_scenario_update_data.add_attribute_buffer("asym_load", "q_specified", - mixed_asym_load_update_q_specified.data() + 1); + // DatasetConst mixed_update_data{"update", true, batch_size}; + + // mixed_update_data.add_buffer("source", 2, 4, nullptr, nullptr); + // mixed_update_data.add_attribute_buffer("source", "id", mixed_source_update_id.data()); + // mixed_update_data.add_attribute_buffer("source", "status", mixed_source_update_status.data()); + // mixed_update_data.add_attribute_buffer("source", "u_ref", mixed_source_update_u_ref.data()); + // mixed_update_data.add_attribute_buffer("source", "u_ref_angle", mixed_source_update_u_ref_angle.data()); + + // mixed_update_data.add_buffer("sym_load", 1, 2, nullptr, nullptr); + // mixed_update_data.add_attribute_buffer("sym_load", "id", mixed_sym_load_update_id.data()); + // mixed_update_data.add_attribute_buffer("sym_load", "status", mixed_sym_load_update_status.data()); + // mixed_update_data.add_attribute_buffer("sym_load", "p_specified", mixed_sym_load_update_p_specified.data()); + // mixed_update_data.add_attribute_buffer("sym_load", "q_specified", mixed_sym_load_update_q_specified.data()); + + // mixed_update_data.add_buffer("asym_load", 1, 2, nullptr, nullptr); + // mixed_update_data.add_attribute_buffer("asym_load", "id", mixed_asym_load_update_id.data()); + // mixed_update_data.add_attribute_buffer("asym_load", "status", mixed_asym_load_update_status.data()); + // mixed_update_data.add_attribute_buffer("asym_load", "p_specified", mixed_asym_load_update_p_specified.data()); + // mixed_update_data.add_attribute_buffer("asym_load", "q_specified", mixed_asym_load_update_q_specified.data()); + + // // TODO(mgovers): remove + // Serializer serializer{mixed_update_data, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const mixed_owning_update_dataset = load_dataset(mixed_update_json); + auto const& mixed_update_data = mixed_owning_update_dataset.dataset; + + // DatasetConst second_scenario_update_data{"update", true, 1}; + + // second_scenario_update_data.add_buffer("source", 2, 2, nullptr, nullptr); + // second_scenario_update_data.add_attribute_buffer("source", "id", mixed_source_update_id.data() + 2); + // second_scenario_update_data.add_attribute_buffer("source", "status", mixed_source_update_status.data() + 2); + // second_scenario_update_data.add_attribute_buffer("source", "u_ref", mixed_source_update_u_ref.data() + 2); + // second_scenario_update_data.add_attribute_buffer("source", "u_ref_angle", + // mixed_source_update_u_ref_angle.data() + 2); + + // second_scenario_update_data.add_buffer("sym_load", 1, 1, nullptr, nullptr); + // second_scenario_update_data.add_attribute_buffer("sym_load", "id", mixed_sym_load_update_id.data() + 1); + // second_scenario_update_data.add_attribute_buffer("sym_load", "status", mixed_sym_load_update_status.data() + 1); + // second_scenario_update_data.add_attribute_buffer("sym_load", "p_specified", + // mixed_sym_load_update_p_specified.data() + 1); + // second_scenario_update_data.add_attribute_buffer("sym_load", "q_specified", + // mixed_sym_load_update_q_specified.data() + 1); + + // second_scenario_update_data.add_buffer("asym_load", 1, 1, nullptr, nullptr); + // second_scenario_update_data.add_attribute_buffer("asym_load", "id", mixed_asym_load_update_id.data() + 1); + // second_scenario_update_data.add_attribute_buffer("asym_load", "status", mixed_asym_load_update_status.data() + + // 1); second_scenario_update_data.add_attribute_buffer("asym_load", "p_specified", + // mixed_asym_load_update_p_specified.data() + 1); + // second_scenario_update_data.add_attribute_buffer("asym_load", "q_specified", + // mixed_asym_load_update_q_specified.data() + 1); + + // // TODO(mgovers): remove + // Serializer serializer{second_scenario_update_data, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const second_scenario_owning_update_dataset = load_dataset(second_scenario_update_json); + auto const& second_scenario_update_data = second_scenario_owning_update_dataset.dataset; for (auto symmetry : {PGM_symmetric, PGM_asymmetric}) { CAPTURE(symmetry); From 4ad1c3f86ce52c8a0880d32d4897ba270eb5c17f Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 10 Dec 2024 09:43:46 +0100 Subject: [PATCH 07/22] more migrations Signed-off-by: Martijn Govers --- .../include/power_grid_model_cpp/dataset.hpp | 10 +++ .../test_api_model_update.cpp | 83 ++----------------- 2 files changed, 15 insertions(+), 78 deletions(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index 8a7f892f0..66ce76bef 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -43,6 +43,16 @@ class DatasetInfo { return handle_.call_with(PGM_dataset_info_total_elements, info_, component_idx); } + Idx component_idx(std::string_view component) const { + Idx const n_comp = n_components(); + for (Idx idx = 0; idx < n_comp; ++idx) { + if (component_name(idx) == component) { + return idx; + } + } + return -1; + } + private: Handle handle_{}; RawDatasetInfo const* info_; diff --git a/tests/native_api_tests/test_api_model_update.cpp b/tests/native_api_tests/test_api_model_update.cpp index 12a1f3d52..3283f82cf 100644 --- a/tests/native_api_tests/test_api_model_update.cpp +++ b/tests/native_api_tests/test_api_model_update.cpp @@ -1071,10 +1071,6 @@ TEST_CASE("API model - Incomplete scenario update followed by complete") { State const complete_state; State const incomplete_state = get_incomplete_state(); - // TODO(mgovers): remove - // auto ref_model = Model{50.0, complete_state.get_input_dataset()}; - // auto test_model = Model{50.0, incomplete_state.get_input_dataset()}; - auto const complete_owning_input_dataset = load_dataset(state_json); auto const incomplete_owning_input_dataset = load_dataset(incomplete_state_json); @@ -1084,83 +1080,14 @@ TEST_CASE("API model - Incomplete scenario update followed by complete") { auto ref_model = Model{50.0, complete_input_data}; auto test_model = Model{50.0, incomplete_input_data}; - constexpr Idx batch_size = 2; - auto const n_nodes = static_cast(complete_state.node_id.size()); - - std::vector mixed_source_update_id{6, 10, 6, 10}; - std::vector mixed_source_update_status{1, 1, 1, 1}; - std::vector mixed_source_update_u_ref{nan, nan, 1.05, 1.05}; - std::vector mixed_source_update_u_ref_angle{nan, nan, nan, 0}; - - std::vector mixed_sym_load_update_id{7, 7}; - std::vector mixed_sym_load_update_status{1, 1}; - std::vector mixed_sym_load_update_p_specified{nan, 0.5e6}; - std::vector mixed_sym_load_update_q_specified{1.0, nan}; - - std::vector mixed_asym_load_update_id{8, 8}; - std::vector mixed_asym_load_update_status{1, 1}; - std::vector mixed_asym_load_update_p_specified{nan, nan, nan, 0.5e6 / 3.0, 0.5e6 / 3.0, 0.5e6 / 3.0}; - std::vector mixed_asym_load_update_q_specified{1.0, 1.0, 1.0, nan, nan, nan}; - - std::vector const source_indptr{0, 0, static_cast(mixed_source_update_id.size())}; - - REQUIRE(source_indptr.size() == batch_size + 1); - - // DatasetConst mixed_update_data{"update", true, batch_size}; - - // mixed_update_data.add_buffer("source", 2, 4, nullptr, nullptr); - // mixed_update_data.add_attribute_buffer("source", "id", mixed_source_update_id.data()); - // mixed_update_data.add_attribute_buffer("source", "status", mixed_source_update_status.data()); - // mixed_update_data.add_attribute_buffer("source", "u_ref", mixed_source_update_u_ref.data()); - // mixed_update_data.add_attribute_buffer("source", "u_ref_angle", mixed_source_update_u_ref_angle.data()); - - // mixed_update_data.add_buffer("sym_load", 1, 2, nullptr, nullptr); - // mixed_update_data.add_attribute_buffer("sym_load", "id", mixed_sym_load_update_id.data()); - // mixed_update_data.add_attribute_buffer("sym_load", "status", mixed_sym_load_update_status.data()); - // mixed_update_data.add_attribute_buffer("sym_load", "p_specified", mixed_sym_load_update_p_specified.data()); - // mixed_update_data.add_attribute_buffer("sym_load", "q_specified", mixed_sym_load_update_q_specified.data()); - - // mixed_update_data.add_buffer("asym_load", 1, 2, nullptr, nullptr); - // mixed_update_data.add_attribute_buffer("asym_load", "id", mixed_asym_load_update_id.data()); - // mixed_update_data.add_attribute_buffer("asym_load", "status", mixed_asym_load_update_status.data()); - // mixed_update_data.add_attribute_buffer("asym_load", "p_specified", mixed_asym_load_update_p_specified.data()); - // mixed_update_data.add_attribute_buffer("asym_load", "q_specified", mixed_asym_load_update_q_specified.data()); - - // // TODO(mgovers): remove - // Serializer serializer{mixed_update_data, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); + auto const& input_info = complete_input_data.get_info(); + auto const n_nodes = input_info.component_elements_per_scenario(input_info.component_idx("node")); + REQUIRE(n_nodes == 3); auto const mixed_owning_update_dataset = load_dataset(mixed_update_json); auto const& mixed_update_data = mixed_owning_update_dataset.dataset; - - // DatasetConst second_scenario_update_data{"update", true, 1}; - - // second_scenario_update_data.add_buffer("source", 2, 2, nullptr, nullptr); - // second_scenario_update_data.add_attribute_buffer("source", "id", mixed_source_update_id.data() + 2); - // second_scenario_update_data.add_attribute_buffer("source", "status", mixed_source_update_status.data() + 2); - // second_scenario_update_data.add_attribute_buffer("source", "u_ref", mixed_source_update_u_ref.data() + 2); - // second_scenario_update_data.add_attribute_buffer("source", "u_ref_angle", - // mixed_source_update_u_ref_angle.data() + 2); - - // second_scenario_update_data.add_buffer("sym_load", 1, 1, nullptr, nullptr); - // second_scenario_update_data.add_attribute_buffer("sym_load", "id", mixed_sym_load_update_id.data() + 1); - // second_scenario_update_data.add_attribute_buffer("sym_load", "status", mixed_sym_load_update_status.data() + 1); - // second_scenario_update_data.add_attribute_buffer("sym_load", "p_specified", - // mixed_sym_load_update_p_specified.data() + 1); - // second_scenario_update_data.add_attribute_buffer("sym_load", "q_specified", - // mixed_sym_load_update_q_specified.data() + 1); - - // second_scenario_update_data.add_buffer("asym_load", 1, 1, nullptr, nullptr); - // second_scenario_update_data.add_attribute_buffer("asym_load", "id", mixed_asym_load_update_id.data() + 1); - // second_scenario_update_data.add_attribute_buffer("asym_load", "status", mixed_asym_load_update_status.data() + - // 1); second_scenario_update_data.add_attribute_buffer("asym_load", "p_specified", - // mixed_asym_load_update_p_specified.data() + 1); - // second_scenario_update_data.add_attribute_buffer("asym_load", "q_specified", - // mixed_asym_load_update_q_specified.data() + 1); - - // // TODO(mgovers): remove - // Serializer serializer{second_scenario_update_data, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); + auto const batch_size = mixed_update_data.get_info().batch_size(); + REQUIRE(batch_size == 2); auto const second_scenario_owning_update_dataset = load_dataset(second_scenario_update_json); auto const& second_scenario_update_data = second_scenario_owning_update_dataset.dataset; From 0ccb71fc55ccb51b688ee232a74c19f85478317e Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Tue, 10 Dec 2024 09:55:42 +0100 Subject: [PATCH 08/22] cleanup Signed-off-by: Martijn Govers --- .../test_api_model_update.cpp | 294 +----------------- 1 file changed, 11 insertions(+), 283 deletions(-) diff --git a/tests/native_api_tests/test_api_model_update.cpp b/tests/native_api_tests/test_api_model_update.cpp index 3283f82cf..e9b2391ff 100644 --- a/tests/native_api_tests/test_api_model_update.cpp +++ b/tests/native_api_tests/test_api_model_update.cpp @@ -381,133 +381,10 @@ auto const update_vector_json = R"json({ } ] })json"s; - -struct State { - std::vector node_id{1, 2, 3}; - std::vector node_u_rated{10e3, 10e3, 10e3}; - - std::vector line_id{4}; - std::vector line_from_node{1}; - std::vector line_to_node{2}; - std::vector line_from_status{1}; - std::vector line_to_status{1}; - std::vector line_r1{10.0}; - std::vector line_x1{0.0}; - std::vector line_c1{0.0}; - std::vector line_tan1{0.0}; - std::vector line_r0{10.0}; - std::vector line_x0{0.0}; - std::vector line_c0{0.0}; - std::vector line_tan0{0.0}; - std::vector line_i_n{1e3}; - - std::vector link_id{5}; - std::vector link_from_node{2}; - std::vector link_to_node{3}; - std::vector link_from_status{1}; - std::vector link_to_status{1}; - - std::vector source_id{6, 10}; - std::vector source_node{1, 3}; - std::vector source_status{1, 0}; - std::vector source_u_ref{1.05, 1.05}; - std::vector source_u_ref_angle{nan, 0.0}; - std::vector source_sk{1e12, 1e12}; - - std::vector sym_load_id{7}; - std::vector sym_load_node{3}; - std::vector sym_load_status{1}; - std::vector sym_load_type{LoadGenType::const_y}; - std::vector sym_load_p_specified{0.5e6}; - std::vector sym_load_q_specified{0.0}; - - std::vector asym_load_id{8}; - std::vector asym_load_node{3}; - std::vector asym_load_status{1}; - std::vector asym_load_type{LoadGenType::const_y}; - std::vector asym_load_p_specified{0.5e6 / 3.0, 0.5e6 / 3.0, 0.5e6 / 3.0}; - std::vector asym_load_q_specified{0.0, 0.0, 0.0}; - - std::vector shunt_id{9}; - std::vector shunt_node{3}; - std::vector shunt_status{1}; - std::vector shunt_g1{0.015}; - std::vector shunt_b1{0.0}; - std::vector shunt_g0{0.015}; - std::vector shunt_b0{0.0}; - - auto get_input_dataset() const { - DatasetConst result{"input", false, 1}; - - result.add_buffer("node", std::ssize(node_id), std::ssize(node_id), nullptr, nullptr); - result.add_attribute_buffer("node", "id", node_id.data()); - result.add_attribute_buffer("node", "u_rated", node_u_rated.data()); - - result.add_buffer("line", std::ssize(line_id), std::ssize(line_id), nullptr, nullptr); - result.add_attribute_buffer("line", "id", line_id.data()); - result.add_attribute_buffer("line", "from_node", line_from_node.data()); - result.add_attribute_buffer("line", "to_node", line_to_node.data()); - result.add_attribute_buffer("line", "from_status", line_from_status.data()); - result.add_attribute_buffer("line", "to_status", line_to_status.data()); - result.add_attribute_buffer("line", "r1", line_r1.data()); - result.add_attribute_buffer("line", "x1", line_x1.data()); - result.add_attribute_buffer("line", "c1", line_c1.data()); - result.add_attribute_buffer("line", "tan1", line_tan1.data()); - result.add_attribute_buffer("line", "r0", line_r0.data()); - result.add_attribute_buffer("line", "x0", line_x0.data()); - result.add_attribute_buffer("line", "c0", line_c0.data()); - result.add_attribute_buffer("line", "tan0", line_tan0.data()); - result.add_attribute_buffer("line", "i_n", line_i_n.data()); - - result.add_buffer("link", std::ssize(link_id), std::ssize(link_id), nullptr, nullptr); - result.add_attribute_buffer("link", "id", link_id.data()); - result.add_attribute_buffer("link", "from_node", link_from_node.data()); - result.add_attribute_buffer("link", "to_node", link_to_node.data()); - result.add_attribute_buffer("link", "from_status", link_from_status.data()); - result.add_attribute_buffer("link", "to_status", link_to_status.data()); - - result.add_buffer("source", std::ssize(source_id), std::ssize(source_id), nullptr, nullptr); - result.add_attribute_buffer("source", "id", source_id.data()); - result.add_attribute_buffer("source", "node", source_node.data()); - result.add_attribute_buffer("source", "status", source_status.data()); - result.add_attribute_buffer("source", "u_ref", source_u_ref.data()); - result.add_attribute_buffer("source", "u_ref_angle", source_u_ref_angle.data()); - result.add_attribute_buffer("source", "sk", source_sk.data()); - - result.add_buffer("sym_load", std::ssize(sym_load_id), std::ssize(sym_load_id), nullptr, nullptr); - result.add_attribute_buffer("sym_load", "id", sym_load_id.data()); - result.add_attribute_buffer("sym_load", "node", sym_load_node.data()); - result.add_attribute_buffer("sym_load", "status", sym_load_status.data()); - result.add_attribute_buffer("sym_load", "type", sym_load_type.data()); - result.add_attribute_buffer("sym_load", "p_specified", sym_load_p_specified.data()); - result.add_attribute_buffer("sym_load", "q_specified", sym_load_q_specified.data()); - - result.add_buffer("asym_load", std::ssize(asym_load_id), std::ssize(asym_load_id), nullptr, nullptr); - result.add_attribute_buffer("asym_load", "id", asym_load_id.data()); - result.add_attribute_buffer("asym_load", "node", asym_load_node.data()); - result.add_attribute_buffer("asym_load", "status", asym_load_status.data()); - result.add_attribute_buffer("asym_load", "type", asym_load_type.data()); - result.add_attribute_buffer("asym_load", "p_specified", asym_load_p_specified.data()); - result.add_attribute_buffer("asym_load", "q_specified", asym_load_q_specified.data()); - - result.add_buffer("shunt", std::ssize(shunt_id), std::ssize(shunt_id), nullptr, nullptr); - result.add_attribute_buffer("shunt", "id", shunt_id.data()); - result.add_attribute_buffer("shunt", "node", shunt_node.data()); - result.add_attribute_buffer("shunt", "status", shunt_status.data()); - result.add_attribute_buffer("shunt", "g1", shunt_g1.data()); - result.add_attribute_buffer("shunt", "b1", shunt_b1.data()); - result.add_attribute_buffer("shunt", "g0", shunt_g0.data()); - result.add_attribute_buffer("shunt", "b0", shunt_b0.data()); - - return result; - } -}; } // namespace TEST_CASE("API model - all updates") { // TODO(mgovers): remove - // State const state; - // auto const input_dataset = state.get_input_dataset(); // Serializer serializer{state.get_input_dataset(), PGM_json}; // auto const str = serializer.get_to_zero_terminated_string(0, 2); @@ -517,59 +394,6 @@ TEST_CASE("API model - all updates") { auto const& input_info = input_dataset.get_info(); auto model = Model{50.0, input_dataset}; - // // update vector - // std::vector sym_load_update_id{7}; - // std::vector sym_load_update_status{1}; - // std::vector sym_load_update_p_specified{2.5e6}; - - // std::vector asym_load_update_id{8}; - // std::vector asym_load_update_status{0}; - - // std::vector shunt_update_id{9}; - // std::vector shunt_update_status{0}; - // std::vector shunt_update_b1{0.02}; - // std::vector shunt_update_b0{0.02}; - - // // used for test case alternate compute mode - // std::vector const shunt_update_2_id{6}; - // std::vector const source_update_2_status{0}; - // std::vector const shunt_update_2_b1{0.01}; - // std::vector const shunt_update_2_b0{0.01}; - - // std::vector source_update_id{10}; - // std::vector source_update_status{1}; - // std::vector source_update_u_ref{test::u1}; - - // std::vector link_update_id{5}; - // std::vector link_update_from_status{1}; - // std::vector link_update_to_status{0}; - - // DatasetConst update_data{"update", true, 1}; - // update_data.add_buffer("sym_load", 1, 1, nullptr, nullptr); - // update_data.add_attribute_buffer("sym_load", "id", sym_load_update_id.data()); - // update_data.add_attribute_buffer("sym_load", "status", sym_load_update_status.data()); - // update_data.add_attribute_buffer("sym_load", "p_specified", sym_load_update_p_specified.data()); - - // update_data.add_buffer("asym_load", 1, 1, nullptr, nullptr); - // update_data.add_attribute_buffer("asym_load", "id", asym_load_update_id.data()); - // update_data.add_attribute_buffer("asym_load", "status", asym_load_update_status.data()); - - // update_data.add_buffer("shunt", 1, 1, nullptr, nullptr); - // update_data.add_attribute_buffer("shunt", "id", shunt_update_id.data()); - // update_data.add_attribute_buffer("shunt", "status", shunt_update_status.data()); - // update_data.add_attribute_buffer("shunt", "b1", shunt_update_b1.data()); - // update_data.add_attribute_buffer("shunt", "b0", shunt_update_b0.data()); - - // update_data.add_buffer("source", 1, 1, nullptr, nullptr); - // update_data.add_attribute_buffer("source", "id", source_update_id.data()); - // update_data.add_attribute_buffer("source", "status", source_update_status.data()); - // update_data.add_attribute_buffer("source", "u_ref", source_update_u_ref.data()); - - // update_data.add_buffer("link", 1, 1, nullptr, nullptr); - // update_data.add_attribute_buffer("link", "id", link_update_id.data()); - // update_data.add_attribute_buffer("link", "from_status", link_update_from_status.data()); - // update_data.add_attribute_buffer("link", "to_status", link_update_to_status.data()); - // TODO(mgovers): remove // Serializer serializer{update_data, PGM_json}; // auto const str = serializer.get_to_zero_terminated_string(0, 2); @@ -709,39 +533,6 @@ TEST_CASE("API model - updates w/ alternating compute mode") { CHECK(asym_shunt_output_i[2] == doctest::Approx(0.0)); }; - // // update vector - // std::vector sym_load_update_id{7}; - // std::vector sym_load_update_status{1}; - // std::vector sym_load_update_p_specified{2.5e6}; - - // std::vector asym_load_update_id{8}; - // std::vector asym_load_update_status{0}; - - // std::vector shunt_update_id{9}; - // std::vector shunt_update_status{0}; - // std::vector shunt_update_b1{0.02}; - // std::vector shunt_update_b0{0.02}; - - // DatasetConst update_data{"update", true, 1}; - // update_data.add_buffer("sym_load", 1, 1, nullptr, nullptr); - // update_data.add_attribute_buffer("sym_load", "id", sym_load_update_id.data()); - // update_data.add_attribute_buffer("sym_load", "status", sym_load_update_status.data()); - // update_data.add_attribute_buffer("sym_load", "p_specified", sym_load_update_p_specified.data()); - - // update_data.add_buffer("asym_load", 1, 1, nullptr, nullptr); - // update_data.add_attribute_buffer("asym_load", "id", asym_load_update_id.data()); - // update_data.add_attribute_buffer("asym_load", "status", asym_load_update_status.data()); - - // update_data.add_buffer("shunt", 1, 1, nullptr, nullptr); - // update_data.add_attribute_buffer("shunt", "id", shunt_update_id.data()); - // update_data.add_attribute_buffer("shunt", "status", shunt_update_status.data()); - // update_data.add_attribute_buffer("shunt", "b1", shunt_update_b1.data()); - // update_data.add_attribute_buffer("shunt", "b0", shunt_update_b0.data()); - - // // TODO(mgovers): remove - // Serializer serializer{update_data, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - auto const owning_update_dataset = load_dataset(update_vector_json); auto const& update_data = owning_update_dataset.dataset; @@ -838,32 +629,18 @@ auto const complete_update_json = R"json({ } ] })json"s; - -auto get_incomplete_state() -> State { - State result; - - std::ranges::fill(result.source_u_ref, nan); - std::ranges::fill(result.source_u_ref_angle, nan); - std::ranges::fill(result.sym_load_p_specified, nan); - std::ranges::fill(result.asym_load_p_specified, nan); - - return result; -} } // namespace TEST_CASE("API model - incomplete input") { - State const complete_state; // TODO(mgovers): also migrate - // State const incomplete_state = get_incomplete_state(); - - auto const owning_input_dataset = load_dataset(incomplete_state_json); - auto const& incomplete_input_data = owning_input_dataset.dataset; + auto const complete_owning_input_dataset = load_dataset(state_json); + auto const& complete_input_data = complete_owning_input_dataset.dataset; - // // TODO(mgovers): remove - // Serializer serializer{update_data, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); + auto const incomplete_owning_input_dataset = load_dataset(incomplete_state_json); + auto const& incomplete_input_data = incomplete_owning_input_dataset.dataset; - // auto const owning_update_dataset = load_dataset(update_vector_json); - // auto const& update_data = owning_update_dataset.dataset; + auto const& input_info = complete_input_data.get_info(); + auto const n_nodes = input_info.component_elements_per_scenario(input_info.component_idx("node")); + REQUIRE(n_nodes == 3); auto test_model = Model{50.0, incomplete_input_data}; @@ -876,7 +653,7 @@ TEST_CASE("API model - incomplete input") { SUBCASE(calculation_symmetry.c_str()) { auto const* node_output_meta = MetaData::get_component_by_name(output_type, "node"); - Buffer test_node_output(node_output_meta, std::ssize(complete_state.node_id)); + Buffer test_node_output(node_output_meta, n_nodes); DatasetMutable test_result_data{output_type, true, 1}; test_result_data.add_buffer("node", test_node_output.size(), test_node_output.size(), nullptr, test_node_output); @@ -902,29 +679,6 @@ TEST_CASE("API model - incomplete input") { } } SUBCASE("Incomplete update dataset") { - // DatasetConst incomplete_update_data{"update", true, 1}; - // incomplete_update_data.add_buffer("source", std::ssize(incomplete_state.source_id), - // std::ssize(incomplete_state.source_id), nullptr, nullptr); - // incomplete_update_data.add_attribute_buffer("source", "id", incomplete_state.source_id.data()); - // incomplete_update_data.add_attribute_buffer("source", "u_ref", incomplete_state.source_u_ref.data()); - // incomplete_update_data.add_attribute_buffer("source", "u_ref_angle", - // incomplete_state.source_u_ref_angle.data()); - - // incomplete_update_data.add_buffer("sym_load", std::ssize(incomplete_state.sym_load_id), - // std::ssize(incomplete_state.sym_load_id), nullptr, nullptr); - // incomplete_update_data.add_attribute_buffer("sym_load", "id", incomplete_state.sym_load_id.data()); - // incomplete_update_data.add_attribute_buffer("sym_load", "p_specified", - // incomplete_state.sym_load_p_specified.data()); - - // incomplete_update_data.add_buffer("asym_load", std::ssize(incomplete_state.asym_load_id), - // std::ssize(incomplete_state.asym_load_id), nullptr, nullptr); - // incomplete_update_data.add_attribute_buffer("asym_load", "id", incomplete_state.asym_load_id.data()); - // incomplete_update_data.add_attribute_buffer("asym_load", "p_specified", - // incomplete_state.asym_load_p_specified.data()); - // // TODO(mgovers): remove - // Serializer serializer{incomplete_update_data, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - auto const owning_update_dataset = load_dataset(incomplete_update_json); auto const& incomplete_update_data = owning_update_dataset.dataset; @@ -941,34 +695,11 @@ TEST_CASE("API model - incomplete input") { } } SUBCASE("Complete update dataset") { - // DatasetConst complete_update_data{"update", true, 1}; - // complete_update_data.add_buffer("source", std::ssize(complete_state.source_id), - // std::ssize(complete_state.source_id), nullptr, nullptr); - // complete_update_data.add_attribute_buffer("source", "id", complete_state.source_id.data()); - // complete_update_data.add_attribute_buffer("source", "u_ref", complete_state.source_u_ref.data()); - // complete_update_data.add_attribute_buffer("source", "u_ref_angle", - // complete_state.source_u_ref_angle.data()); - - // complete_update_data.add_buffer("sym_load", std::ssize(complete_state.sym_load_id), - // std::ssize(complete_state.sym_load_id), nullptr, nullptr); - // complete_update_data.add_attribute_buffer("sym_load", "id", complete_state.sym_load_id.data()); - // complete_update_data.add_attribute_buffer("sym_load", "p_specified", - // complete_state.sym_load_p_specified.data()); - - // complete_update_data.add_buffer("asym_load", std::ssize(complete_state.asym_load_id), - // std::ssize(complete_state.asym_load_id), nullptr, nullptr); - // complete_update_data.add_attribute_buffer("asym_load", "id", complete_state.asym_load_id.data()); - // complete_update_data.add_attribute_buffer("asym_load", "p_specified", - // complete_state.asym_load_p_specified.data()); - // // // TODO(mgovers): remove - // Serializer serializer{complete_update_data, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - auto const owning_update_dataset = load_dataset(complete_update_json); auto const& complete_update_data = owning_update_dataset.dataset; - auto ref_model = Model{50.0, complete_state.get_input_dataset()}; - Buffer ref_node_output(node_output_meta, std::ssize(complete_state.node_id)); + auto ref_model = Model{50.0, complete_input_data}; + Buffer ref_node_output(node_output_meta, n_nodes); DatasetMutable ref_result_data{output_type, true, 1}; ref_result_data.add_buffer("node", ref_node_output.size(), ref_node_output.size(), nullptr, ref_node_output); @@ -985,7 +716,7 @@ TEST_CASE("API model - incomplete input") { complete_update_data)); } - for (Idx node_idx = 0; node_idx < std::ssize(complete_state.node_id); ++node_idx) { + for (Idx node_idx = 0; node_idx < n_nodes; ++node_idx) { CAPTURE(node_idx); for (Idx attr_idx = 0; attr_idx < MetaData::n_attributes(node_output_meta); ++attr_idx) { @@ -1068,9 +799,6 @@ auto const second_scenario_update_json = R"json({ })json"s; TEST_CASE("API model - Incomplete scenario update followed by complete") { - State const complete_state; - State const incomplete_state = get_incomplete_state(); - auto const complete_owning_input_dataset = load_dataset(state_json); auto const incomplete_owning_input_dataset = load_dataset(incomplete_state_json); From 9d53b55d2bb4ecf5612e715ab5759b8f192d0852 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Wed, 11 Dec 2024 09:43:16 +0100 Subject: [PATCH 09/22] migrate input + update data of test API model Signed-off-by: Martijn Govers --- .../include/power_grid_model_cpp/dataset.hpp | 1 + .../power_grid_model_cpp/serialization.hpp | 1 + .../test_math_solver_common.hpp | 6 + tests/cpp_unit_tests/test_math_solver_pf.hpp | 6 + tests/cpp_unit_tests/test_math_solver_se.hpp | 6 + tests/cpp_unit_tests/test_optimizer.hpp | 6 + tests/native_api_tests/load_dataset.hpp | 21 + tests/native_api_tests/test_api_model.cpp | 362 ++++++++++++++---- .../test_api_model_update.cpp | 12 +- 9 files changed, 347 insertions(+), 74 deletions(-) create mode 100644 tests/native_api_tests/load_dataset.hpp diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index 66ce76bef..021c15fbe 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -11,6 +11,7 @@ #include "handle.hpp" #include "power_grid_model_c/dataset.h" + namespace power_grid_model_cpp { class DatasetInfo { diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp index 185c768ec..e8e6ad53b 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp @@ -9,6 +9,7 @@ #include "basics.hpp" #include "dataset.hpp" #include "handle.hpp" +#include "meta_data.hpp" #include "power_grid_model_c/serialization.h" diff --git a/tests/cpp_unit_tests/test_math_solver_common.hpp b/tests/cpp_unit_tests/test_math_solver_common.hpp index 5f07e1bc1..37f027b31 100644 --- a/tests/cpp_unit_tests/test_math_solver_common.hpp +++ b/tests/cpp_unit_tests/test_math_solver_common.hpp @@ -4,6 +4,10 @@ // In this unit test the powerflow solvers are tested +#pragma once +#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_COMMON_HPP +#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_COMMON_HPP + #include #include #include @@ -265,3 +269,5 @@ template struct SteadyStateSolverTestGrid { }; } // namespace power_grid_model + +#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_COMMON_HPP diff --git a/tests/cpp_unit_tests/test_math_solver_pf.hpp b/tests/cpp_unit_tests/test_math_solver_pf.hpp index 1939cff45..ffe927514 100644 --- a/tests/cpp_unit_tests/test_math_solver_pf.hpp +++ b/tests/cpp_unit_tests/test_math_solver_pf.hpp @@ -4,6 +4,10 @@ // In this unit test the powerflow solvers are tested +#pragma once +#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_PF_HPP +#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_PF_HPP + #include "test_math_solver_common.hpp" #include @@ -142,3 +146,5 @@ TEST_CASE_TEMPLATE_DEFINE("Test math solver - PF", SolverType, test_math_solver_ } } // namespace power_grid_model + +#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_PF_HPP diff --git a/tests/cpp_unit_tests/test_math_solver_se.hpp b/tests/cpp_unit_tests/test_math_solver_se.hpp index 93c4f65fe..dfbbceb5a 100644 --- a/tests/cpp_unit_tests/test_math_solver_se.hpp +++ b/tests/cpp_unit_tests/test_math_solver_se.hpp @@ -4,6 +4,10 @@ // In this unit test the powerflow solvers are tested +#pragma once +#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_SE_HPP +#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_SE_HPP + #include "test_math_solver_common.hpp" #include @@ -516,3 +520,5 @@ TEST_CASE_TEMPLATE_DEFINE("Test math solver - SE, measurements", SolverType, tes } } // namespace power_grid_model + +#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_SE_HPP diff --git a/tests/cpp_unit_tests/test_optimizer.hpp b/tests/cpp_unit_tests/test_optimizer.hpp index f640d145e..c941ef8d3 100644 --- a/tests/cpp_unit_tests/test_optimizer.hpp +++ b/tests/cpp_unit_tests/test_optimizer.hpp @@ -2,6 +2,10 @@ // // SPDX-License-Identifier: MPL-2.0 +#pragma once +#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_OPTIMIZER_HPP +#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_OPTIMIZER_HPP + #include #include #include @@ -246,3 +250,5 @@ template <> struct get_attributes_list { }; } // namespace meta_data } // namespace power_grid_model + +#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_OPTIMIZER_HPP diff --git a/tests/native_api_tests/load_dataset.hpp b/tests/native_api_tests/load_dataset.hpp new file mode 100644 index 000000000..e118475a4 --- /dev/null +++ b/tests/native_api_tests/load_dataset.hpp @@ -0,0 +1,21 @@ +// SPDX-FileCopyrightText: Contributors to the Power Grid Model project +// +// SPDX-License-Identifier: MPL-2.0 + +#pragma once +#ifndef POWER_GRID_MODEL_TESTS_NATIVE_API_TESTS_LOAD_DATASET_HPP +#define POWER_GRID_MODEL_TESTS_NATIVE_API_TESTS_LOAD_DATASET_HPP + +#include + +namespace power_grid_model_cpp_test { +inline power_grid_model_cpp::OwningDatasetConst load_dataset(std::string const& json_string) { + power_grid_model_cpp::Deserializer deserializer{json_string, PGM_json}; + auto& writable_dataset = deserializer.get_dataset(); + auto owning_dataset = power_grid_model_cpp::create_owning_dataset(writable_dataset); + deserializer.parse_to_buffer(); + return owning_dataset; +} +} // namespace power_grid_model_cpp_test + +#endif // POWER_GRID_MODEL_TESTS_NATIVE_API_TESTS_LOAD_DATASET_HPP diff --git a/tests/native_api_tests/test_api_model.cpp b/tests/native_api_tests/test_api_model.cpp index 9808715dd..810847f16 100644 --- a/tests/native_api_tests/test_api_model.cpp +++ b/tests/native_api_tests/test_api_model.cpp @@ -2,6 +2,8 @@ // // SPDX-License-Identifier: MPL-2.0 +#include "load_dataset.hpp" + #include "power_grid_model_cpp.hpp" #include @@ -58,6 +60,9 @@ Dataset created with the following buffers: namespace power_grid_model_cpp { namespace { +using namespace std::string_literals; +using power_grid_model_cpp_test::load_dataset; + enum class MeasuredTerminalType : IntS { branch_from = 0, branch_to = 1, @@ -89,6 +94,180 @@ void check_throws_with(Func&& func, PGM_ErrorCode const& reference_error, std::s check_exception(e, reference_error, reference_err_msg); } } + +auto const state_json = R"json({ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "sym_load": [ + {"id": 2, "node": 0, "status": 1, "type": 2, "p_specified": 0, "q_specified": 500} + ], + "source": [ + {"id": 1, "node": 0, "status": 1, "u_ref": 1, "sk": 1000, "rx_ratio": 0} + ], + "node": [ + {"id": 0, "u_rated": 100}, + {"id": 4, "u_rated": 100} + ], + "line": [ + {"id": 5, "from_node": 0, "to_node": 4, "from_status": 0, "to_status": 1}, + {"id": 6, "from_node": 4, "to_node": 0, "from_status": 0, "to_status": 0} + ] + } +})json"s; + +auto const bad_load_id_state_json = R"json({ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "sym_load": [ + {"id": 0, "node": 0, "status": 1, "type": 2, "p_specified": 0, "q_specified": 500} + ], + "source": [ + {"id": 1, "node": 0, "status": 1, "u_ref": 1, "sk": 1000, "rx_ratio": 0} + ], + "node": [ + {"id": 0, "u_rated": 100}, + {"id": 4, "u_rated": 100} + ], + "line": [ + {"id": 5, "from_node": 0, "to_node": 4, "from_status": 0, "to_status": 1}, + {"id": 6, "from_node": 4, "to_node": 0, "from_status": 0, "to_status": 0} + ] + } +})json"s; + +auto const single_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": false, + "attributes": {}, + "data": { + "source": [ + {"id": 1, "u_ref": 0.5} + ], + "sym_load": [ + {"id": 2, "q_specified": 100} + ], + "line": [ + {"id": 5, "from_status": 0, "to_status": 1}, + {"id": 6, "from_status": 0, "to_status": 0} + ] + } +})json"s; + +auto const batch_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "source": [ + {"id": 1, "u_ref": 0.5} + ], + "sym_load": [ + {"id": 2, "q_specified": 100} + ], + "line": [ + {"id": 5, "from_status": 0, "to_status": 1}, + {"id": 6, "from_status": 0, "to_status": 0} + ] + }, + { + "sym_load": [ + {"id": 2, "q_specified": 300} + ], + "line": [ + {"id": 5, "from_status": 0, "to_status": 0}, + {"id": 6, "from_status": 0, "to_status": 0} + ] + } + ] +})json"s; + +auto const bad_source_id_single_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": false, + "attributes": {}, + "data": { + "source": [ + {"id": 99, "u_ref": 0.5} + ], + "sym_load": [ + {"id": 2, "q_specified": 100} + ], + "line": [ + {"id": 5, "from_status": 0, "to_status": 1}, + {"id": 6, "from_status": 0, "to_status": 0} + ] + } +})json"s; + +auto const bad_load_id_batch_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "source": [ + {"id": 1, "u_ref": 0.5} + ], + "sym_load": [ + {"id": 2, "q_specified": 100} + ], + "line": [ + {"id": 99, "from_status": 0, "to_status": 1}, + {"id": 999, "from_status": 0, "to_status": 0} + ] + }, + { + "sym_load": [ + {"id": 2, "q_specified": 300} + ], + "line": [ + {"id": 9999, "from_status": 0, "to_status": 0}, + {"id": 99999, "from_status": 0, "to_status": 0} + ] + } + ] +})json"s; + +auto const bad_line_id_batch_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "source": [ + {"id": 1, "u_ref": 0.5} + ], + "sym_load": [ + {"id": 2, "q_specified": 100} + ], + "line": [ + {"id": 5, "from_status": 0, "to_status": 1}, + {"id": 6, "from_status": 0, "to_status": 0} + ] + }, + { + "sym_load": [ + {"id": 999, "q_specified": 300} + ], + "line": [ + {"id": 5, "from_status": 0, "to_status": 0}, + {"id": 6, "from_status": 0, "to_status": 0} + ] + } + ] +})json"s; } // namespace TEST_CASE("API Model") { @@ -96,9 +275,6 @@ TEST_CASE("API Model") { Options options{}; - // input data - DatasetConst input_dataset{"input", false, 1}; - // node buffer std::vector const node_id{0, 4}; std::vector const node_u_rated{100.0, 100.0}; @@ -146,6 +322,9 @@ TEST_CASE("API Model") { load_buffer.set_value(PGM_def_input_sym_load_p_specified, &load_p_specified, -1); load_buffer.set_value(PGM_def_input_sym_load_q_specified, &load_q_specified, -1); + // input data + DatasetConst input_dataset{"input", false, 1}; + // add buffers - row input_dataset.add_buffer("sym_load", 1, 1, nullptr, load_buffer); input_dataset.add_buffer("source", 1, 1, nullptr, source_buffer); @@ -161,6 +340,13 @@ TEST_CASE("API Model") { input_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); input_dataset.add_attribute_buffer("line", "to_status", line_to_status.data()); + // // TODO(mgovers): remove + // Serializer serializer{input_dataset, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + // auto const owning_input_dataset = load_dataset(state_json); + // auto const& input_dataset = owning_input_dataset.dataset; + // output data Buffer node_output{PGM_def_sym_output_node, 2}; node_output.set_nan(); @@ -182,43 +368,53 @@ TEST_CASE("API Model") { std::vector batch_node_result_u_pu(4); std::vector batch_node_result_u_angle(4); - // update data - ID const source_update_id = 1; - int8_t const source_update_status = std::numeric_limits::min(); - double const source_update_u_ref = 0.5; - double const source_update_u_ref_angle = std::numeric_limits::quiet_NaN(); - Buffer source_update_buffer{PGM_def_update_source, 1}; - source_update_buffer.set_nan(); - source_update_buffer.set_value(PGM_def_update_source_id, &source_update_id, 0, -1); - source_update_buffer.set_value(PGM_def_update_source_status, &source_update_status, 0, -1); - source_update_buffer.set_value(PGM_def_update_source_u_ref, &source_update_u_ref, 0, -1); - source_update_buffer.set_value(PGM_def_update_source_u_ref_angle, &source_update_u_ref_angle, 0, -1); - std::array source_update_indptr{0, 1, 1}; - - std::vector load_updates_id = {2, 2}; - std::vector load_updates_q_specified = {100.0, 300.0}; - Buffer load_updates_buffer{PGM_def_update_sym_load, 2}; - // set nan twice with offset - load_updates_buffer.set_nan(0); - load_updates_buffer.set_nan(1); - load_updates_buffer.set_value(PGM_def_update_sym_load_id, load_updates_id.data(), -1); - load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 0, -1); - load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 1, -1); - // dataset - DatasetConst single_update_dataset{"update", false, 1}; - single_update_dataset.add_buffer("source", 1, 1, nullptr, source_update_buffer); - single_update_dataset.add_buffer("sym_load", 1, 1, nullptr, load_updates_buffer.get()); - single_update_dataset.add_buffer("line", 2, 2, nullptr, nullptr); - single_update_dataset.add_attribute_buffer("line", "id", line_id.data()); - single_update_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); - single_update_dataset.add_attribute_buffer("line", "to_status", line_to_status.data()); - DatasetConst batch_update_dataset{"update", true, 2}; - batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), source_update_buffer.get()); - batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); - batch_update_dataset.add_buffer("line", 2, 4, nullptr, nullptr); - batch_update_dataset.add_attribute_buffer("line", "id", batch_line_id.data()); - batch_update_dataset.add_attribute_buffer("line", "from_status", batch_line_from_status.data()); - batch_update_dataset.add_attribute_buffer("line", "to_status", batch_line_to_status.data()); + // // update data + // ID const source_update_id = 1; + // int8_t const source_update_status = std::numeric_limits::min(); + // double const source_update_u_ref = 0.5; + // double const source_update_u_ref_angle = std::numeric_limits::quiet_NaN(); + // Buffer source_update_buffer{PGM_def_update_source, 1}; + // source_update_buffer.set_nan(); + // source_update_buffer.set_value(PGM_def_update_source_id, &source_update_id, 0, -1); + // source_update_buffer.set_value(PGM_def_update_source_status, &source_update_status, 0, -1); + // source_update_buffer.set_value(PGM_def_update_source_u_ref, &source_update_u_ref, 0, -1); + // source_update_buffer.set_value(PGM_def_update_source_u_ref_angle, &source_update_u_ref_angle, 0, -1); + // std::array source_update_indptr{0, 1, 1}; + + // std::vector load_updates_id = {2, 2}; + // std::vector load_updates_q_specified = {100.0, 300.0}; + // Buffer load_updates_buffer{PGM_def_update_sym_load, 2}; + // // set nan twice with offset + // load_updates_buffer.set_nan(0); + // load_updates_buffer.set_nan(1); + // load_updates_buffer.set_value(PGM_def_update_sym_load_id, load_updates_id.data(), -1); + // load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 0, -1); + // load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 1, -1); + // // dataset + // DatasetConst single_update_dataset{"update", false, 1}; + // single_update_dataset.add_buffer("source", 1, 1, nullptr, source_update_buffer); + // single_update_dataset.add_buffer("sym_load", 1, 1, nullptr, load_updates_buffer.get()); + // single_update_dataset.add_buffer("line", 2, 2, nullptr, nullptr); + // single_update_dataset.add_attribute_buffer("line", "id", line_id.data()); + // single_update_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); + // single_update_dataset.add_attribute_buffer("line", "to_status", line_to_status.data()); + // DatasetConst batch_update_dataset{"update", true, 2}; + // batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), source_update_buffer.get()); + // batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); + // batch_update_dataset.add_buffer("line", 2, 4, nullptr, nullptr); + // batch_update_dataset.add_attribute_buffer("line", "id", batch_line_id.data()); + // batch_update_dataset.add_attribute_buffer("line", "from_status", batch_line_from_status.data()); + // batch_update_dataset.add_attribute_buffer("line", "to_status", batch_line_to_status.data()); + + // // TODO(mgovers): remove + // Serializer serializer{batch_update_dataset, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const single_owning_update_dataset = load_dataset(single_update_json); + auto const& single_update_dataset = single_owning_update_dataset.dataset; + + auto const batch_owning_update_dataset = load_dataset(batch_update_json); + auto const& batch_update_dataset = batch_owning_update_dataset.dataset; // create model Model model{50.0, input_dataset}; @@ -343,21 +539,42 @@ TEST_CASE("API Model") { SUBCASE("Input error handling") { SUBCASE("Construction error") { - ID const bad_load_id = 0; - ID const good_source_update_id = 1; - load_buffer.set_value(PGM_def_input_sym_load_id, &bad_load_id, -1); - source_update_buffer.set_value(PGM_def_update_source_id, &good_source_update_id, 0, -1); + // ID const bad_load_id = 0; + // ID const good_source_update_id = 1; + // load_buffer.set_value(PGM_def_input_sym_load_id, &bad_load_id, -1); + // source_update_buffer.set_value(PGM_def_update_source_id, &good_source_update_id, 0, -1); + + // // TODO(mgovers): remove + // Serializer serializer{input_dataset, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); - auto const wrong_model_lambda = [&input_dataset]() { Model const wrong_model{50.0, input_dataset}; }; + auto const bad_owning_input_dataset = load_dataset(bad_load_id_state_json); + auto const& bad_input_dataset = bad_owning_input_dataset.dataset; - check_throws_with(wrong_model_lambda, PGM_regular_error, "Conflicting id detected:"s); + auto const bad_model_lambda = [&bad_input_dataset]() { Model const wrong_model{50.0, bad_input_dataset}; }; + + check_throws_with(bad_model_lambda, PGM_regular_error, "Conflicting id detected:"s); } SUBCASE("Update error") { - ID const good_load_id = 2; - ID const bad_source_update_id = 99; - load_buffer.set_value(PGM_def_input_sym_load_id, &good_load_id, -1); - source_update_buffer.set_value(PGM_def_update_source_id, &bad_source_update_id, 0, -1); + // ID const good_load_id = 2; + // ID const bad_source_update_id = 99; + // load_buffer.set_value(PGM_def_input_sym_load_id, &good_load_id, -1); + // source_update_buffer.set_value(PGM_def_update_source_id, &bad_source_update_id, 0, -1); + + // // TODO(mgovers): remove + // Serializer serializer{input_dataset, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + // auto const owning_input_dataset = load_dataset(bad_source_update_load_id_state_json); + // auto const& input_dataset = owning_input_dataset.dataset; + + // // TODO(mgovers): remove + // Serializer serializer{single_update_dataset, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const bad_single_owning_update_dataset = load_dataset(bad_source_id_single_update_json); + auto const& single_update_dataset = bad_single_owning_update_dataset.dataset; auto const bad_update_lambda = [&model, &single_update_dataset]() { model.update(single_update_dataset); }; @@ -365,17 +582,24 @@ TEST_CASE("API Model") { } SUBCASE("Update error in calculation") { - ID const bad_load_id = 2; - load_buffer.set_value(PGM_def_input_sym_load_id, &bad_load_id, -1); - DatasetConst bad_batch_update_dataset{"update", true, 2}; - bad_batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), - source_update_buffer.get()); - bad_batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); - bad_batch_update_dataset.add_buffer("line", 2, 4, nullptr, nullptr); // columnar input for line - std::vector const bad_batch_line_id{99, 999, 9999, 99999}; - bad_batch_update_dataset.add_attribute_buffer("line", "id", bad_batch_line_id.data()); - bad_batch_update_dataset.add_attribute_buffer("line", "from_status", batch_line_from_status.data()); - bad_batch_update_dataset.add_attribute_buffer("line", "to_status", batch_line_to_status.data()); + // ID const bad_load_id = 2; + // load_buffer.set_value(PGM_def_input_sym_load_id, &bad_load_id, -1); + // DatasetConst bad_batch_update_dataset{"update", true, 2}; + // bad_batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), + // source_update_buffer.get()); + // bad_batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); + // bad_batch_update_dataset.add_buffer("line", 2, 4, nullptr, nullptr); // columnar input for line + // std::vector const bad_batch_line_id{99, 999, 9999, 99999}; + // bad_batch_update_dataset.add_attribute_buffer("line", "id", bad_batch_line_id.data()); + // bad_batch_update_dataset.add_attribute_buffer("line", "from_status", batch_line_from_status.data()); + // bad_batch_update_dataset.add_attribute_buffer("line", "to_status", batch_line_to_status.data()); + + // // TODO(mgovers): remove + // Serializer serializer{bad_batch_update_dataset, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const bad_batch_owning_update_dataset = load_dataset(bad_load_id_batch_update_json); + auto const& bad_batch_update_dataset = bad_batch_owning_update_dataset.dataset; auto const bad_calc_with_update_lambda = [&model, &options, &batch_output_dataset, &bad_batch_update_dataset]() { @@ -427,10 +651,18 @@ TEST_CASE("API Model") { SUBCASE("Batch calculation error") { SUBCASE("Line bad line id") { - // wrong id - load_updates_id[1] = 999; - load_updates_buffer.set_value(PGM_def_update_sym_load_id, load_updates_id.data(), 1, -1); - // failed in batch 1 + // // wrong id + // load_updates_id[1] = 999; + // load_updates_buffer.set_value(PGM_def_update_sym_load_id, load_updates_id.data(), 1, -1); + + // // TODO(mgovers): remove + // Serializer serializer{batch_update_dataset, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + + auto const bad_batch_owning_update_dataset = load_dataset(bad_line_id_batch_update_json); + auto const& batch_update_dataset = bad_batch_owning_update_dataset.dataset; + + // failed in batch scenario 1 try { model.calculate(options, batch_output_dataset, batch_update_dataset); FAIL("Expected batch calculation error not thrown."); diff --git a/tests/native_api_tests/test_api_model_update.cpp b/tests/native_api_tests/test_api_model_update.cpp index e9b2391ff..0835502f3 100644 --- a/tests/native_api_tests/test_api_model_update.cpp +++ b/tests/native_api_tests/test_api_model_update.cpp @@ -2,10 +2,11 @@ // // SPDX-License-Identifier: MPL-2.0 +#include "load_dataset.hpp" + #include #include #include -#include #include #include @@ -83,6 +84,7 @@ TYPE_TO_STRING_AS("row_t, columnar_t, dense_t, invalid_id_t", TypeCombo); namespace power_grid_model_cpp { +using power_grid_model_cpp_test::load_dataset; /* @@ -286,14 +288,6 @@ Options get_default_options(PGM_SymmetryType calculation_symmetry, PGM_Calculati return opt; } -OwningDatasetConst load_dataset(std::string const& json_string) { - Deserializer deserializer{json_string, PGM_json}; - auto& writable_dataset = deserializer.get_dataset(); - auto owning_dataset = create_owning_dataset(writable_dataset); - deserializer.parse_to_buffer(); - return owning_dataset; -} - namespace test { constexpr double z_bus_2 = 1.0 / (0.015 + 0.5e6 / 10e3 / 10e3 * 2); constexpr double z_total = z_bus_2 + 10.0; From 5ab23205c96c624b1353abbae55064a40140ce94 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Wed, 11 Dec 2024 10:14:34 +0100 Subject: [PATCH 10/22] migrate some more test api model functions Signed-off-by: Martijn Govers --- tests/native_api_tests/test_api_model.cpp | 187 ++++++++++++++++------ 1 file changed, 137 insertions(+), 50 deletions(-) diff --git a/tests/native_api_tests/test_api_model.cpp b/tests/native_api_tests/test_api_model.cpp index 810847f16..2818b50c2 100644 --- a/tests/native_api_tests/test_api_model.cpp +++ b/tests/native_api_tests/test_api_model.cpp @@ -1047,52 +1047,102 @@ TEST_CASE("API Model") { } SUBCASE("Forbid link power measurements") { - // input data - DatasetConst input_dataset_se{"input", false, 1}; - auto const construct_model = [&input_dataset_se] { return Model{50.0, input_dataset_se}; }; + // // input data + // DatasetConst input_dataset_se{"input", false, 1}; + // auto const construct_model = [&input_dataset_se] { return Model{50.0, input_dataset_se}; }; - // node buffer - std::vector const node_id_se{1, 2}; - std::vector const node_u_rated_se{10000.0, 10000.0}; + // // node buffer + // std::vector const node_id_se{1, 2}; + // std::vector const node_u_rated_se{10000.0, 10000.0}; - // link buffer - std::vector const link_id_se{3}; - std::vector const link_from_node_se{1}; - std::vector const link_to_node_se{2}; + // // link buffer + // std::vector const link_id_se{3}; + // std::vector const link_from_node_se{1}; + // std::vector const link_to_node_se{2}; - // power sensor - std::vector const power_sensor_id_se{4}; - std::vector const power_sensor_measured_object_se{3}; - std::vector const power_sensor_measured_terminal_type_se{0}; + // // power sensor + // std::vector const power_sensor_id_se{4}; + // std::vector const power_sensor_measured_object_se{3}; + // std::vector const power_sensor_measured_terminal_type_se{0}; - input_dataset_se.add_buffer("node", 2, 2, nullptr, nullptr); - input_dataset_se.add_attribute_buffer("node", "id", node_id_se.data()); - input_dataset_se.add_attribute_buffer("node", "u_rated", node_u_rated_se.data()); + // input_dataset_se.add_buffer("node", 2, 2, nullptr, nullptr); + // input_dataset_se.add_attribute_buffer("node", "id", node_id_se.data()); + // input_dataset_se.add_attribute_buffer("node", "u_rated", node_u_rated_se.data()); - input_dataset_se.add_buffer("link", 1, 1, nullptr, nullptr); - input_dataset_se.add_attribute_buffer("link", "id", link_id_se.data()); - input_dataset_se.add_attribute_buffer("link", "from_node", link_from_node_se.data()); - input_dataset_se.add_attribute_buffer("link", "to_node", link_to_node_se.data()); + // input_dataset_se.add_buffer("link", 1, 1, nullptr, nullptr); + // input_dataset_se.add_attribute_buffer("link", "id", link_id_se.data()); + // input_dataset_se.add_attribute_buffer("link", "from_node", link_from_node_se.data()); + // input_dataset_se.add_attribute_buffer("link", "to_node", link_to_node_se.data()); SUBCASE("SymPowerSensor") { - input_dataset_se.add_buffer("sym_power_sensor", 1, 1, nullptr, nullptr); - input_dataset_se.add_attribute_buffer("sym_power_sensor", "id", power_sensor_id_se.data()); - input_dataset_se.add_attribute_buffer("sym_power_sensor", "measured_object", - power_sensor_measured_object_se.data()); - input_dataset_se.add_attribute_buffer("sym_power_sensor", "measured_terminal_type", - power_sensor_measured_terminal_type_se.data()); + // input_dataset_se.add_buffer("sym_power_sensor", 1, 1, nullptr, nullptr); + // input_dataset_se.add_attribute_buffer("sym_power_sensor", "id", power_sensor_id_se.data()); + // input_dataset_se.add_attribute_buffer("sym_power_sensor", "measured_object", + // power_sensor_measured_object_se.data()); + // input_dataset_se.add_attribute_buffer("sym_power_sensor", "measured_terminal_type", + // power_sensor_measured_terminal_type_se.data()); + + // // TODO(mgovers): remove + // Serializer serializer{input_dataset_se, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + auto const input_data_se_json = R"json({ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 1, "u_rated": 10000}, + {"id": 2, "u_rated": 10000} + ], + "link": [ + {"id": 3, "from_node": 1, "to_node": 2} + ], + "sym_power_sensor": [ + {"id": 4, "measured_object": 3, "measured_terminal_type": 0} + ] + } +})json"s; + + auto const owning_input_dataset_se = load_dataset(input_data_se_json); + auto const& input_dataset_se = owning_input_dataset_se.dataset; + + auto const construct_model = [&input_dataset_se] { return Model{50.0, input_dataset_se}; }; CHECK_THROWS_WITH_AS(construct_model(), "PowerSensor measurement is not supported for object of type Link", PowerGridRegularError); } SUBCASE("AsymPowerSensor") { - input_dataset_se.add_buffer("asym_power_sensor", 2, 2, nullptr, nullptr); - input_dataset_se.add_attribute_buffer("asym_power_sensor", "id", power_sensor_id_se.data()); - input_dataset_se.add_attribute_buffer("asym_power_sensor", "measured_object", - power_sensor_measured_object_se.data()); - input_dataset_se.add_attribute_buffer("asym_power_sensor", "measured_terminal_type", - power_sensor_measured_terminal_type_se.data()); + // input_dataset_se.add_buffer("asym_power_sensor", 2, 2, nullptr, nullptr); + // input_dataset_se.add_attribute_buffer("asym_power_sensor", "id", power_sensor_id_se.data()); + // input_dataset_se.add_attribute_buffer("asym_power_sensor", "measured_object", + // power_sensor_measured_object_se.data()); + // input_dataset_se.add_attribute_buffer("asym_power_sensor", "measured_terminal_type", + // power_sensor_measured_terminal_type_se.data()); + auto const input_data_se_json = R"json({ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 1, "u_rated": 10000}, + {"id": 2, "u_rated": 10000} + ], + "link": [ + {"id": 3, "from_node": 1, "to_node": 2} + ], + "asym_power_sensor": [ + {"id": 4, "measured_object": 3, "measured_terminal_type": 0} + ] + } +})json"s; + + auto const owning_input_dataset_se = load_dataset(input_data_se_json); + auto const& input_dataset_se = owning_input_dataset_se.dataset; + + auto const construct_model = [&input_dataset_se] { return Model{50.0, input_dataset_se}; }; CHECK_THROWS_WITH_AS(construct_model(), "PowerSensor measurement is not supported for object of type Link", PowerGridRegularError); @@ -1100,34 +1150,71 @@ TEST_CASE("API Model") { } SUBCASE("Test duplicated id") { - std::vector node_id_2{1, 1, 3}; - DatasetConst input_dataset_2{"input", false, 1}; + // std::vector node_id_2{1, 1, 3}; + // DatasetConst input_dataset_2{"input", false, 1}; - input_dataset_2.add_buffer("node", std::ssize(node_id_2), std::ssize(node_id_2), nullptr, nullptr); - input_dataset_2.add_attribute_buffer("node", "id", node_id_2.data()); + // input_dataset_2.add_buffer("node", std::ssize(node_id_2), std::ssize(node_id_2), nullptr, nullptr); + // input_dataset_2.add_attribute_buffer("node", "id", node_id_2.data()); + auto const input_data_2_json = R"json({ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 1}, + {"id": 1}, + {"id": 3} + ] + } +})json"s; + + auto const owning_input_dataset_2 = load_dataset(input_data_2_json); + auto const& input_dataset_2 = owning_input_dataset_2.dataset; auto construct_model = [&] { Model{50.0, input_dataset_2}; }; CHECK_THROWS_WITH_AS(construct_model(), "Conflicting id detected: 1\n", PowerGridRegularError); } SUBCASE("Test non-existing id") { - std::vector const node_id_2{1, 2, 3}; - std::vector const node_u_rated_2{10.0e3, 10.0e3, 10.0e3}; + // std::vector const node_id_2{1, 2, 3}; + // std::vector const node_u_rated_2{10.0e3, 10.0e3, 10.0e3}; - std::vector link_id{5}; - std::vector link_from_node{99}; - std::vector link_to_node{3}; + // std::vector link_id{5}; + // std::vector link_from_node{99}; + // std::vector link_to_node{3}; - DatasetConst input_dataset_2{"input", false, 1}; + // DatasetConst input_dataset_2{"input", false, 1}; - input_dataset_2.add_buffer("node", std::ssize(node_id_2), std::ssize(node_id_2), nullptr, nullptr); - input_dataset_2.add_attribute_buffer("node", "id", node_id_2.data()); - input_dataset_2.add_attribute_buffer("node", "u_rated", node_u_rated_2.data()); + // input_dataset_2.add_buffer("node", std::ssize(node_id_2), std::ssize(node_id_2), nullptr, nullptr); + // input_dataset_2.add_attribute_buffer("node", "id", node_id_2.data()); + // input_dataset_2.add_attribute_buffer("node", "u_rated", node_u_rated_2.data()); - input_dataset_2.add_buffer("link", std::ssize(link_id), std::ssize(link_id), nullptr, nullptr); - input_dataset_2.add_attribute_buffer("link", "id", link_id.data()); - input_dataset_2.add_attribute_buffer("link", "from_node", link_from_node.data()); - input_dataset_2.add_attribute_buffer("link", "to_node", link_to_node.data()); + // input_dataset_2.add_buffer("link", std::ssize(link_id), std::ssize(link_id), nullptr, nullptr); + // input_dataset_2.add_attribute_buffer("link", "id", link_id.data()); + // input_dataset_2.add_attribute_buffer("link", "from_node", link_from_node.data()); + // input_dataset_2.add_attribute_buffer("link", "to_node", link_to_node.data()); + + // // TODO(mgovers): remove + // Serializer serializer{input_dataset_2, PGM_json}; + // auto const str = serializer.get_to_zero_terminated_string(0, 2); + auto const input_data_2_json = R"json({ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "node": [ + {"id": 1, "u_rated": 10000}, + {"id": 2, "u_rated": 10000} + ], + "link": [ + {"id": 5, "from_node": 99, "to_node": 2} + ] + } +})json"s; + auto const owning_input_dataset_2 = load_dataset(input_data_2_json); + auto const& input_dataset_2 = owning_input_dataset_2.dataset; auto construct_model = [&] { Model{50.0, input_dataset_2}; }; CHECK_THROWS_WITH_AS(construct_model(), "The id cannot be found: 99\n", PowerGridRegularError); From 35eff1731c25396756187aea3c20b8348f01cd84 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Wed, 11 Dec 2024 10:18:55 +0100 Subject: [PATCH 11/22] remove unused code Signed-off-by: Martijn Govers --- tests/native_api_tests/test_api_model.cpp | 245 +--------------------- 1 file changed, 8 insertions(+), 237 deletions(-) diff --git a/tests/native_api_tests/test_api_model.cpp b/tests/native_api_tests/test_api_model.cpp index 2818b50c2..75421bfb3 100644 --- a/tests/native_api_tests/test_api_model.cpp +++ b/tests/native_api_tests/test_api_model.cpp @@ -275,77 +275,14 @@ TEST_CASE("API Model") { Options options{}; - // node buffer - std::vector const node_id{0, 4}; - std::vector const node_u_rated{100.0, 100.0}; - - // line buffer - std::vector const line_id{5, 6}; - std::vector const line_from_node{0, 4}; - std::vector const line_to_node{4, 0}; - std::vector const line_from_status{0, 1}; - std::vector const line_to_status{1, 0}; - std::vector const batch_line_id{5, 6, 5, 6}; - std::vector const batch_line_from_node{0, 4, 0, 4}; - std::vector const batch_line_to_node{4, 0, 4, 0}; - std::vector const batch_line_from_status{0, 1, 0, 1}; - std::vector const batch_line_to_status{1, 0, 1, 0}; - - // source buffer - ID const source_id = 1; - ID const source_node = 0; - int8_t const source_status = 1; - double const source_u_ref = 1.0; - double const source_sk = 1000.0; - double const source_rx_ratio = 0.0; - Buffer source_buffer{PGM_def_input_source, 1}; - source_buffer.set_nan(); - source_buffer.set_value(PGM_def_input_source_id, &source_id, -1); - source_buffer.set_value(PGM_def_input_source_node, &source_node, 0, sizeof(ID)); - source_buffer.set_value(PGM_def_input_source_status, &source_status, -1); - source_buffer.set_value(PGM_def_input_source_u_ref, &source_u_ref, -1); - source_buffer.set_value(PGM_def_input_source_sk, &source_sk, -1); - source_buffer.set_value(PGM_def_input_source_rx_ratio, &source_rx_ratio, -1); - - // load buffer - ID const load_id = 2; - ID const load_node = 0; - int8_t const load_status = 1; - int8_t const load_type = 2; - double const load_p_specified = 0.0; - double const load_q_specified = 500.0; - Buffer load_buffer{PGM_def_input_sym_load, 1}; - load_buffer.set_value(PGM_def_input_sym_load_id, &load_id, -1); - load_buffer.set_value(PGM_def_input_sym_load_node, &load_node, -1); - load_buffer.set_value(PGM_def_input_sym_load_status, &load_status, -1); - load_buffer.set_value(PGM_def_input_sym_load_type, &load_type, -1); - load_buffer.set_value(PGM_def_input_sym_load_p_specified, &load_p_specified, -1); - load_buffer.set_value(PGM_def_input_sym_load_q_specified, &load_q_specified, -1); - - // input data - DatasetConst input_dataset{"input", false, 1}; - - // add buffers - row - input_dataset.add_buffer("sym_load", 1, 1, nullptr, load_buffer); - input_dataset.add_buffer("source", 1, 1, nullptr, source_buffer); - - // add buffers - columnar - input_dataset.add_buffer("node", 2, 2, nullptr, nullptr); - input_dataset.add_attribute_buffer("node", "id", node_id.data()); - input_dataset.add_attribute_buffer("node", "u_rated", node_u_rated.data()); - input_dataset.add_buffer("line", 2, 2, nullptr, nullptr); - input_dataset.add_attribute_buffer("line", "id", line_id.data()); - input_dataset.add_attribute_buffer("line", "from_node", line_from_node.data()); - input_dataset.add_attribute_buffer("line", "to_node", line_to_node.data()); - input_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); - input_dataset.add_attribute_buffer("line", "to_status", line_to_status.data()); - - // // TODO(mgovers): remove - // Serializer serializer{input_dataset, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - - // auto const owning_input_dataset = load_dataset(state_json); - // auto const& input_dataset = owning_input_dataset.dataset; + auto const owning_input_dataset = load_dataset(state_json); + auto const& input_dataset = owning_input_dataset.dataset; + + auto const single_owning_update_dataset = load_dataset(single_update_json); + auto const& single_update_dataset = single_owning_update_dataset.dataset; + + auto const batch_owning_update_dataset = load_dataset(batch_update_json); + auto const& batch_update_dataset = batch_owning_update_dataset.dataset; // output data Buffer node_output{PGM_def_sym_output_node, 2}; @@ -368,54 +305,6 @@ TEST_CASE("API Model") { std::vector batch_node_result_u_pu(4); std::vector batch_node_result_u_angle(4); - // // update data - // ID const source_update_id = 1; - // int8_t const source_update_status = std::numeric_limits::min(); - // double const source_update_u_ref = 0.5; - // double const source_update_u_ref_angle = std::numeric_limits::quiet_NaN(); - // Buffer source_update_buffer{PGM_def_update_source, 1}; - // source_update_buffer.set_nan(); - // source_update_buffer.set_value(PGM_def_update_source_id, &source_update_id, 0, -1); - // source_update_buffer.set_value(PGM_def_update_source_status, &source_update_status, 0, -1); - // source_update_buffer.set_value(PGM_def_update_source_u_ref, &source_update_u_ref, 0, -1); - // source_update_buffer.set_value(PGM_def_update_source_u_ref_angle, &source_update_u_ref_angle, 0, -1); - // std::array source_update_indptr{0, 1, 1}; - - // std::vector load_updates_id = {2, 2}; - // std::vector load_updates_q_specified = {100.0, 300.0}; - // Buffer load_updates_buffer{PGM_def_update_sym_load, 2}; - // // set nan twice with offset - // load_updates_buffer.set_nan(0); - // load_updates_buffer.set_nan(1); - // load_updates_buffer.set_value(PGM_def_update_sym_load_id, load_updates_id.data(), -1); - // load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 0, -1); - // load_updates_buffer.set_value(PGM_def_update_sym_load_q_specified, load_updates_q_specified.data(), 1, -1); - // // dataset - // DatasetConst single_update_dataset{"update", false, 1}; - // single_update_dataset.add_buffer("source", 1, 1, nullptr, source_update_buffer); - // single_update_dataset.add_buffer("sym_load", 1, 1, nullptr, load_updates_buffer.get()); - // single_update_dataset.add_buffer("line", 2, 2, nullptr, nullptr); - // single_update_dataset.add_attribute_buffer("line", "id", line_id.data()); - // single_update_dataset.add_attribute_buffer("line", "from_status", line_from_status.data()); - // single_update_dataset.add_attribute_buffer("line", "to_status", line_to_status.data()); - // DatasetConst batch_update_dataset{"update", true, 2}; - // batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), source_update_buffer.get()); - // batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); - // batch_update_dataset.add_buffer("line", 2, 4, nullptr, nullptr); - // batch_update_dataset.add_attribute_buffer("line", "id", batch_line_id.data()); - // batch_update_dataset.add_attribute_buffer("line", "from_status", batch_line_from_status.data()); - // batch_update_dataset.add_attribute_buffer("line", "to_status", batch_line_to_status.data()); - - // // TODO(mgovers): remove - // Serializer serializer{batch_update_dataset, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - - auto const single_owning_update_dataset = load_dataset(single_update_json); - auto const& single_update_dataset = single_owning_update_dataset.dataset; - - auto const batch_owning_update_dataset = load_dataset(batch_update_json); - auto const& batch_update_dataset = batch_owning_update_dataset.dataset; - // create model Model model{50.0, input_dataset}; @@ -539,15 +428,6 @@ TEST_CASE("API Model") { SUBCASE("Input error handling") { SUBCASE("Construction error") { - // ID const bad_load_id = 0; - // ID const good_source_update_id = 1; - // load_buffer.set_value(PGM_def_input_sym_load_id, &bad_load_id, -1); - // source_update_buffer.set_value(PGM_def_update_source_id, &good_source_update_id, 0, -1); - - // // TODO(mgovers): remove - // Serializer serializer{input_dataset, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - auto const bad_owning_input_dataset = load_dataset(bad_load_id_state_json); auto const& bad_input_dataset = bad_owning_input_dataset.dataset; @@ -557,22 +437,6 @@ TEST_CASE("API Model") { } SUBCASE("Update error") { - // ID const good_load_id = 2; - // ID const bad_source_update_id = 99; - // load_buffer.set_value(PGM_def_input_sym_load_id, &good_load_id, -1); - // source_update_buffer.set_value(PGM_def_update_source_id, &bad_source_update_id, 0, -1); - - // // TODO(mgovers): remove - // Serializer serializer{input_dataset, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - - // auto const owning_input_dataset = load_dataset(bad_source_update_load_id_state_json); - // auto const& input_dataset = owning_input_dataset.dataset; - - // // TODO(mgovers): remove - // Serializer serializer{single_update_dataset, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - auto const bad_single_owning_update_dataset = load_dataset(bad_source_id_single_update_json); auto const& single_update_dataset = bad_single_owning_update_dataset.dataset; @@ -582,22 +446,6 @@ TEST_CASE("API Model") { } SUBCASE("Update error in calculation") { - // ID const bad_load_id = 2; - // load_buffer.set_value(PGM_def_input_sym_load_id, &bad_load_id, -1); - // DatasetConst bad_batch_update_dataset{"update", true, 2}; - // bad_batch_update_dataset.add_buffer("source", -1, 1, source_update_indptr.data(), - // source_update_buffer.get()); - // bad_batch_update_dataset.add_buffer("sym_load", 1, 2, nullptr, load_updates_buffer); - // bad_batch_update_dataset.add_buffer("line", 2, 4, nullptr, nullptr); // columnar input for line - // std::vector const bad_batch_line_id{99, 999, 9999, 99999}; - // bad_batch_update_dataset.add_attribute_buffer("line", "id", bad_batch_line_id.data()); - // bad_batch_update_dataset.add_attribute_buffer("line", "from_status", batch_line_from_status.data()); - // bad_batch_update_dataset.add_attribute_buffer("line", "to_status", batch_line_to_status.data()); - - // // TODO(mgovers): remove - // Serializer serializer{bad_batch_update_dataset, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - auto const bad_batch_owning_update_dataset = load_dataset(bad_load_id_batch_update_json); auto const& bad_batch_update_dataset = bad_batch_owning_update_dataset.dataset; @@ -651,14 +499,6 @@ TEST_CASE("API Model") { SUBCASE("Batch calculation error") { SUBCASE("Line bad line id") { - // // wrong id - // load_updates_id[1] = 999; - // load_updates_buffer.set_value(PGM_def_update_sym_load_id, load_updates_id.data(), 1, -1); - - // // TODO(mgovers): remove - // Serializer serializer{batch_update_dataset, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - auto const bad_batch_owning_update_dataset = load_dataset(bad_line_id_batch_update_json); auto const& batch_update_dataset = bad_batch_owning_update_dataset.dataset; @@ -1047,44 +887,7 @@ TEST_CASE("API Model") { } SUBCASE("Forbid link power measurements") { - // // input data - // DatasetConst input_dataset_se{"input", false, 1}; - // auto const construct_model = [&input_dataset_se] { return Model{50.0, input_dataset_se}; }; - - // // node buffer - // std::vector const node_id_se{1, 2}; - // std::vector const node_u_rated_se{10000.0, 10000.0}; - - // // link buffer - // std::vector const link_id_se{3}; - // std::vector const link_from_node_se{1}; - // std::vector const link_to_node_se{2}; - - // // power sensor - // std::vector const power_sensor_id_se{4}; - // std::vector const power_sensor_measured_object_se{3}; - // std::vector const power_sensor_measured_terminal_type_se{0}; - - // input_dataset_se.add_buffer("node", 2, 2, nullptr, nullptr); - // input_dataset_se.add_attribute_buffer("node", "id", node_id_se.data()); - // input_dataset_se.add_attribute_buffer("node", "u_rated", node_u_rated_se.data()); - - // input_dataset_se.add_buffer("link", 1, 1, nullptr, nullptr); - // input_dataset_se.add_attribute_buffer("link", "id", link_id_se.data()); - // input_dataset_se.add_attribute_buffer("link", "from_node", link_from_node_se.data()); - // input_dataset_se.add_attribute_buffer("link", "to_node", link_to_node_se.data()); - SUBCASE("SymPowerSensor") { - // input_dataset_se.add_buffer("sym_power_sensor", 1, 1, nullptr, nullptr); - // input_dataset_se.add_attribute_buffer("sym_power_sensor", "id", power_sensor_id_se.data()); - // input_dataset_se.add_attribute_buffer("sym_power_sensor", "measured_object", - // power_sensor_measured_object_se.data()); - // input_dataset_se.add_attribute_buffer("sym_power_sensor", "measured_terminal_type", - // power_sensor_measured_terminal_type_se.data()); - - // // TODO(mgovers): remove - // Serializer serializer{input_dataset_se, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); auto const input_data_se_json = R"json({ "version": "1.0", "type": "input", @@ -1114,12 +917,6 @@ TEST_CASE("API Model") { } SUBCASE("AsymPowerSensor") { - // input_dataset_se.add_buffer("asym_power_sensor", 2, 2, nullptr, nullptr); - // input_dataset_se.add_attribute_buffer("asym_power_sensor", "id", power_sensor_id_se.data()); - // input_dataset_se.add_attribute_buffer("asym_power_sensor", "measured_object", - // power_sensor_measured_object_se.data()); - // input_dataset_se.add_attribute_buffer("asym_power_sensor", "measured_terminal_type", - // power_sensor_measured_terminal_type_se.data()); auto const input_data_se_json = R"json({ "version": "1.0", "type": "input", @@ -1150,11 +947,6 @@ TEST_CASE("API Model") { } SUBCASE("Test duplicated id") { - // std::vector node_id_2{1, 1, 3}; - // DatasetConst input_dataset_2{"input", false, 1}; - - // input_dataset_2.add_buffer("node", std::ssize(node_id_2), std::ssize(node_id_2), nullptr, nullptr); - // input_dataset_2.add_attribute_buffer("node", "id", node_id_2.data()); auto const input_data_2_json = R"json({ "version": "1.0", "type": "input", @@ -1177,27 +969,6 @@ TEST_CASE("API Model") { } SUBCASE("Test non-existing id") { - // std::vector const node_id_2{1, 2, 3}; - // std::vector const node_u_rated_2{10.0e3, 10.0e3, 10.0e3}; - - // std::vector link_id{5}; - // std::vector link_from_node{99}; - // std::vector link_to_node{3}; - - // DatasetConst input_dataset_2{"input", false, 1}; - - // input_dataset_2.add_buffer("node", std::ssize(node_id_2), std::ssize(node_id_2), nullptr, nullptr); - // input_dataset_2.add_attribute_buffer("node", "id", node_id_2.data()); - // input_dataset_2.add_attribute_buffer("node", "u_rated", node_u_rated_2.data()); - - // input_dataset_2.add_buffer("link", std::ssize(link_id), std::ssize(link_id), nullptr, nullptr); - // input_dataset_2.add_attribute_buffer("link", "id", link_id.data()); - // input_dataset_2.add_attribute_buffer("link", "from_node", link_from_node.data()); - // input_dataset_2.add_attribute_buffer("link", "to_node", link_to_node.data()); - - // // TODO(mgovers): remove - // Serializer serializer{input_dataset_2, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); auto const input_data_2_json = R"json({ "version": "1.0", "type": "input", From 0c477720269dacbe40e41c7c914125c034ab2cd1 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Wed, 11 Dec 2024 10:23:32 +0100 Subject: [PATCH 12/22] reorder Signed-off-by: Martijn Govers --- tests/native_api_tests/test_api_model.cpp | 204 +++++++++++----------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/tests/native_api_tests/test_api_model.cpp b/tests/native_api_tests/test_api_model.cpp index 75421bfb3..405ed6ce4 100644 --- a/tests/native_api_tests/test_api_model.cpp +++ b/tests/native_api_tests/test_api_model.cpp @@ -118,29 +118,6 @@ auto const state_json = R"json({ } })json"s; -auto const bad_load_id_state_json = R"json({ - "version": "1.0", - "type": "input", - "is_batch": false, - "attributes": {}, - "data": { - "sym_load": [ - {"id": 0, "node": 0, "status": 1, "type": 2, "p_specified": 0, "q_specified": 500} - ], - "source": [ - {"id": 1, "node": 0, "status": 1, "u_ref": 1, "sk": 1000, "rx_ratio": 0} - ], - "node": [ - {"id": 0, "u_rated": 100}, - {"id": 4, "u_rated": 100} - ], - "line": [ - {"id": 5, "from_node": 0, "to_node": 4, "from_status": 0, "to_status": 1}, - {"id": 6, "from_node": 4, "to_node": 0, "from_status": 0, "to_status": 0} - ] - } -})json"s; - auto const single_update_json = R"json({ "version": "1.0", "type": "update", @@ -189,85 +166,6 @@ auto const batch_update_json = R"json({ } ] })json"s; - -auto const bad_source_id_single_update_json = R"json({ - "version": "1.0", - "type": "update", - "is_batch": false, - "attributes": {}, - "data": { - "source": [ - {"id": 99, "u_ref": 0.5} - ], - "sym_load": [ - {"id": 2, "q_specified": 100} - ], - "line": [ - {"id": 5, "from_status": 0, "to_status": 1}, - {"id": 6, "from_status": 0, "to_status": 0} - ] - } -})json"s; - -auto const bad_load_id_batch_update_json = R"json({ - "version": "1.0", - "type": "update", - "is_batch": true, - "attributes": {}, - "data": [ - { - "source": [ - {"id": 1, "u_ref": 0.5} - ], - "sym_load": [ - {"id": 2, "q_specified": 100} - ], - "line": [ - {"id": 99, "from_status": 0, "to_status": 1}, - {"id": 999, "from_status": 0, "to_status": 0} - ] - }, - { - "sym_load": [ - {"id": 2, "q_specified": 300} - ], - "line": [ - {"id": 9999, "from_status": 0, "to_status": 0}, - {"id": 99999, "from_status": 0, "to_status": 0} - ] - } - ] -})json"s; - -auto const bad_line_id_batch_update_json = R"json({ - "version": "1.0", - "type": "update", - "is_batch": true, - "attributes": {}, - "data": [ - { - "source": [ - {"id": 1, "u_ref": 0.5} - ], - "sym_load": [ - {"id": 2, "q_specified": 100} - ], - "line": [ - {"id": 5, "from_status": 0, "to_status": 1}, - {"id": 6, "from_status": 0, "to_status": 0} - ] - }, - { - "sym_load": [ - {"id": 999, "q_specified": 300} - ], - "line": [ - {"id": 5, "from_status": 0, "to_status": 0}, - {"id": 6, "from_status": 0, "to_status": 0} - ] - } - ] -})json"s; } // namespace TEST_CASE("API Model") { @@ -428,6 +326,29 @@ TEST_CASE("API Model") { SUBCASE("Input error handling") { SUBCASE("Construction error") { + auto const bad_load_id_state_json = R"json({ + "version": "1.0", + "type": "input", + "is_batch": false, + "attributes": {}, + "data": { + "sym_load": [ + {"id": 0, "node": 0, "status": 1, "type": 2, "p_specified": 0, "q_specified": 500} + ], + "source": [ + {"id": 1, "node": 0, "status": 1, "u_ref": 1, "sk": 1000, "rx_ratio": 0} + ], + "node": [ + {"id": 0, "u_rated": 100}, + {"id": 4, "u_rated": 100} + ], + "line": [ + {"id": 5, "from_node": 0, "to_node": 4, "from_status": 0, "to_status": 1}, + {"id": 6, "from_node": 4, "to_node": 0, "from_status": 0, "to_status": 0} + ] + } +})json"s; + auto const bad_owning_input_dataset = load_dataset(bad_load_id_state_json); auto const& bad_input_dataset = bad_owning_input_dataset.dataset; @@ -437,6 +358,25 @@ TEST_CASE("API Model") { } SUBCASE("Update error") { + auto const bad_source_id_single_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": false, + "attributes": {}, + "data": { + "source": [ + {"id": 99, "u_ref": 0.5} + ], + "sym_load": [ + {"id": 2, "q_specified": 100} + ], + "line": [ + {"id": 5, "from_status": 0, "to_status": 1}, + {"id": 6, "from_status": 0, "to_status": 0} + ] + } +})json"s; + auto const bad_single_owning_update_dataset = load_dataset(bad_source_id_single_update_json); auto const& single_update_dataset = bad_single_owning_update_dataset.dataset; @@ -446,6 +386,36 @@ TEST_CASE("API Model") { } SUBCASE("Update error in calculation") { + auto const bad_load_id_batch_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "source": [ + {"id": 1, "u_ref": 0.5} + ], + "sym_load": [ + {"id": 2, "q_specified": 100} + ], + "line": [ + {"id": 99, "from_status": 0, "to_status": 1}, + {"id": 999, "from_status": 0, "to_status": 0} + ] + }, + { + "sym_load": [ + {"id": 2, "q_specified": 300} + ], + "line": [ + {"id": 9999, "from_status": 0, "to_status": 0}, + {"id": 99999, "from_status": 0, "to_status": 0} + ] + } + ] +})json"s; + auto const bad_batch_owning_update_dataset = load_dataset(bad_load_id_batch_update_json); auto const& bad_batch_update_dataset = bad_batch_owning_update_dataset.dataset; @@ -499,6 +469,36 @@ TEST_CASE("API Model") { SUBCASE("Batch calculation error") { SUBCASE("Line bad line id") { + auto const bad_line_id_batch_update_json = R"json({ + "version": "1.0", + "type": "update", + "is_batch": true, + "attributes": {}, + "data": [ + { + "source": [ + {"id": 1, "u_ref": 0.5} + ], + "sym_load": [ + {"id": 2, "q_specified": 100} + ], + "line": [ + {"id": 5, "from_status": 0, "to_status": 1}, + {"id": 6, "from_status": 0, "to_status": 0} + ] + }, + { + "sym_load": [ + {"id": 999, "q_specified": 300} + ], + "line": [ + {"id": 5, "from_status": 0, "to_status": 0}, + {"id": 6, "from_status": 0, "to_status": 0} + ] + } + ] +})json"s; + auto const bad_batch_owning_update_dataset = load_dataset(bad_line_id_batch_update_json); auto const& batch_update_dataset = bad_batch_owning_update_dataset.dataset; From 3190f3e2dcea0838fc2cca57614774f17691ce07 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Thu, 12 Dec 2024 13:10:41 +0100 Subject: [PATCH 13/22] fix linux build Signed-off-by: Martijn Govers --- .../include/power_grid_model_cpp/serialization.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp index e8e6ad53b..87fa38f80 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp @@ -104,7 +104,6 @@ inline OwningDatasetConst create_owning_dataset(DatasetWritable& writable_datase for (Idx component_idx{}; component_idx < info.n_components(); ++component_idx) { auto const& component_name = info.component_name(component_idx); auto const& component_meta = MetaData::get_component_by_name(dataset_name, component_name); - Idx const component_elements_per_scenario = info.component_elements_per_scenario(component_idx); Idx const component_size = info.component_total_elements(component_idx); auto& current_indptr = From f210727edb1dee22171665cb08dcfbe85c0e8d46 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Thu, 12 Dec 2024 14:27:46 +0100 Subject: [PATCH 14/22] clang-tidy Signed-off-by: Martijn Govers --- .../include/power_grid_model_cpp/serialization.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp index 87fa38f80..ddf5f1aea 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp @@ -97,8 +97,6 @@ inline OwningDatasetConst create_owning_dataset(DatasetWritable& writable_datase bool const is_batch = info.is_batch(); Idx const batch_size = info.batch_size(); auto const& dataset_name = info.name(); - DatasetMutable dataset_mutable{dataset_name, is_batch, batch_size}; - DatasetConst dataset_const{dataset_mutable}; OwningMemory storage{}; for (Idx component_idx{}; component_idx < info.n_components(); ++component_idx) { From df49310913db37ec68dbb07a8529d6f66ff5001c Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Thu, 12 Dec 2024 14:35:28 +0100 Subject: [PATCH 15/22] only mutable owning dataset Signed-off-by: Martijn Govers --- .../include/power_grid_model_cpp/dataset.hpp | 7 +------ .../power_grid_model_cpp/serialization.hpp | 10 ++++++---- tests/cpp_validation_tests/test_validation.cpp | 18 +++++++++--------- tests/native_api_tests/load_dataset.hpp | 2 +- 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index 021c15fbe..e9e41b89f 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -188,15 +188,10 @@ struct OwningMemory { std::vector> indptrs; }; -struct OwningDatasetMutable { +struct OwningDataset { DatasetMutable dataset; OwningMemory storage{}; }; - -struct OwningDatasetConst { - DatasetConst dataset; - OwningMemory storage{}; -}; } // namespace power_grid_model_cpp #endif // POWER_GRID_MODEL_CPP_DATASET_HPP diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp index ddf5f1aea..d1c3181cb 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/serialization.hpp @@ -92,20 +92,21 @@ class Serializer { detail::UniquePtr serializer_; }; -inline OwningDatasetConst create_owning_dataset(DatasetWritable& writable_dataset) { +inline OwningDataset create_owning_dataset(DatasetWritable& writable_dataset) { auto const& info = writable_dataset.get_info(); bool const is_batch = info.is_batch(); Idx const batch_size = info.batch_size(); auto const& dataset_name = info.name(); + DatasetMutable dataset_mutable{dataset_name, is_batch, batch_size}; OwningMemory storage{}; for (Idx component_idx{}; component_idx < info.n_components(); ++component_idx) { auto const& component_name = info.component_name(component_idx); auto const& component_meta = MetaData::get_component_by_name(dataset_name, component_name); Idx const component_size = info.component_total_elements(component_idx); + Idx const elements_per_scenario = info.component_elements_per_scenario(component_idx); - auto& current_indptr = - storage.indptrs.emplace_back(info.component_elements_per_scenario(component_idx) < 0 ? batch_size + 1 : 0); + auto& current_indptr = storage.indptrs.emplace_back(elements_per_scenario < 0 ? batch_size + 1 : 0); if (!current_indptr.empty()) { current_indptr.at(0) = 0; current_indptr.at(batch_size) = component_size; @@ -113,8 +114,9 @@ inline OwningDatasetConst create_owning_dataset(DatasetWritable& writable_datase Idx* const indptr = current_indptr.empty() ? nullptr : current_indptr.data(); auto& current_buffer = storage.buffers.emplace_back(component_meta, component_size); writable_dataset.set_buffer(component_name, indptr, current_buffer); + dataset_mutable.add_buffer(component_name, elements_per_scenario, component_size, indptr, current_buffer); } - return OwningDatasetConst{.dataset = writable_dataset, .storage = std::move(storage)}; + return OwningDataset{.dataset = std::move(dataset_mutable), .storage = std::move(storage)}; } } // namespace power_grid_model_cpp diff --git a/tests/cpp_validation_tests/test_validation.cpp b/tests/cpp_validation_tests/test_validation.cpp index d93989bfe..84048508c 100644 --- a/tests/cpp_validation_tests/test_validation.cpp +++ b/tests/cpp_validation_tests/test_validation.cpp @@ -60,11 +60,11 @@ auto read_json(std::filesystem::path const& path) { return j; } -OwningDatasetMutable create_result_dataset(OwningDatasetConst const& input, std::string const& dataset_name, - bool is_batch = false, Idx batch_size = 1) { +OwningDataset create_result_dataset(OwningDataset const& input, std::string const& dataset_name, bool is_batch = false, + Idx batch_size = 1) { DatasetInfo const& input_info = input.dataset.get_info(); - OwningDatasetMutable result{.dataset{dataset_name, is_batch, batch_size}, .storage{}}; + OwningDataset result{.dataset{dataset_name, is_batch, batch_size}, .storage{}}; for (Idx component_idx{}; component_idx != input_info.n_components(); ++component_idx) { auto const& component_name = input_info.component_name(component_idx); @@ -82,7 +82,7 @@ OwningDatasetMutable create_result_dataset(OwningDatasetConst const& input, std: return result; } -OwningDatasetConst load_dataset(std::filesystem::path const& path) { +OwningDataset load_dataset(std::filesystem::path const& path) { // Issue in msgpack, reported in https://github.com/msgpack/msgpack-c/issues/1098 // May be a Clang Analyzer bug #ifndef __clang_analyzer__ // TODO(mgovers): re-enable this when issue in msgpack is fixed @@ -209,7 +209,7 @@ void check_individual_attribute(Buffer const& buffer, Buffer const& ref_buffer, } } -void assert_result(OwningDatasetMutable const& owning_result, OwningDatasetConst const& owning_reference_result, +void assert_result(OwningDataset const& owning_result, OwningDataset const& owning_reference_result, std::map> atol, double rtol) { using namespace std::string_literals; @@ -438,10 +438,10 @@ void add_cases(std::filesystem::path const& case_dir, std::string const& calcula // test case with parameter struct ValidationCase { CaseParam param; - OwningDatasetConst input; - std::optional output; - std::optional update_batch; - std::optional output_batch; + OwningDataset input; + std::optional output; + std::optional update_batch; + std::optional output_batch; }; ValidationCase create_validation_case(CaseParam const& param, std::string const& output_type) { diff --git a/tests/native_api_tests/load_dataset.hpp b/tests/native_api_tests/load_dataset.hpp index e118475a4..16817e967 100644 --- a/tests/native_api_tests/load_dataset.hpp +++ b/tests/native_api_tests/load_dataset.hpp @@ -9,7 +9,7 @@ #include namespace power_grid_model_cpp_test { -inline power_grid_model_cpp::OwningDatasetConst load_dataset(std::string const& json_string) { +inline power_grid_model_cpp::OwningDataset load_dataset(std::string const& json_string) { power_grid_model_cpp::Deserializer deserializer{json_string, PGM_json}; auto& writable_dataset = deserializer.get_dataset(); auto owning_dataset = power_grid_model_cpp::create_owning_dataset(writable_dataset); From a960b1b447c050ec840edd35943a5c6e751f6dd5 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Thu, 12 Dec 2024 15:08:09 +0100 Subject: [PATCH 16/22] use explicit constructor Signed-off-by: Martijn Govers --- tests/cpp_validation_tests/test_validation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cpp_validation_tests/test_validation.cpp b/tests/cpp_validation_tests/test_validation.cpp index 84048508c..883c5a904 100644 --- a/tests/cpp_validation_tests/test_validation.cpp +++ b/tests/cpp_validation_tests/test_validation.cpp @@ -64,7 +64,7 @@ OwningDataset create_result_dataset(OwningDataset const& input, std::string cons Idx batch_size = 1) { DatasetInfo const& input_info = input.dataset.get_info(); - OwningDataset result{.dataset{dataset_name, is_batch, batch_size}, .storage{}}; + OwningDataset result{.dataset = DatasetMutable{dataset_name, is_batch, batch_size}, .storage{}}; for (Idx component_idx{}; component_idx != input_info.n_components(); ++component_idx) { auto const& component_name = input_info.component_name(component_idx); From 981d866124b8263b9449787a904aa84ee3621025 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 16 Dec 2024 07:55:48 +0100 Subject: [PATCH 17/22] resolve comment Signed-off-by: Martijn Govers --- tests/native_api_tests/test_api_model.cpp | 4 ++-- .../native_api_tests/test_api_model_update.cpp | 18 +++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/tests/native_api_tests/test_api_model.cpp b/tests/native_api_tests/test_api_model.cpp index 405ed6ce4..10738634b 100644 --- a/tests/native_api_tests/test_api_model.cpp +++ b/tests/native_api_tests/test_api_model.cpp @@ -95,7 +95,7 @@ void check_throws_with(Func&& func, PGM_ErrorCode const& reference_error, std::s } } -auto const state_json = R"json({ +auto const complete_state_json = R"json({ "version": "1.0", "type": "input", "is_batch": false, @@ -173,7 +173,7 @@ TEST_CASE("API Model") { Options options{}; - auto const owning_input_dataset = load_dataset(state_json); + auto const owning_input_dataset = load_dataset(complete_state_json); auto const& input_dataset = owning_input_dataset.dataset; auto const single_owning_update_dataset = load_dataset(single_update_json); diff --git a/tests/native_api_tests/test_api_model_update.cpp b/tests/native_api_tests/test_api_model_update.cpp index 0835502f3..8dd14f324 100644 --- a/tests/native_api_tests/test_api_model_update.cpp +++ b/tests/native_api_tests/test_api_model_update.cpp @@ -297,7 +297,7 @@ constexpr double i_shunt = 0.015 / 0.025 * i; constexpr double i_load = 0.005 / 0.025 * i; } // namespace test -auto const state_json = R"json({ +auto const complete_state_json = R"json({ "version": "1.0", "type": "input", "is_batch": false, @@ -378,20 +378,12 @@ auto const update_vector_json = R"json({ } // namespace TEST_CASE("API model - all updates") { - // TODO(mgovers): remove - // Serializer serializer{state.get_input_dataset(), PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - - auto const owning_input_dataset = load_dataset(state_json); + auto const owning_input_dataset = load_dataset(complete_state_json); auto const& input_dataset = owning_input_dataset.dataset; auto const& input_info = input_dataset.get_info(); auto model = Model{50.0, input_dataset}; - // TODO(mgovers): remove - // Serializer serializer{update_data, PGM_json}; - // auto const str = serializer.get_to_zero_terminated_string(0, 2); - auto const owning_update_dataset = load_dataset(update_json); auto const& update_data = owning_update_dataset.dataset; @@ -443,7 +435,7 @@ TEST_CASE("API model - all updates") { } TEST_CASE("API model - updates w/ alternating compute mode") { - auto const owning_input_dataset = load_dataset(state_json); + auto const owning_input_dataset = load_dataset(complete_state_json); auto const& input_dataset = owning_input_dataset.dataset; auto model = Model{50.0, input_dataset}; @@ -626,7 +618,7 @@ auto const complete_update_json = R"json({ } // namespace TEST_CASE("API model - incomplete input") { - auto const complete_owning_input_dataset = load_dataset(state_json); + auto const complete_owning_input_dataset = load_dataset(complete_state_json); auto const& complete_input_data = complete_owning_input_dataset.dataset; auto const incomplete_owning_input_dataset = load_dataset(incomplete_state_json); @@ -793,7 +785,7 @@ auto const second_scenario_update_json = R"json({ })json"s; TEST_CASE("API model - Incomplete scenario update followed by complete") { - auto const complete_owning_input_dataset = load_dataset(state_json); + auto const complete_owning_input_dataset = load_dataset(complete_state_json); auto const incomplete_owning_input_dataset = load_dataset(incomplete_state_json); auto const& complete_input_data = complete_owning_input_dataset.dataset; From 55b779c19223f07f6e8b7abadc95ff9b7ab62011 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 16 Dec 2024 08:28:01 +0100 Subject: [PATCH 18/22] fix sonar cloud Signed-off-by: Martijn Govers --- tests/cpp_validation_tests/test_validation.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/tests/cpp_validation_tests/test_validation.cpp b/tests/cpp_validation_tests/test_validation.cpp index 883c5a904..a52a05c7f 100644 --- a/tests/cpp_validation_tests/test_validation.cpp +++ b/tests/cpp_validation_tests/test_validation.cpp @@ -35,15 +35,6 @@ class UnsupportedValidationCase : public PowerGridError { }()} {} }; -class OptionalNotInitialized : public PowerGridError { - public: - OptionalNotInitialized(std::string const& object) - : PowerGridError{[&]() { - using namespace std::string_literals; - return "Optional "s + object + " object not initialized"s; - }()} {} -}; - using nlohmann::json; auto read_file(std::filesystem::path const& path) { From b918f381706c726d24ae4641b6ba3c6ce102943e Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 16 Dec 2024 08:54:14 +0100 Subject: [PATCH 19/22] more sonar cloud Signed-off-by: Martijn Govers --- tests/native_api_tests/test_api_model.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/native_api_tests/test_api_model.cpp b/tests/native_api_tests/test_api_model.cpp index 10738634b..0709749fd 100644 --- a/tests/native_api_tests/test_api_model.cpp +++ b/tests/native_api_tests/test_api_model.cpp @@ -378,9 +378,9 @@ TEST_CASE("API Model") { })json"s; auto const bad_single_owning_update_dataset = load_dataset(bad_source_id_single_update_json); - auto const& single_update_dataset = bad_single_owning_update_dataset.dataset; - - auto const bad_update_lambda = [&model, &single_update_dataset]() { model.update(single_update_dataset); }; + auto const bad_update_lambda = [&model, &bad_single_owning_update_dataset]() { + model.update(bad_single_owning_update_dataset.dataset); + }; check_throws_with(bad_update_lambda, PGM_regular_error, "The id cannot be found:"s); } @@ -417,11 +417,9 @@ TEST_CASE("API Model") { })json"s; auto const bad_batch_owning_update_dataset = load_dataset(bad_load_id_batch_update_json); - auto const& bad_batch_update_dataset = bad_batch_owning_update_dataset.dataset; - auto const bad_calc_with_update_lambda = [&model, &options, &batch_output_dataset, - &bad_batch_update_dataset]() { - model.calculate(options, batch_output_dataset, bad_batch_update_dataset); + &bad_batch_owning_update_dataset]() { + model.calculate(options, batch_output_dataset, bad_batch_owning_update_dataset.dataset); }; check_throws_with(bad_calc_with_update_lambda, PGM_batch_error, "The id cannot be found:"s); } @@ -500,11 +498,10 @@ TEST_CASE("API Model") { })json"s; auto const bad_batch_owning_update_dataset = load_dataset(bad_line_id_batch_update_json); - auto const& batch_update_dataset = bad_batch_owning_update_dataset.dataset; // failed in batch scenario 1 try { - model.calculate(options, batch_output_dataset, batch_update_dataset); + model.calculate(options, batch_output_dataset, bad_batch_owning_update_dataset.dataset); FAIL("Expected batch calculation error not thrown."); } catch (PowerGridBatchError const& e) { CHECK(e.error_code() == PGM_batch_error); From 16ea1e30e53a692dfb58150f03f7d3d42115edd7 Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 16 Dec 2024 09:09:32 +0100 Subject: [PATCH 20/22] minor Signed-off-by: Martijn Govers --- .../include/power_grid_model_cpp/handle.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp index d08b99e11..47108cc59 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/handle.hpp @@ -40,8 +40,8 @@ class PowerGridBatchError : public PowerGridError { std::string error_message; }; - PowerGridBatchError(std::string const& message, std::vector failed_scenarios_c) - : PowerGridError{message}, failed_scenarios_{std::move(failed_scenarios_c)} {} + PowerGridBatchError(std::string message, std::vector failed_scenarios_c) + : PowerGridError{std::move(message)}, failed_scenarios_{std::move(failed_scenarios_c)} {} Idx error_code() const noexcept override { return PGM_batch_error; } std::vector const& failed_scenarios() const { return failed_scenarios_; } From 1d6d13308fdd2fa7731fc04bf8d6cf69622ec12e Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 16 Dec 2024 10:13:41 +0100 Subject: [PATCH 21/22] throw when component type not found in dataset Signed-off-by: Martijn Govers --- .../include/power_grid_model_cpp/dataset.hpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp index e9e41b89f..eaf12f11f 100644 --- a/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp +++ b/power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp @@ -13,6 +13,15 @@ #include "power_grid_model_c/dataset.h" namespace power_grid_model_cpp { +class ComponentTypeNotFound : public PowerGridError { + public: + ComponentTypeNotFound(std::string const& component) + : PowerGridError{[&]() { + using namespace std::string_literals; + return "ComponentType"s + component + " not found"s; + }()} {} + ComponentTypeNotFound(std::string_view component) : ComponentTypeNotFound{std::string{component}} {} +}; class DatasetInfo { @@ -51,7 +60,7 @@ class DatasetInfo { return idx; } } - return -1; + throw ComponentTypeNotFound{component}; } private: From 336e1afe9d8440cebff51053815de7004376f58f Mon Sep 17 00:00:00 2001 From: Martijn Govers Date: Mon, 16 Dec 2024 14:21:50 +0100 Subject: [PATCH 22/22] remove unnecessary header guards protected by pragma once Signed-off-by: Martijn Govers --- .pre-commit-config.yaml | 2 +- tests/cpp_unit_tests/test_math_solver_common.hpp | 4 ---- tests/cpp_unit_tests/test_math_solver_pf.hpp | 4 ---- tests/cpp_unit_tests/test_math_solver_se.hpp | 4 ---- tests/cpp_unit_tests/test_optimizer.hpp | 4 ---- tests/native_api_tests/load_dataset.hpp | 4 ---- 6 files changed, 1 insertion(+), 21 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7bce9224f..d07c0dd5e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: hooks: - id: black-jupyter - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.11.2 + rev: v1.13.0 hooks: - id: mypy additional_dependencies: diff --git a/tests/cpp_unit_tests/test_math_solver_common.hpp b/tests/cpp_unit_tests/test_math_solver_common.hpp index 37f027b31..da4f005d8 100644 --- a/tests/cpp_unit_tests/test_math_solver_common.hpp +++ b/tests/cpp_unit_tests/test_math_solver_common.hpp @@ -5,8 +5,6 @@ // In this unit test the powerflow solvers are tested #pragma once -#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_COMMON_HPP -#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_COMMON_HPP #include #include @@ -269,5 +267,3 @@ template struct SteadyStateSolverTestGrid { }; } // namespace power_grid_model - -#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_COMMON_HPP diff --git a/tests/cpp_unit_tests/test_math_solver_pf.hpp b/tests/cpp_unit_tests/test_math_solver_pf.hpp index ffe927514..1971d83ea 100644 --- a/tests/cpp_unit_tests/test_math_solver_pf.hpp +++ b/tests/cpp_unit_tests/test_math_solver_pf.hpp @@ -5,8 +5,6 @@ // In this unit test the powerflow solvers are tested #pragma once -#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_PF_HPP -#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_PF_HPP #include "test_math_solver_common.hpp" @@ -146,5 +144,3 @@ TEST_CASE_TEMPLATE_DEFINE("Test math solver - PF", SolverType, test_math_solver_ } } // namespace power_grid_model - -#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_PF_HPP diff --git a/tests/cpp_unit_tests/test_math_solver_se.hpp b/tests/cpp_unit_tests/test_math_solver_se.hpp index dfbbceb5a..1d4268261 100644 --- a/tests/cpp_unit_tests/test_math_solver_se.hpp +++ b/tests/cpp_unit_tests/test_math_solver_se.hpp @@ -5,8 +5,6 @@ // In this unit test the powerflow solvers are tested #pragma once -#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_SE_HPP -#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_SE_HPP #include "test_math_solver_common.hpp" @@ -520,5 +518,3 @@ TEST_CASE_TEMPLATE_DEFINE("Test math solver - SE, measurements", SolverType, tes } } // namespace power_grid_model - -#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_MATH_SOLVER_SE_HPP diff --git a/tests/cpp_unit_tests/test_optimizer.hpp b/tests/cpp_unit_tests/test_optimizer.hpp index c941ef8d3..7f24b915d 100644 --- a/tests/cpp_unit_tests/test_optimizer.hpp +++ b/tests/cpp_unit_tests/test_optimizer.hpp @@ -3,8 +3,6 @@ // SPDX-License-Identifier: MPL-2.0 #pragma once -#ifndef POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_OPTIMIZER_HPP -#define POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_OPTIMIZER_HPP #include #include @@ -250,5 +248,3 @@ template <> struct get_attributes_list { }; } // namespace meta_data } // namespace power_grid_model - -#endif // POWER_GRID_MODEL_TESTS_CPP_UNIT_TESTS_TEST_OPTIMIZER_HPP diff --git a/tests/native_api_tests/load_dataset.hpp b/tests/native_api_tests/load_dataset.hpp index 16817e967..4354ab7a1 100644 --- a/tests/native_api_tests/load_dataset.hpp +++ b/tests/native_api_tests/load_dataset.hpp @@ -3,8 +3,6 @@ // SPDX-License-Identifier: MPL-2.0 #pragma once -#ifndef POWER_GRID_MODEL_TESTS_NATIVE_API_TESTS_LOAD_DATASET_HPP -#define POWER_GRID_MODEL_TESTS_NATIVE_API_TESTS_LOAD_DATASET_HPP #include @@ -17,5 +15,3 @@ inline power_grid_model_cpp::OwningDataset load_dataset(std::string const& json_ return owning_dataset; } } // namespace power_grid_model_cpp_test - -#endif // POWER_GRID_MODEL_TESTS_NATIVE_API_TESTS_LOAD_DATASET_HPP