Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
5 changes: 4 additions & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
{
"name": "unix-sanitizer",
"environment": {
"SANITIZER_FLAGS": "-fsanitize=address"
"SANITIZER_FLAGS": "-fstack-protector -fsanitize=address,pointer-compare,undefined"
},
"inherits": "unix-base",
"hidden": true
Expand Down Expand Up @@ -137,6 +137,9 @@
{
"name": "msvc-debug",
"displayName": "Debug (MSVC)",
"environment": {
"SANITIZER_FLAGS": "/RTC1"
},
"inherits": [
"msvc-base",
"debug"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ class ColumnarAttributeRange : public std::ranges::view_interface<ColumnarAttrib
for (auto const& attribute_buffer : attribute_buffers_) {
assert(attribute_buffer.meta_attribute != nullptr);
auto const& meta_attribute = *attribute_buffer.meta_attribute;
ctype_func_selector(
meta_attribute.ctype, [&result, &attribute_buffer, &meta_attribute, this]<typename AttributeType> {
AttributeType const* buffer_ptr =
reinterpret_cast<AttributeType const*>(attribute_buffer.data) + idx_;
auto& attribute_ref =
meta_attribute.template get_attribute<AttributeType>(reinterpret_cast<RawDataPtr>(&result));
attribute_ref = *buffer_ptr;
});
ctype_func_selector(meta_attribute.ctype, [&result, &attribute_buffer, &meta_attribute,
idx = idx_]<typename AttributeType> {
AttributeType const* buffer_ptr =
reinterpret_cast<AttributeType const*>(attribute_buffer.data) + idx;
AttributeType& attribute_ref =
meta_attribute.template get_attribute<AttributeType>(reinterpret_cast<RawDataPtr>(&result));
attribute_ref = *buffer_ptr;
});
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,9 @@ template <symmetry_tag sym> class YBus {
std::shared_ptr<MathModelParam<sym> const> const& param,
std::shared_ptr<YBusStructure const> const& y_bus_struct = {})
: math_topology_{topo_ptr} {
assert(math_topology_ != nullptr);
assert(param != nullptr);

// use existing struct or make new struct
if (y_bus_struct) {
y_bus_struct_ = y_bus_struct;
Expand Down Expand Up @@ -447,36 +450,41 @@ template <symmetry_tag sym> class YBus {
template <typename T>
requires std::same_as<T, BranchSolverOutput<sym>> || std::same_as<T, BranchShortCircuitSolverOutput<sym>>
std::vector<T> calculate_branch_flow(ComplexValueVector<sym> const& u) const {
std::vector<T> branch_flow(math_topology_->branch_bus_idx.size());
std::transform(math_topology_->branch_bus_idx.cbegin(), math_topology_->branch_bus_idx.cend(),
math_model_param_->branch_param.cbegin(), branch_flow.begin(),
[&u](BranchIdx branch_idx, BranchCalcParam<sym> const& param) {
auto const [f, t] = branch_idx;
// if one side is disconnected, use zero voltage at that side
ComplexValue<sym> const uf = f != -1 ? u[f] : ComplexValue<sym>{0.0};
ComplexValue<sym> const ut = t != -1 ? u[t] : ComplexValue<sym>{0.0};
T output;

// See "Branch Flow Calculation" in "State Estimation Alliander"
output.i_f = dot(param.yff(), uf) + dot(param.yft(), ut);
output.i_t = dot(param.ytf(), uf) + dot(param.ytt(), ut);

if constexpr (std::same_as<T, BranchSolverOutput<sym>>) {
// See "Shunt Injection Flow Calculation" in "State Estimation Alliander"
output.s_f = uf * conj(output.i_f);
output.s_t = ut * conj(output.i_t);
}

return output;
});
return branch_flow;
assert(math_topology_ != nullptr);

return std::views::zip(std::as_const(math_topology_->branch_bus_idx),
std::as_const(math_model_param_->branch_param)) |
std::views::transform([&u](auto const& branch_idx_params) -> T {
auto const& [branch_idx, param] = branch_idx_params;

auto const [f, t] = branch_idx;
// if one side is disconnected, use zero voltage at that side
ComplexValue<sym> const uf = f != -1 ? u[f] : ComplexValue<sym>{0.0};
ComplexValue<sym> const ut = t != -1 ? u[t] : ComplexValue<sym>{0.0};
T output;

// See "Branch Flow Calculation" in "State Estimation Alliander"
output.i_f = dot(param.yff(), uf) + dot(param.yft(), ut);
output.i_t = dot(param.ytf(), uf) + dot(param.ytt(), ut);

if constexpr (std::same_as<T, BranchSolverOutput<sym>>) {
// See "Shunt Injection Flow Calculation" in "State Estimation Alliander"
output.s_f = uf * conj(output.i_f);
output.s_t = ut * conj(output.i_t);
}

return output;
}) |
std::ranges::to<std::vector<T>>();
}

// calculate shunt flow based on voltage, injection direction
template <typename SolverOutputType>
requires std::same_as<SolverOutputType, ApplianceSolverOutput<sym>> ||
std::same_as<SolverOutputType, ApplianceShortCircuitSolverOutput<sym>>
std::vector<SolverOutputType> calculate_shunt_flow(ComplexValueVector<sym> const& u) const {
assert(math_topology_ != nullptr);

std::vector<SolverOutputType> shunt_flow(math_topology_->n_shunt());
for (auto const [bus, shunts] : enumerated_zip_sequence(math_topology_->shunts_per_bus)) {
for (Idx const shunt : shunts) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,9 @@ class Topology {
};
// k as branch number for 2-way branch
for (auto const& [idx, branch_node_idx, branch_connected] :
std::views::zip(std::views::iota(0), comp_topo_.branch_node_idx, comp_conn_.branch_connected)) {
assert(std::ssize(branch_connected) == 2); // NOSONAR(R354)
std::views::zip(std::views::iota(0), std::as_const(comp_topo_.branch_node_idx),
std::as_const(comp_conn_.branch_connected))) {
assert(std::ssize(branch_connected) == 2);

auto const [i, j] = branch_node_idx;
IntS const i_status = branch_connected[0];
Expand Down Expand Up @@ -387,8 +388,9 @@ class Topology {
}
// k as branch number for 3-way branch
for (auto const& [idx, i, i_status, j_math] :
std::views::zip(std::views::iota(0), comp_topo_.branch3_node_idx, comp_conn_.branch3_connected,
std::views::drop(comp_coup_.node, comp_topo_.n_node))) {
std::views::zip(std::views::iota(0), std::as_const(comp_topo_.branch3_node_idx),
std::as_const(comp_conn_.branch3_connected),
std::views::drop(std::as_const(comp_coup_.node), comp_topo_.n_node))) {
std::array<Idx2D, 3> const i_math{
comp_coup_.node[i[0]],
comp_coup_.node[i[1]],
Expand Down Expand Up @@ -553,7 +555,8 @@ class Topology {
std::ranges::for_each(math_topology_,
[](MathModelTopology& topo) { topo.load_gen_type.resize(topo.n_load_gen()); });
// assign load type
for (auto const& [idx_math, load_gen_type] : std::views::zip(comp_coup_.load_gen, comp_topo_.load_gen_type)) {
for (auto const& [idx_math, load_gen_type] :
std::views::zip(std::as_const(comp_coup_.load_gen), std::as_const(comp_topo_.load_gen_type))) {
if (idx_math.group == -1) {
continue;
}
Expand Down
26 changes: 26 additions & 0 deletions power_grid_model_c/power_grid_model_c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,32 @@ set_target_properties(
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE
)

# Always-on hardening
target_compile_definitions(
power_grid_model_c
PRIVATE
"$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>>:_FORTIFY_SOURCE=2>"
"$<$<CXX_COMPILER_ID:MSVC>:_ITERATOR_DEBUG_LEVEL=$<IF:$<CONFIG:DEBUG>,2,1>>"
)
target_compile_options(
power_grid_model_c
BEFORE
PRIVATE
"$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>>:-fstack-protector;-fsanitize=undefined>"
"$<$<CXX_COMPILER_ID:GNU>:-static-libubsan>"
"$<$<CXX_COMPILER_ID:Clang>:-lubsan>"
"$<$<AND:$<CXX_COMPILER_ID:Clang>,$<NOT:$<OR:$<IN_LIST:address,${CMAKE_CFLAGS}>,$<IN_LIST:address,${CMAKE_CXXFLAGS}>>>>:-fsanitize-minimal-runtime>"
)
target_link_options(
power_grid_model_c
BEFORE
PRIVATE
"$<$<OR:$<CXX_COMPILER_ID:GNU>,$<CXX_COMPILER_ID:Clang>>:-fstack-protector;-fsanitize=undefined>"
"$<$<CXX_COMPILER_ID:GNU>:-static-libubsan>"
"$<$<CXX_COMPILER_ID:Clang>:-lubsan>"
"$<$<AND:$<CXX_COMPILER_ID:Clang>,$<NOT:$<IN_LIST:address,${CMAKE_LDFLAGS}>>>:-fsanitize-minimal-runtime>"
)

install(
TARGETS power_grid_model_c
EXPORT power_grid_modelTargets
Expand Down
5 changes: 5 additions & 0 deletions tests/native_api_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ target_compile_definitions(
PRIVATE PGM_ENABLE_EXPERIMENTAL
)

set_target_properties(
power_grid_model_api_tests
PROPERTIES BUILD_RPATH $<TARGET_FILE_DIR:power_grid_model_c>
)

doctest_discover_tests(power_grid_model_api_tests)
Loading