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
7 changes: 7 additions & 0 deletions .github/workflows/build-test-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,13 @@ jobs:
name: version
path: .

- name: Set up gcc
if: runner.os == 'Linux'
run: |
sudo apt-get install -y ninja-build gcc-14 g++-14
sudo ln -s /usr/bin/gcc-14 /usr/local/bin/gcc
sudo ln -s /usr/bin/g++-14 /usr/local/bin/g++

- uses: ./.github/actions/enable-msvc
if: runner.os == 'Windows'

Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ include("cmake/pgm_version.cmake")
project(power_grid_model VERSION ${PGM_VERSION})

option(PGM_ENABLE_DEV_BUILD "Enable developer build (e.g.: tests)" OFF)
option(PGM_ENABLE_HARDENING "Enable compile and link time hardening options" ON)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand Down
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"
},
Comment on lines +140 to +142
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this also to the CMakeLists?

"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 @@ -28,7 +28,7 @@ template <class T> using EigenDiagonalTensor3 = Eigen::DiagonalMatrix<T, 3>;

template <scalar_value T> class Vector : public EigenVector3<T> {
public:
Vector() { (*this) = EigenVector3<T>::Zero(); };
Vector() { this->setConstant(T{}); };
// eigen expression
template <typename OtherDerived> Vector(Eigen::ArrayBase<OtherDerived> const& other) : EigenVector3<T>{other} {}
template <typename OtherDerived> Vector& operator=(Eigen::ArrayBase<OtherDerived> const& other) {
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,40 @@ 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(math_topology_->branch_bus_idx, 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
27 changes: 27 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,33 @@ set_target_properties(
INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE
)

if(PGM_ENABLE_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>>"
)
if(NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
set(_HAS_ADDRESS_SANITIZER
"$<NOT:$<OR:$<IN_LIST:address,${CMAKE_CFLAGS}>,$<IN_LIST:address,${CMAKE_CXXFLAGS}>>>"
)
target_compile_options(
power_grid_model_c
BEFORE
PRIVATE "-fstack-protector" "-fsanitize=undefined"
)
endif()
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>"
)
endif()

install(
TARGETS power_grid_model_c
EXPORT power_grid_modelTargets
Expand Down
2 changes: 1 addition & 1 deletion power_grid_model_c/power_grid_model_c/src/dataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ using power_grid_model_c::to_c_size;
// dataset info

char const* PGM_dataset_info_name(PGM_Handle* handle, PGM_DatasetInfo const* info) {
return call_with_catch(handle, [info] { return safe_ptr_get(safe_ptr(info)->dataset).name; });
return call_with_catch(handle, [info] { return safe_ptr_get(safe_ptr_get(info).dataset).name; });
}

PGM_Idx PGM_dataset_info_is_batch(PGM_Handle* handle, PGM_DatasetInfo const* info) {
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 @@ -31,4 +31,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>
)

Comment on lines +34 to +38
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be removed

doctest_discover_tests(power_grid_model_api_tests)
Loading