Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental Y-Bus admittance matrix update #444

Merged
Show file tree
Hide file tree
Changes from 67 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
f551e8b
Incremental updates with decrement functionality, implemented without…
Jerry-Jinfeng-Guo Dec 5, 2023
5a96194
fixed minor sign error with decrement
Jerry-Jinfeng-Guo Dec 5, 2023
74f5d82
Fixed type cast complaints on linux/macos compilers; added logic to p…
Jerry-Jinfeng-Guo Dec 6, 2023
ada5e76
Added function interface in the `update.hpp`; next to add `std::view`…
Jerry-Jinfeng-Guo Dec 6, 2023
17548e5
Removed code 3 smells
Jerry-Jinfeng-Guo Dec 6, 2023
c5bf91d
Minor fix: clang tidy doesn't like copy constructor
Jerry-Jinfeng-Guo Dec 8, 2023
04c7796
Updated several duplicated code; better naming of variable (to avoid …
Jerry-Jinfeng-Guo Dec 18, 2023
aa7c7a5
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Dec 18, 2023
e1abfef
fix clang-tidy warning
Jerry-Jinfeng-Guo Dec 18, 2023
28c21d3
Re-worked function structures
Jerry-Jinfeng-Guo Dec 19, 2023
a67f779
range copy fix
Jerry-Jinfeng-Guo Dec 19, 2023
d8eff9b
clang-tidy
Jerry-Jinfeng-Guo Dec 19, 2023
e0c57a7
Test case work in progress
Jerry-Jinfeng-Guo Dec 19, 2023
62e8678
Test case on the `y_bus` itself
Jerry-Jinfeng-Guo Dec 20, 2023
7ecb109
Fixed an index error: admittance matrix entry <-> parameter map
Jerry-Jinfeng-Guo Dec 20, 2023
a817271
clang tidy
Jerry-Jinfeng-Guo Dec 21, 2023
82d02c7
Reverted to `boost` for `iota`; fixed couple other things like functi…
Jerry-Jinfeng-Guo Dec 21, 2023
3581ef8
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Dec 21, 2023
83e7ce8
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
mgovers Dec 22, 2023
f968f8a
Fully boost; simplified a couple duplication in lambda; lowered UPPER…
Jerry-Jinfeng-Guo Dec 22, 2023
b2a89d3
[WIP] Draft integration: changed from delta based increment to whole …
Jerry-Jinfeng-Guo Jan 2, 2024
6e8392f
Integration. Increment\decrement\delta-based update.
Jerry-Jinfeng-Guo Jan 3, 2024
a51ca64
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Jan 4, 2024
a010452
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Jan 4, 2024
3067db8
Refactored the code; no more delta based in-/de-crements; swap based …
Jerry-Jinfeng-Guo Jan 5, 2024
fa69783
Brief code cleaning-up
Jerry-Jinfeng-Guo Jan 8, 2024
64dc9ac
Retouched the test case
Jerry-Jinfeng-Guo Jan 8, 2024
7ad1a67
Minor code smell removal
Jerry-Jinfeng-Guo Jan 8, 2024
78ae4b5
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Jan 10, 2024
2bcc366
Manually merge conflict fix; namespace math_model_impl -> math_solver
Jerry-Jinfeng-Guo Jan 10, 2024
c9fd978
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
mgovers Jan 11, 2024
a4eece8
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Jan 16, 2024
2a2ff1a
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Jan 16, 2024
59a8a7d
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
mgovers Jan 17, 2024
409ea24
Tentative implementation integrating progressive `update_y_bus` with …
Jerry-Jinfeng-Guo Jan 19, 2024
5448fb3
Changes not included due to merger from master
Jerry-Jinfeng-Guo Jan 22, 2024
7231ecc
Suppress some compiler warnings.
Jerry-Jinfeng-Guo Jan 22, 2024
da1330a
minor fix
Jerry-Jinfeng-Guo Jan 22, 2024
d7b3acb
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
mgovers Jan 23, 2024
04f8ed3
Fix and cleaned up the implementation.
Jerry-Jinfeng-Guo Jan 23, 2024
9e69d74
Code cleaning up. `set` to `vector` correction.
Jerry-Jinfeng-Guo Jan 24, 2024
382c4dc
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Jan 24, 2024
bb0d92d
Changes processing review comments
Jerry-Jinfeng-Guo Jan 24, 2024
1f3199e
Minor improvement. string lookup avoided.
Jerry-Jinfeng-Guo Jan 25, 2024
ab3b523
Removed decrement logic from `y_bus`
Jerry-Jinfeng-Guo Jan 26, 2024
5d92cd6
Processed review comments.
Jerry-Jinfeng-Guo Jan 26, 2024
25f0392
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Jan 26, 2024
5c5dd69
Review comments processing.
Jerry-Jinfeng-Guo Jan 26, 2024
8153eb6
Added `sequence_index_map` accumulation logic for repeated `update` call
Jerry-Jinfeng-Guo Jan 26, 2024
ab20979
Minor update main_model.hpp
Jerry-Jinfeng-Guo Jan 26, 2024
0a94100
Update main_model.hpp
Jerry-Jinfeng-Guo Jan 26, 2024
274a5a1
Update the `sequence_idx_map` accumulation logic to simply just accum…
Jerry-Jinfeng-Guo Jan 29, 2024
63b1e8a
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Jan 29, 2024
68f41a7
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
mgovers Jan 30, 2024
19346c1
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
mgovers Jan 30, 2024
b449278
fix asym/sym switching edge case
mgovers Feb 1, 2024
1f3f936
Merge branch 'feature/DGC-1950-Incrementally-update-topology-paramete…
mgovers Feb 1, 2024
f6726d6
remove unused functions
mgovers Feb 1, 2024
616b6df
sonar cloud
mgovers Feb 1, 2024
97750dd
Sonar cloud, attempt 2
Jerry-Jinfeng-Guo Feb 1, 2024
8a40ef1
Sonar cloud, attempt 3
Jerry-Jinfeng-Guo Feb 1, 2024
19c95ee
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Feb 2, 2024
9179778
Added test case for the new sym/asym alternating compute mode logic i…
Jerry-Jinfeng-Guo Feb 2, 2024
e09021d
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Feb 2, 2024
5885897
Test case reworked; cleaned unneeded headers
Jerry-Jinfeng-Guo Feb 2, 2024
dc270b3
improve test case
mgovers Feb 5, 2024
57d3487
fix sonar cloud code smells
mgovers Feb 5, 2024
34f4050
fix more code smells
mgovers Feb 5, 2024
c67781d
Merge branch 'main' into feature/DGC-1950-Incrementally-update-topolo…
Jerry-Jinfeng-Guo Feb 5, 2024
3bb8ac0
params changed callback from ybus to math solver
mgovers Feb 5, 2024
f1161cc
clang-tidy pleasing
Jerry-Jinfeng-Guo Feb 5, 2024
bf404f6
resolve code smells
mgovers Feb 5, 2024
5f211c6
copy of admittance
mgovers Feb 5, 2024
8dbf135
make ybus owner of admittance data
mgovers Feb 5, 2024
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 @@ -159,6 +159,11 @@ template <bool sym> struct MathModelParam {
ComplexTensorVector<sym> source_param;
};

struct MathModelParamIncrement {
std::vector<Idx> branch_param_to_change; // indices of changed branch_param
std::vector<Idx> shunt_param_to_change; // indices of changed shunt_param
};

template <bool sym> struct PowerFlowInput {
ComplexVector source; // Complex u_ref of each source
ComplexValueVector<sym> s_injection; // Specified injection power of each load_gen
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,20 @@ class Container<RetrievableTypes<GettableTypes...>, StorageableTypes...> {
return size_[get_cls_pos_v<Gettable, GettableTypes...>];
}

// get sequence idx based on idx_2d
// E.g. when you know the idx_2d of the derived class but want to know the index of the base class getter
template <class Gettable> Idx get_seq(Idx2D idx_2d) const {
assert(construction_complete_);
std::array<Idx, num_storageable + 1> const& cum_size = cum_size_[get_cls_pos_v<Gettable, GettableTypes...>];
return cum_size[idx_2d.group] + idx_2d.pos;
}

// get sequence idx based on id
template <class Gettable> Idx get_seq(ID id) const {
assert(construction_complete_);
std::array<Idx, num_storageable + 1> const& cum_size = cum_size_[get_cls_pos_v<Gettable, GettableTypes...>];
auto const found = map_.find(id);
assert(found != map_.end());
return cum_size[found->second.group] + found->second.pos;
return get_seq<Gettable>(found->second);
}

// get idx_2d based on sequence
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,30 @@ inline std::vector<Idx2D> get_component_sequence(MainModelState<ComponentContain
// using forward interators
// different selection based on component type
// if sequence_idx is given, it will be used to load the object instead of using IDs via hash map.
template <std::derived_from<Base> Component, class ComponentContainer, std::forward_iterator ForwardIterator>
template <std::derived_from<Base> Component, class ComponentContainer, std::forward_iterator ForwardIterator,
std::output_iterator<Idx2D> OutputIterator>
requires model_component_state<MainModelState, ComponentContainer, Component>
inline UpdateChange update_component(MainModelState<ComponentContainer>& state, ForwardIterator begin,
ForwardIterator end, std::vector<Idx2D> const& sequence_idx = {}) {
ForwardIterator end, OutputIterator changed_it,
std::vector<Idx2D> const& sequence_idx = {}) {
using UpdateType = typename Component::UpdateType;

UpdateChange changed;
UpdateChange state_changed;

detail::iterate_component_sequence<Component>(
[&changed, &state](UpdateType const& update_data, Idx2D const& sequence_single) {
[&state_changed, &changed_it, &state](UpdateType const& update_data, Idx2D const& sequence_single) {
auto& comp = state.components.template get_item<Component>(sequence_single);
changed = changed || comp.update(update_data);
auto const comp_changed = comp.update(update_data);

state_changed = state_changed || comp_changed;

if (comp_changed.param || comp_changed.topo) {
*changed_it++ = sequence_single;
}
},
begin, end, sequence_idx);

return changed;
return state_changed;
}

// template to get the inverse update for components
Expand All @@ -97,23 +105,42 @@ inline void update_inverse(MainModelState<ComponentContainer> const& state, Forw
}

template <bool sym>
inline void update_y_bus(YBus<sym>& y_bus, std::shared_ptr<MathModelParam<sym> const> const& math_model_param) {
y_bus.update_admittance(math_model_param);
inline void update_y_bus(MathState& math_state, std::vector<MathModelParam<sym>> const& math_model_params) {
auto& y_bus_vec = [&math_state]() -> auto& {
if constexpr (sym) {
return math_state.y_bus_vec_sym;
} else {
return math_state.y_bus_vec_asym;
}
}
();

assert(y_bus_vec.size() == math_model_params.size());

for (Idx i = 0; i != static_cast<Idx>(y_bus_vec.size()); ++i) {
y_bus_vec[i].update_admittance(std::make_shared<MathModelParam<sym> const>(std::move(math_model_params[i])));
}
}

template <bool sym>
inline void update_y_bus(MathState& math_state, std::vector<MathModelParam<sym>> const& math_model_params,
Idx n_math_solvers) {
for (Idx i = 0; i != n_math_solvers; ++i) {
std::vector<MathModelParamIncrement> const& math_model_param_increments) {
auto& y_bus_vec = [&math_state]() -> auto& {
if constexpr (sym) {
update_y_bus(math_state.y_bus_vec_sym[i],
std::make_shared<MathModelParam<sym> const>(std::move(math_model_params[i])));

return math_state.y_bus_vec_sym;
} else {
update_y_bus(math_state.y_bus_vec_asym[i],
std::make_shared<MathModelParam<sym> const>(std::move(math_model_params[i])));
return math_state.y_bus_vec_asym;
}
}
();

assert(y_bus_vec.size() == math_model_params.size());

for (Idx i = 0; i != static_cast<Idx>(y_bus_vec.size()); ++i) {
y_bus_vec[i].update_admittance_increment(
std::make_shared<MathModelParam<sym> const>(std::move(math_model_params[i])),
math_model_param_increments[i]);
}
}

} // namespace power_grid_model::main_core
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,17 +152,18 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
// if sequence_idx is given, it will be used to load the object instead of using IDs via hash map.
template <class CompType, class CacheType, std::forward_iterator ForwardIterator>
void update_component(ForwardIterator begin, ForwardIterator end, std::vector<Idx2D> const& sequence_idx) {
constexpr auto comp_index = AllComponents::template index_of<CompType>();

assert(construction_complete_);
assert(static_cast<ptrdiff_t>(sequence_idx.size()) == std::distance(begin, end));

if constexpr (CacheType::value) {
constexpr auto comp_index = AllComponents::template index_of<CompType>();

main_core::update_inverse<CompType>(
state_, begin, end, std::back_inserter(std::get<comp_index>(cached_inverse_update_)), sequence_idx);
}

UpdateChange const changed = main_core::update_component<CompType>(state_, begin, end, sequence_idx);
UpdateChange const changed = main_core::update_component<CompType>(
state_, begin, end, std::back_inserter(std::get<comp_index>(parameter_changed_components_)), sequence_idx);

// update, get changed variable
update_state(changed);
Expand Down Expand Up @@ -748,7 +749,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
}

template <typename Component, math_output_type MathOutputType, std::forward_iterator ResIt>
ResIt output_result(std::vector<MathOutputType> const& math_output, ResIt res_it) {
ResIt output_result(std::vector<MathOutputType> const& math_output, ResIt res_it) const {
assert(construction_complete_);
return main_core::output_result<Component, ComponentContainer>(state_, math_output, res_it);
}
Expand Down Expand Up @@ -783,7 +784,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
}
}

CalculationInfo calculation_info() { return calculation_info_; }
CalculationInfo calculation_info() const { return calculation_info_; }

private:
CalculationInfo calculation_info_; // needs to be first due to padding override
Expand All @@ -797,9 +798,12 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
bool is_topology_up_to_date_{false};
bool is_sym_parameter_up_to_date_{false};
bool is_asym_parameter_up_to_date_{false};
bool is_accumulated_component_updated_{true};
bool last_updated_calculation_symmetry_mode_{false};

OwnedUpdateDataset cached_inverse_update_{};
UpdateChange cached_state_changes_{};
std::array<std::vector<Idx2D>, n_types> parameter_changed_components_{};
#ifndef NDEBUG
// construction_complete is used for debug assertions only
bool construction_complete_{false};
Expand Down Expand Up @@ -877,7 +881,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
math_param[i].source_param.resize(state_.math_topology[i]->n_source());
}
// loop all branch
for (Idx i = 0; i != (Idx)state_.comp_topo->branch_node_idx.size(); ++i) {
for (Idx i = 0; i != static_cast<Idx>(state_.comp_topo->branch_node_idx.size()); ++i) {
Idx2D const math_idx = state_.topo_comp_coup->branch[i];
if (math_idx.group == -1) {
continue;
Expand All @@ -887,7 +891,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
state_.components.template get_item_by_seq<Branch>(i).template calc_param<sym>();
}
// loop all branch3
for (Idx i = 0; i != (Idx)state_.comp_topo->branch3_node_idx.size(); ++i) {
for (Idx i = 0; i != static_cast<Idx>(state_.comp_topo->branch3_node_idx.size()); ++i) {
Idx2DBranch3 const math_idx = state_.topo_comp_coup->branch3[i];
if (math_idx.group == -1) {
continue;
Expand All @@ -900,7 +904,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
}
}
// loop all shunt
for (Idx i = 0; i != (Idx)state_.comp_topo->shunt_node_idx.size(); ++i) {
for (Idx i = 0; i != static_cast<Idx>(state_.comp_topo->shunt_node_idx.size()); ++i) {
Idx2D const math_idx = state_.topo_comp_coup->shunt[i];
if (math_idx.group == -1) {
continue;
Expand All @@ -910,7 +914,7 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
state_.components.template get_item_by_seq<Shunt>(i).template calc_param<sym>();
}
// loop all source
for (Idx i = 0; i != (Idx)state_.comp_topo->source_node_idx.size(); ++i) {
for (Idx i = 0; i != static_cast<Idx>(state_.comp_topo->source_node_idx.size()); ++i) {
Idx2D const math_idx = state_.topo_comp_coup->source[i];
if (math_idx.group == -1) {
continue;
Expand All @@ -921,6 +925,56 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
}
return math_param;
}
template <bool sym> std::vector<MathModelParamIncrement> get_math_param_increment() {
using AddToIncrement = void (*)(std::vector<MathModelParamIncrement>&, MainModelState const&, Idx2D const&);

static constexpr std::array<AddToIncrement, n_types> add_to_increments{
[](std::vector<MathModelParamIncrement>& increments, MainModelState const& state,
Idx2D const& changed_component_idx) {
if constexpr (std::derived_from<ComponentType, Branch>) {
Idx2D const math_idx =
state.topo_comp_coup->branch[state.components.template get_seq<Branch>(changed_component_idx)];
if (math_idx.group == -1) {
return;
}
// assign parameters
increments[math_idx.group].branch_param_to_change.push_back(math_idx.pos);
} else if constexpr (std::derived_from<ComponentType, Branch3>) {
Idx2DBranch3 const math_idx =
state.topo_comp_coup
->branch3[state.components.template get_seq<Branch3>(changed_component_idx)];
if (math_idx.group == -1) {
return;
}
// assign parameters, branch3 param consists of three branch parameters
Jerry-Jinfeng-Guo marked this conversation as resolved.
Show resolved Hide resolved
// auto const branch3_param =
// state.components.template get_item<Branch3>(changed_component_idx).template calc_param<sym>();
for (size_t branch2 = 0; branch2 < 3; ++branch2) {
increments[math_idx.group].branch_param_to_change.push_back(math_idx.pos[branch2]);
}
} else if constexpr (std::same_as<ComponentType, Shunt>) {
Idx2D const math_idx =
state.topo_comp_coup->shunt[state.components.template get_seq<Shunt>(changed_component_idx)];
if (math_idx.group == -1) {
return;
}
// assign parameters
increments[math_idx.group].shunt_param_to_change.push_back(math_idx.pos);
}
}...};

std::vector<MathModelParamIncrement> math_param_increment(n_math_solvers_);

for (size_t i = 0; i < n_types; ++i) {
auto const& changed_type_components = parameter_changed_components_[i];
auto const& add_type_to_increment = add_to_increments[i];
for (auto const& changed_component : changed_type_components) {
add_type_to_increment(math_param_increment, state_, changed_component);
}
}

return math_param_increment;
}

static constexpr auto include_all = [](Idx) { return true; };

Expand Down Expand Up @@ -1181,6 +1235,12 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
y_bus_vec.reserve(n_math_solvers_);
auto math_params = get_math_param<sym>();

// Check the branch and shunt indices
constexpr auto branch_param_in_seq_map =
std::array{AllComponents::template index_of<Line>(), AllComponents::template index_of<Link>(),
AllComponents::template index_of<Transformer>()};
constexpr auto shunt_param_in_seq_map = std::array{AllComponents::template index_of<Shunt>()};

for (Idx i = 0; i != n_math_solvers_; ++i) {
// construct from existing Y_bus structure if possible
if (other_y_bus_exist) {
Expand All @@ -1191,6 +1251,11 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
y_bus_vec.emplace_back(state_.math_topology[i],
std::make_shared<MathModelParam<sym> const>(std::move(math_params[i])));
}

y_bus_vec.back().set_branch_param_idx(
IdxVector{branch_param_in_seq_map.begin(), branch_param_in_seq_map.end()});
y_bus_vec.back().set_shunt_param_idx(
IdxVector{shunt_param_in_seq_map.begin(), shunt_param_in_seq_map.end()});
}
}
}
Expand All @@ -1202,23 +1267,28 @@ class MainModelImpl<ExtraRetrievableTypes<ExtraRetrievableType...>, ComponentLis
rebuild_topology();
}
prepare_y_bus<sym>();
// if solvers do not exist, build them
if (n_math_solvers_ != (Idx)solvers.size()) {

if (n_math_solvers_ != static_cast<Idx>(solvers.size())) {
assert(solvers.empty());
assert(n_math_solvers_ == static_cast<Idx>(state_.math_topology.size()));

solvers.clear();
solvers.reserve(n_math_solvers_);
// loop to build
for (Idx i = 0; i != n_math_solvers_; ++i) {
solvers.emplace_back(state_.math_topology[i]);
}
}
// if parameters are not up to date, update them
else if (!is_parameter_up_to_date<sym>()) {
// get param, will be consumed
std::ranges::transform(state_.math_topology, std::back_inserter(solvers),
[](auto math_topo) { return MathSolver<sym>{std::move(math_topo)}; });
} else if (!is_parameter_up_to_date<sym>()) {
std::vector<MathModelParam<sym>> const math_params = get_math_param<sym>();
main_core::update_y_bus(math_state_, math_params, n_math_solvers_);
std::vector<MathModelParamIncrement> const math_param_increments = get_math_param_increment<sym>();
if (last_updated_calculation_symmetry_mode_ == sym) {
main_core::update_y_bus(math_state_, math_params, math_param_increments);
} else {
main_core::update_y_bus(math_state_, math_params);
}
}
// else do nothing, set everything up to date
is_parameter_up_to_date<sym>() = true;
std::ranges::for_each(parameter_changed_components_, [](auto& comps) { comps.clear(); });
last_updated_calculation_symmetry_mode_ = sym;
}
};

Expand Down
Loading
Loading