Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "power_grid_model_c/dataset.h"

#include <array>
#include <functional>
#include <map>
#include <set>
#include <string>
Expand All @@ -23,6 +24,16 @@
#include <vector>

namespace power_grid_model_cpp {
namespace detail {
inline std::set<std::string, std::less<>> get_irrelevant_components(PGM_CalculationType calculation_type) {
using namespace std::string_literals;

if (calculation_type == PGM_power_flow || calculation_type == PGM_state_estimation) {
return {"fault"s};
}
return {};
}
} // namespace detail
class ComponentTypeNotFound : public PowerGridError {
public:
ComponentTypeNotFound(std::string const& component)
Expand Down Expand Up @@ -256,14 +267,25 @@
std::vector<std::vector<AttributeBuffer>> attribute_buffers;
};

inline std::string get_output_type(PGM_CalculationType calculation_type, bool sym) {
using namespace std::string_literals;

if (calculation_type == PGM_short_circuit) {
return "sc_output"s;
}
if (sym) {
return "sym_output"s;
}
return "asym_output"s;
}
Comment thread
TonyXiang8787 marked this conversation as resolved.

struct OwningDataset {
DatasetMutable dataset;
OwningMemory storage{};

OwningDataset(DatasetWritable& writable_dataset, bool enable_columnar_buffers = false)
Comment thread
TonyXiang8787 marked this conversation as resolved.
: dataset{writable_dataset.get_info().name(), writable_dataset.get_info().is_batch(),
writable_dataset.get_info().batch_size()},
storage{} {
writable_dataset.get_info().batch_size()} {
auto const& info = writable_dataset.get_info();
Idx const batch_size = info.batch_size();
auto const& dataset_name = info.name();
Expand Down Expand Up @@ -305,20 +327,30 @@
}

OwningDataset(
OwningDataset const& ref_dataset, std::string const& dataset_name, bool is_batch = false, Idx batch_size = 1,
OwningDataset const& ref_dataset, PGM_CalculationType calculation_type, bool sym, bool is_batch = false,
Comment thread
TonyXiang8787 marked this conversation as resolved.
Idx batch_size = 1,
std::map<MetaComponent const*, std::set<MetaAttribute const*>> const& output_component_attribute_filters = {})
: dataset{dataset_name, is_batch, batch_size}, storage{} {
: dataset{get_output_type(calculation_type, sym), is_batch, batch_size} {
DatasetInfo const& ref_info = ref_dataset.dataset.get_info();
bool const enable_filters = !output_component_attribute_filters.empty();
auto const irrelevant_components = detail::get_irrelevant_components(calculation_type);

auto const contains_irrelevant_component = [&irrelevant_components](std::string const& component) {
return irrelevant_components.find(component) != irrelevant_components.end();

Check warning on line 339 in power_grid_model_c/power_grid_model_cpp/include/power_grid_model_cpp/dataset.hpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use "contains" member function.

See more on https://sonarcloud.io/project/issues?id=PowerGridModel_power-grid-model&issues=AZ0a7IqTbU7bKjPpF3HM&open=AZ0a7IqTbU7bKjPpF3HM&pullRequest=1340
Comment thread
TonyXiang8787 marked this conversation as resolved.
};

for (Idx component_idx{}; component_idx != ref_info.n_components(); ++component_idx) {
auto const& component_name = ref_info.component_name(component_idx);
auto const& component_meta = MetaData::get_component_by_name(dataset_name, component_name);
auto const& component_meta = MetaData::get_component_by_name(dataset.get_info().name(), component_name);
// skip components not in the filter
if (enable_filters &&
output_component_attribute_filters.find(component_meta) == output_component_attribute_filters.end()) {
continue;
}
// skip irrelevant components for the calculation type
if (contains_irrelevant_component(component_name)) {
continue;
}

// get size info from reference dataset
Idx const component_elements_per_scenario = ref_info.component_elements_per_scenario(component_idx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ inline OwningDataset load_dataset(std::filesystem::path const& path, PGM_Seriali
return buffer;
};

Deserializer deserializer{read_file(path), serialization_format};
auto const file_content = read_file(path);
Deserializer deserializer{file_content, serialization_format};
auto& writable_dataset = deserializer.get_dataset();
OwningDataset dataset{writable_dataset, enable_columnar_buffers};
deserializer.parse_to_buffer();
Expand Down
84 changes: 36 additions & 48 deletions tests/cpp_validation_tests/test_validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@

namespace power_grid_model_cpp {
namespace {
class UnsupportedValidationCase : public PowerGridError {
public:
UnsupportedValidationCase(std::string const& calculation_type, bool sym)
: PowerGridError{std::format("Unsupported validation case: {} {}", sym ? "sym" : "asym", calculation_type)} {}
};

using nlohmann::json;

auto read_json(std::filesystem::path const& path) {
Expand Down Expand Up @@ -402,11 +396,11 @@ std::map<std::string, PGM_ExperimentalFeatures, std::less<>> const experimental_
struct CaseParam {
std::filesystem::path case_dir;
std::string case_name;
std::string calculation_type;
std::string calculation_method;
std::string short_circuit_voltage_scaling;
std::string tap_changing_strategy;
std::string experimental_features;
PGM_CalculationType calculation_type;
PGM_CalculationMethod calculation_method;
PGM_ShortCircuitVoltageScaling short_circuit_voltage_scaling;
PGM_TapChangingStrategy tap_changing_strategy;
PGM_ExperimentalFeatures experimental_features;
double err_tol = 1e-8;
Idx max_iter = 20;
bool sym{};
Expand All @@ -425,40 +419,29 @@ struct CaseParam {

Options get_options(CaseParam const& param, Idx threading = -1) {
Options options{};
options.set_calculation_type(calculation_type_mapping.at(param.calculation_type));
options.set_calculation_method(calculation_method_mapping.at(param.calculation_method));
options.set_calculation_type(param.calculation_type);
options.set_calculation_method(param.calculation_method);
options.set_symmetric(param.sym ? PGM_symmetric : PGM_asymmetric);
options.set_err_tol(param.err_tol);
options.set_max_iter(param.max_iter);
options.set_threading(threading);
options.set_short_circuit_voltage_scaling(sc_voltage_scaling_mapping.at(param.short_circuit_voltage_scaling));
options.set_tap_changing_strategy(optimizer_strategy_mapping.at(param.tap_changing_strategy));
options.set_experimental_features(experimental_features_mapping.at(param.experimental_features));
options.set_short_circuit_voltage_scaling(param.short_circuit_voltage_scaling);
options.set_tap_changing_strategy(param.tap_changing_strategy);
options.set_experimental_features(param.experimental_features);
return options;
}

std::string get_output_type(std::string const& calculation_type, bool sym) {
using namespace std::string_literals;

if (calculation_type == "short_circuit"s) {
if (sym) {
throw UnsupportedValidationCase{calculation_type, sym};
}
return "sc_output"s;
}
if (sym) {
return "sym_output"s;
}
return "asym_output"s;
}

std::optional<CaseParam> construct_case(std::filesystem::path const& case_dir, json const& j,
std::string const& calculation_type, bool is_batch,
std::string const& calculation_method, bool sym) {
std::string const& calculation_type_str, bool is_batch,
std::string const& calculation_method_str, bool sym) {
using namespace std::string_literals;

auto const batch_suffix = is_batch ? "_batch"s : ""s;

// Convert strings to enums
PGM_CalculationType const calculation_type = calculation_type_mapping.at(calculation_type_str);
PGM_CalculationMethod const calculation_method = calculation_method_mapping.at(calculation_method_str);

// add a case if output file exists
std::filesystem::path const output_file =
case_dir / (get_output_type(calculation_type, sym) + batch_suffix + ".json"s);
Expand All @@ -484,8 +467,8 @@ std::optional<CaseParam> construct_case(std::filesystem::path const& case_dir, j
json calculation_method_params;
calculation_method_params.update(j, true);
if (j.contains("extra_params")) {
if (json const& extra_params = j.at("extra_params"); extra_params.contains(calculation_method)) {
calculation_method_params.update(extra_params.at(calculation_method), true);
if (json const& extra_params = j.at("extra_params"); extra_params.contains(calculation_method_str)) {
calculation_method_params.update(extra_params.at(calculation_method_str), true);
}
}

Expand All @@ -499,14 +482,18 @@ std::optional<CaseParam> construct_case(std::filesystem::path const& case_dir, j
param.xfail = xfail.at("raises").get<std::string>();
}
}
if (calculation_type == "short_circuit") {
calculation_method_params.at("short_circuit_voltage_scaling").get_to(param.short_circuit_voltage_scaling);
if (calculation_type == PGM_short_circuit) {
std::string const sc_scaling_str =
calculation_method_params.at("short_circuit_voltage_scaling").get<std::string>();
param.short_circuit_voltage_scaling = sc_voltage_scaling_mapping.at(sc_scaling_str);
}

param.tap_changing_strategy = calculation_method_params.value("tap_changing_strategy", "disabled");
param.experimental_features = calculation_method_params.value("experimental_features", "disabled");
std::string const tap_strategy_str = calculation_method_params.value("tap_changing_strategy", "disabled");
param.tap_changing_strategy = optimizer_strategy_mapping.at(tap_strategy_str);
std::string const experimental_features_str = calculation_method_params.value("experimental_features", "disabled");
param.experimental_features = experimental_features_mapping.at(experimental_features_str);
param.case_name += sym ? "-sym"s : "-asym"s;
param.case_name += "-"s + param.calculation_method;
param.case_name += "-"s + calculation_method_str;
param.case_name += is_batch ? "_batch"s : ""s;

return param;
Expand Down Expand Up @@ -625,7 +612,7 @@ void validate_single_case(CaseParam const& param) {
execute_test(param, [&param](Subcase& subcase) {
auto const output_prefix = get_output_type(param.calculation_type, param.sym);
auto const validation_case = create_validation_case(param, output_prefix);
OwningDataset const result{validation_case.output.value(), output_prefix};
OwningDataset const result{validation_case.output.value(), param.calculation_type, param.sym};

// create and run model
auto const& options = get_options(param);
Expand All @@ -643,7 +630,8 @@ void validate_batch_case(CaseParam const& param) {
auto const validation_case = create_validation_case(param, output_prefix);
auto const& info = validation_case.update_batch.value().dataset.get_info();
Idx const batch_size = info.batch_size();
OwningDataset const batch_result{validation_case.output_batch.value(), output_prefix, true, batch_size};
OwningDataset const batch_result{validation_case.output_batch.value(), param.calculation_type, param.sym, true,
batch_size};

// create model
Model model{50.0, validation_case.input.dataset};
Expand All @@ -666,7 +654,7 @@ void validate_batch_case(CaseParam const& param) {
TEST_CASE("Validation test single - power flow") {
std::vector<CaseParam> const& all_cases = get_all_single_cases();
for (CaseParam const& param : all_cases) {
if (param.calculation_type == "power_flow") {
if (param.calculation_type == PGM_power_flow) {
SUBCASE(param.case_name.c_str()) { validate_single_case(param); }
}
}
Expand All @@ -675,7 +663,7 @@ TEST_CASE("Validation test single - power flow") {
TEST_CASE("Validation test single - state estimation") {
std::vector<CaseParam> const& all_cases = get_all_single_cases();
for (CaseParam const& param : all_cases) {
if (param.calculation_type == "state_estimation") {
if (param.calculation_type == PGM_state_estimation) {
SUBCASE(param.case_name.c_str()) { validate_single_case(param); }
}
}
Expand All @@ -684,7 +672,7 @@ TEST_CASE("Validation test single - state estimation") {
TEST_CASE("Validation test single - short circuit") {
std::vector<CaseParam> const& all_cases = get_all_single_cases();
for (CaseParam const& param : all_cases) {
if (param.calculation_type == "short_circuit") {
if (param.calculation_type == PGM_short_circuit) {
SUBCASE(param.case_name.c_str()) { validate_single_case(param); }
}
}
Expand All @@ -694,7 +682,7 @@ TEST_CASE("Validation test batch - power flow") {
std::vector<CaseParam> const& all_cases = get_all_batch_cases();

for (CaseParam const& param : all_cases) {
if (param.calculation_type == "power_flow") {
if (param.calculation_type == PGM_power_flow) {
SUBCASE(param.case_name.c_str()) { validate_batch_case(param); }
}
}
Expand All @@ -704,7 +692,7 @@ TEST_CASE("Validation test batch - state estimation") {
std::vector<CaseParam> const& all_cases = get_all_batch_cases();

for (CaseParam const& param : all_cases) {
if (param.calculation_type == "state_estimation") {
if (param.calculation_type == PGM_state_estimation) {
SUBCASE(param.case_name.c_str()) { validate_batch_case(param); }
}
}
Expand All @@ -714,7 +702,7 @@ TEST_CASE("Validation test batch - short circuit") {
std::vector<CaseParam> const& all_cases = get_all_batch_cases();

for (CaseParam const& param : all_cases) {
if (param.calculation_type == "short_circuit") {
if (param.calculation_type == PGM_short_circuit) {
SUBCASE(param.case_name.c_str()) { validate_batch_case(param); }
}
}
Expand Down
1 change: 1 addition & 0 deletions tests/native_api_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set(PROJECT_SOURCES
"test_api_serialization.cpp"
"test_api_utils.cpp"
"test_api_model_multi_dimension.cpp"
"test_api_dataset.cpp"
)

add_executable(power_grid_model_api_tests ${PROJECT_SOURCES})
Expand Down
Loading
Loading