diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/calculation_preparation.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/calculation_preparation.hpp new file mode 100644 index 000000000..ef47be30f --- /dev/null +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/calculation_preparation.hpp @@ -0,0 +1,180 @@ +// SPDX-FileCopyrightText: Contributors to the Power Grid Model project +// +// SPDX-License-Identifier: MPL-2.0 + +#pragma once + +#include "topology.hpp" + +#include "common/common.hpp" + +#include "math_solver/math_solver_dispatch.hpp" + +#include "main_core/main_model_type.hpp" +#include "main_core/math_state.hpp" +#include "main_core/topology.hpp" +#include "main_core/y_bus.hpp" + +namespace power_grid_model { +struct SolverPreparationContext { + main_core::MathState math_state; + MathSolverDispatcher const* math_solver_dispatcher; +}; + +template + requires(main_core::is_main_model_type_v) +class SolversCacheStatus { + public: + using SequenceIdx = typename ModelType::SequenceIdx; + + private: + struct YBusParameterCacheValidity { + bool sym{false}; + bool asym{false}; + }; + + enum class SymmetryMode : IntS { symmetric = 0, asymmetric = 1, not_set = na_IntS }; + + bool topology_cache_validity{false}; + YBusParameterCacheValidity parameter_cache_validity{}; + SymmetryMode previous_symmetry_mode{SymmetryMode::not_set}; + SequenceIdx changed_components_indices_{}; + + public: + SequenceIdx const& changed_components_indices() const { return changed_components_indices_; } + SequenceIdx& changed_components_indices() { return changed_components_indices_; } + void clear_changed_components_indices() { + std::ranges::for_each(changed_components_indices(), [](auto& comps) { comps.clear(); }); + } + + bool is_topology_valid() const { return topology_cache_validity; } + void set_topology_status(bool topology) { topology_cache_validity = topology; } + + template bool is_parameter_valid() const { + if constexpr (is_symmetric_v) { + return parameter_cache_validity.sym; + } else { + return parameter_cache_validity.asym; + } + } + template void set_parameter_status(bool parameter) { + if constexpr (is_symmetric_v) { + parameter_cache_validity.sym = parameter; + } else { + parameter_cache_validity.asym = parameter; + } + } + + template bool is_symmetry_mode_conserved() const { + if (previous_symmetry_mode == SymmetryMode::not_set) { + return false; // No previous calculation + } + + if constexpr (is_symmetric_v) { + return previous_symmetry_mode == SymmetryMode::symmetric; + } else { + return previous_symmetry_mode == SymmetryMode::asymmetric; + } + } + template void set_previous_symmetry_mode() { + if constexpr (is_symmetric_v) { + previous_symmetry_mode = SymmetryMode::symmetric; + } else { + previous_symmetry_mode = SymmetryMode::asymmetric; + } + } + + void update(UpdateChange const& changes) { + // if topology changed, everything is not up to date + // if only param changed, set param to not up to date + if (changes.topo || !is_topology_valid()) { + set_topology_status(false); + set_parameter_status(false); + set_parameter_status(false); + return; + } + + set_topology_status(true); + if (changes.param) { + set_parameter_status(false); + set_parameter_status(false); + return; + } + set_parameter_status(is_parameter_valid()); + set_parameter_status(is_parameter_valid()); + } +}; + +namespace detail { +template +void reset_solvers(typename ModelType::MainModelState& state, SolverPreparationContext& solver_context, + SolversCacheStatus& solvers_cache_status) { + solvers_cache_status.set_topology_status(false); + solvers_cache_status.template set_parameter_status(false); + solvers_cache_status.template set_parameter_status(false); + main_core::clear(solver_context.math_state); + state.math_topology.clear(); + state.topo_comp_coup.reset(); + state.comp_coup = {}; +} + +template +void rebuild_topology(typename ModelType::MainModelState& state, SolverPreparationContext& solver_context, + SolversCacheStatus& solvers_cache_status) { + // clear old solvers + reset_solvers(state, solver_context, solvers_cache_status); + ComponentConnections const comp_conn = main_core::construct_components_connections(state.components); + // re build + Topology topology{*state.comp_topo, comp_conn}; + std::tie(state.math_topology, state.topo_comp_coup) = topology.build_topology(); + solvers_cache_status.set_topology_status(true); + solvers_cache_status.template set_parameter_status(false); + solvers_cache_status.template set_parameter_status(false); +} +} // namespace detail + +template Idx get_n_math_solvers(typename ModelType::MainModelState const& state) { + return static_cast(state.math_topology.size()); +} + +template +void prepare_solvers(typename ModelType::MainModelState& state, SolverPreparationContext& solver_context, + SolversCacheStatus& solvers_cache_status) { + std::vector>& solvers = main_core::get_solvers(solver_context.math_state); + // rebuild topology if needed + if (!solvers_cache_status.is_topology_valid()) { + detail::rebuild_topology(state, solver_context, solvers_cache_status); + } + Idx const n_math_solvers = get_n_math_solvers(state); + main_core::prepare_y_bus(state, n_math_solvers, solver_context.math_state); + if (n_math_solvers != static_cast(solvers.size())) { + assert(solvers.empty()); + assert(n_math_solvers == static_cast(main_core::get_y_bus(solver_context.math_state).size())); + + solvers.clear(); + solvers.reserve(n_math_solvers); + std::ranges::transform(state.math_topology, std::back_inserter(solvers), + [&solver_context](auto const& math_topo) { + return MathSolverProxy{solver_context.math_solver_dispatcher, math_topo}; + }); + for (Idx idx = 0; idx < n_math_solvers; ++idx) { + main_core::get_y_bus(solver_context.math_state)[idx].register_parameters_changed_callback( + [solver = std::ref(solvers[idx])](bool changed) { solver.get().get().parameters_changed(changed); }); + } + } else if (!solvers_cache_status.template is_parameter_valid()) { + std::vector> const math_params = main_core::get_math_param(state, n_math_solvers); + if (solvers_cache_status.template is_symmetry_mode_conserved()) { + std::vector const math_param_increments = + main_core::get_math_param_increment(state, n_math_solvers, + solvers_cache_status.changed_components_indices()); + main_core::update_y_bus(solver_context.math_state, math_params, math_param_increments); + } else { + main_core::update_y_bus(solver_context.math_state, math_params); + } + } + // else do nothing, set everything up to date + solvers_cache_status.template set_parameter_status(true); + solvers_cache_status.clear_changed_components_indices(); + solvers_cache_status.template set_previous_symmetry_mode(); +} +} // namespace power_grid_model diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/calculation_input_preparation.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/calculation_input_preparation.hpp index f9dc0165c..4e6edd49d 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/calculation_input_preparation.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/calculation_input_preparation.hpp @@ -12,7 +12,6 @@ #include namespace power_grid_model::main_core { -constexpr Idx isolated_component{-1}; constexpr Idx not_connected{-1}; namespace detail { diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/y_bus.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/y_bus.hpp index 9f6a8b0cb..183abcfd9 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/y_bus.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_core/y_bus.hpp @@ -7,6 +7,7 @@ #include "../common/common.hpp" namespace power_grid_model::main_core { +constexpr Idx isolated_component{-1}; namespace detail { template ComponentType, typename ComponentContainer> diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp index b7cac93a1..f3f30e40c 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model.hpp @@ -25,10 +25,14 @@ class MainModel { explicit MainModel(double system_frequency, ConstDataset const& input_data, MathSolverDispatcher const& math_solver_dispatcher, Idx pos = 0) - : impl_{std::make_unique(system_frequency, input_data, math_solver_dispatcher, pos)} {} + : impl_{std::make_unique( + system_frequency, input_data, + SolverPreparationContext{.math_state = {}, .math_solver_dispatcher = &math_solver_dispatcher}, pos)} {} explicit MainModel(double system_frequency, meta_data::MetaData const& meta_data, MathSolverDispatcher const& math_solver_dispatcher) - : impl_{std::make_unique(system_frequency, meta_data, math_solver_dispatcher)} {}; + : impl_{std::make_unique( + system_frequency, meta_data, + SolverPreparationContext{.math_state = {}, .math_solver_dispatcher = &math_solver_dispatcher})} {}; // deep copy MainModel(MainModel const& other) { diff --git a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp index b785c5340..d376683be 100644 --- a/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp +++ b/power_grid_model_c/power_grid_model/include/power_grid_model/main_model_impl.hpp @@ -9,6 +9,7 @@ // main include #include "batch_parameter.hpp" #include "calculation_parameters.hpp" +#include "calculation_preparation.hpp" #include "container.hpp" #include "main_model_fwd.hpp" #include "topology.hpp" @@ -33,11 +34,9 @@ #include "main_core/calculation_input_preparation.hpp" #include "main_core/input.hpp" #include "main_core/main_model_type.hpp" -#include "main_core/math_state.hpp" #include "main_core/output.hpp" #include "main_core/topology.hpp" #include "main_core/update.hpp" -#include "main_core/y_bus.hpp" // stl library #include @@ -122,7 +121,6 @@ class MainModelImpl { private: // internal type traits - using ComponentContainer = typename ModelType::ComponentContainer; using MainModelState = typename ModelType::MainModelState; using SequenceIdx = typename ModelType::SequenceIdx; @@ -131,22 +129,17 @@ class MainModelImpl { using OwnedUpdateDataset = typename ModelType::OwnedUpdateDataset; using ComponentFlags = typename ModelType::ComponentFlags; - static constexpr Idx isolated_component{main_core::isolated_component}; - static constexpr Idx not_connected{main_core::not_connected}; - static constexpr Idx sequential{main_core::utils::sequential}; - public: using ImplType = ModelType; using Options = MainModelOptions; - using MathState = main_core::MathState; using MetaData = meta_data::MetaData; // constructor with data explicit MainModelImpl(double system_frequency, ConstDataset const& input_data, - MathSolverDispatcher const& math_solver_dispatcher, Idx pos = 0) + SolverPreparationContext solver_preparation_context, Idx pos = 0) : system_frequency_{system_frequency}, meta_data_{&input_data.meta_data()}, - math_solver_dispatcher_{&math_solver_dispatcher} { + solver_preparation_context_{std::move(solver_preparation_context)} { assert(input_data.get_description().dataset->name == std::string_view("input")); add_components(input_data, pos); set_construction_complete(); @@ -154,10 +147,10 @@ class MainModelImpl { // constructor with only frequency explicit MainModelImpl(double system_frequency, meta_data::MetaData const& meta_data, - MathSolverDispatcher const& math_solver_dispatcher) + SolverPreparationContext solver_preparation_context) : system_frequency_{system_frequency}, meta_data_{&meta_data}, - math_solver_dispatcher_{&math_solver_dispatcher} {} + solver_preparation_context_{std::move(solver_preparation_context)} {} // helper function to get what components are present in the update data ComponentFlags get_components_to_update(ConstDataset const& update_data) const { @@ -206,10 +199,10 @@ class MainModelImpl { UpdateChange const changed = main_core::update::update_component( state_.components, std::forward(updates), - std::back_inserter(std::get(parameter_changed_components_)), sequence_idx); + std::back_inserter(std::get(solvers_cache_status_.changed_components_indices())), sequence_idx); // update, get changed variable - update_state(changed); + solvers_cache_status_.update(changed); if constexpr (CacheType::value) { cached_state_changes_ = cached_state_changes_ || changed; } @@ -266,18 +259,6 @@ class MainModelImpl { std::make_shared(main_core::construct_topology(state_.components)); } - void reset_solvers() { - assert(construction_complete_); - is_topology_up_to_date_ = false; - is_sym_parameter_up_to_date_ = false; - is_asym_parameter_up_to_date_ = false; - n_math_solvers_ = 0; - main_core::clear(math_state_); - state_.math_topology.clear(); - state_.topo_comp_coup.reset(); - state_.comp_coup = {}; - } - public: /* the the sequence indexer given an input array of ID's for a given component type @@ -304,14 +285,6 @@ class MainModelImpl { components_to_update, update_independence, false); } - void update_state(UpdateChange const& changes) { - // if topology changed, everything is not up to date - // if only param changed, set param to not up to date - is_topology_up_to_date_ = is_topology_up_to_date_ && !changes.topo; - is_sym_parameter_up_to_date_ = is_sym_parameter_up_to_date_ && !changes.topo && !changes.param; - is_asym_parameter_up_to_date_ = is_asym_parameter_up_to_date_ && !changes.topo && !changes.param; - } - template void restore_component(SequenceIdxView const& sequence_idx) { constexpr auto component_index = ModelType::template index_of_component; @@ -330,7 +303,8 @@ class MainModelImpl { ModelType::run_functor_with_all_component_types_return_void( [this, &sequence_idx]() { this->restore_component(sequence_idx); }); - update_state(cached_state_changes_); + solvers_cache_status_.update(cached_state_changes_); + // we can probably reset topo, solvers and ybus here cached_state_changes_ = {}; } @@ -363,18 +337,20 @@ class MainModelImpl { // prepare auto const& input = [this, &logger, prepare_input_ = std::forward(prepare_input)] { Timer const timer{logger, LogEvent::prepare}; - prepare_solvers(); - assert(is_topology_up_to_date_ && is_parameter_up_to_date()); - return prepare_input_(n_math_solvers_); + assert(construction_complete_); + prepare_solvers(state_, solver_preparation_context_, solvers_cache_status_); + assert(solvers_cache_status_.is_topology_valid()); + assert(solvers_cache_status_.template is_parameter_valid()); + return prepare_input_(get_n_math_solvers(state_)); }(); // calculate return [this, &logger, &input, solve_ = std::forward(solve)] { Timer const timer{logger, LogEvent::math_calculation}; - auto& solvers = main_core::get_solvers(math_state_); - auto& y_bus_vec = main_core::get_y_bus(math_state_); + auto& solvers = main_core::get_solvers(solver_preparation_context_.math_state); + auto& y_bus_vec = main_core::get_y_bus(solver_preparation_context_.math_state); std::vector solver_output; - solver_output.reserve(n_math_solvers_); - for (Idx i = 0; i != n_math_solvers_; ++i) { + solver_output.reserve(get_n_math_solvers(state_)); + for (Idx i = 0; i != get_n_math_solvers(state_); ++i) { solver_output.emplace_back(solve_(solvers[i], y_bus_vec[i], input[i])); } return solver_output; @@ -424,7 +400,8 @@ class MainModelImpl { return calculate_, MathSolverProxy, YBus, ShortCircuitInput>( [this, voltage_scaling](Idx n_math_solvers) { - assert(is_topology_up_to_date_ && is_parameter_up_to_date()); + assert(solvers_cache_status_.is_topology_valid()); + assert(solvers_cache_status_.template is_parameter_valid()); return main_core::prepare_short_circuit_input(state_, state_.comp_coup, n_math_solvers, voltage_scaling); }, @@ -542,89 +519,19 @@ class MainModelImpl { double system_frequency_; MetaData const* meta_data_; - MathSolverDispatcher const* math_solver_dispatcher_; MainModelState state_; - // math model - MathState math_state_; - Idx n_math_solvers_{0}; - 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}; + + SolverPreparationContext solver_preparation_context_; + + SolversCacheStatus solvers_cache_status_{}; OwnedUpdateDataset cached_inverse_update_{}; UpdateChange cached_state_changes_{}; - SequenceIdx parameter_changed_components_{}; #ifndef NDEBUG // construction_complete is used for debug assertions only bool construction_complete_{false}; #endif // !NDEBUG - - template bool& is_parameter_up_to_date() { - if constexpr (is_symmetric_v) { - return is_sym_parameter_up_to_date_; - } else { - return is_asym_parameter_up_to_date_; - } - } - - void rebuild_topology() { - assert(construction_complete_); - // clear old solvers - reset_solvers(); - ComponentConnections const comp_conn = - main_core::construct_components_connections(state_.components); - // re build - Topology topology{*state_.comp_topo, comp_conn}; - std::tie(state_.math_topology, state_.topo_comp_coup) = topology.build_topology(); - n_math_solvers_ = static_cast(state_.math_topology.size()); - is_topology_up_to_date_ = true; - is_sym_parameter_up_to_date_ = false; - is_asym_parameter_up_to_date_ = false; - } - - template void prepare_solvers() { - std::vector>& solvers = main_core::get_solvers(math_state_); - // rebuild topology if needed - if (!is_topology_up_to_date_) { - rebuild_topology(); - } - main_core::prepare_y_bus(state_, n_math_solvers_, math_state_); - - if (n_math_solvers_ != static_cast(solvers.size())) { - assert(solvers.empty()); - assert(n_math_solvers_ == static_cast(state_.math_topology.size())); - assert(n_math_solvers_ == static_cast(main_core::get_y_bus(math_state_).size())); - - solvers.clear(); - solvers.reserve(n_math_solvers_); - std::ranges::transform(state_.math_topology, std::back_inserter(solvers), [this](auto const& math_topo) { - return MathSolverProxy{math_solver_dispatcher_, math_topo}; - }); - for (Idx idx = 0; idx < n_math_solvers_; ++idx) { - main_core::get_y_bus(math_state_)[idx].register_parameters_changed_callback( - [solver = std::ref(solvers[idx])](bool changed) { - solver.get().get().parameters_changed(changed); - }); - } - } else if (!is_parameter_up_to_date()) { - std::vector> const math_params = - main_core::get_math_param(state_, n_math_solvers_); - std::vector const math_param_increments = - main_core::get_math_param_increment(state_, n_math_solvers_, parameter_changed_components_); - if (last_updated_calculation_symmetry_mode_ == is_symmetric_v) { - 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() = true; - std::ranges::for_each(parameter_changed_components_, [](auto& comps) { comps.clear(); }); - last_updated_calculation_symmetry_mode_ = is_symmetric_v; - } }; } // namespace power_grid_model diff --git a/tests/cpp_unit_tests/CMakeLists.txt b/tests/cpp_unit_tests/CMakeLists.txt index 2bca8ecb1..16592f36f 100644 --- a/tests/cpp_unit_tests/CMakeLists.txt +++ b/tests/cpp_unit_tests/CMakeLists.txt @@ -128,6 +128,7 @@ add_executable( "test_container.cpp" "test_index_mapping.cpp" "test_job_dispatch.cpp" + "test_calculation_preparation.cpp" ) target_link_libraries( diff --git a/tests/cpp_unit_tests/test_calculation_preparation.cpp b/tests/cpp_unit_tests/test_calculation_preparation.cpp new file mode 100644 index 000000000..fbd2d2928 --- /dev/null +++ b/tests/cpp_unit_tests/test_calculation_preparation.cpp @@ -0,0 +1,96 @@ +// SPDX-FileCopyrightText: Contributors to the Power Grid Model project +// +// SPDX-License-Identifier: MPL-2.0 + +#include +#include +#include +#include + +#include + +namespace power_grid_model { +namespace { +using MainModelType = main_core::MainModelType; + +TEST_CASE("Test SolversCacheStatus") { + SUBCASE("Default construction") { + SolversCacheStatus const cache_status{}; + + CHECK_FALSE(cache_status.is_topology_valid()); + CHECK_FALSE(cache_status.is_parameter_valid()); + CHECK_FALSE(cache_status.is_parameter_valid()); + CHECK_FALSE(cache_status.is_symmetry_mode_conserved()); + CHECK_FALSE(cache_status.is_symmetry_mode_conserved()); + CHECK(cache_status.changed_components_indices() == MainModelType::SequenceIdx{}); + } + + SUBCASE("Setters and getters") { + SolversCacheStatus cache_status{}; + + // Topology status + cache_status.set_topology_status(true); + CHECK(cache_status.is_topology_valid()); + cache_status.set_topology_status(false); + CHECK_FALSE(cache_status.is_topology_valid()); + + // Parameter status + cache_status.set_parameter_status(true); + CHECK(cache_status.is_parameter_valid()); + CHECK_FALSE(cache_status.is_parameter_valid()); + + cache_status.set_parameter_status(true); + CHECK(cache_status.is_parameter_valid()); + CHECK(cache_status.is_parameter_valid()); + + cache_status.set_parameter_status(false); + CHECK_FALSE(cache_status.is_parameter_valid()); + CHECK(cache_status.is_parameter_valid()); + + // Symmetry mode + cache_status.set_previous_symmetry_mode(); + CHECK(cache_status.is_symmetry_mode_conserved()); + CHECK_FALSE(cache_status.is_symmetry_mode_conserved()); + + cache_status.set_previous_symmetry_mode(); + CHECK_FALSE(cache_status.is_symmetry_mode_conserved()); + CHECK(cache_status.is_symmetry_mode_conserved()); + + // Changed components indices + auto& indices = cache_status.changed_components_indices(); + std::get<0>(indices).push_back(Idx2D{0, 1}); + std::get<1>(indices).push_back(Idx2D{1, 2}); + CHECK(std::get<0>(cache_status.changed_components_indices())[0] == Idx2D{0, 1}); + CHECK(std::get<1>(cache_status.changed_components_indices())[0] == Idx2D{1, 2}); + + cache_status.clear_changed_components_indices(); + CHECK(std::ranges::all_of(cache_status.changed_components_indices(), + [](auto const& vec) { return vec.empty(); })); + } +} + +TEST_CASE("Test SolverPreparationContext") { + SUBCASE("Default construction") { + SolverPreparationContext const context{}; + + CHECK(context.math_solver_dispatcher == nullptr); + CHECK(context.math_state.y_bus_vec_sym.empty()); + CHECK(context.math_state.y_bus_vec_asym.empty()); + CHECK(context.math_state.math_solvers_sym.empty()); + CHECK(context.math_state.math_solvers_asym.empty()); + } + + SUBCASE("Dummy construction") { + MathSolverDispatcher const dispatcher{math_solver::math_solver_tag{}}; + SolverPreparationContext const context{.math_state = {}, .math_solver_dispatcher = &dispatcher}; + + CHECK(context.math_solver_dispatcher == &dispatcher); + CHECK(context.math_state.y_bus_vec_sym.empty()); + CHECK(context.math_state.y_bus_vec_asym.empty()); + CHECK(context.math_state.math_solvers_sym.empty()); + CHECK(context.math_state.math_solvers_asym.empty()); + } +} + +} // namespace +} // namespace power_grid_model diff --git a/tests/cpp_unit_tests/test_main_model_type.cpp b/tests/cpp_unit_tests/test_main_model_type.cpp index 59533a9b3..72ddd768b 100644 --- a/tests/cpp_unit_tests/test_main_model_type.cpp +++ b/tests/cpp_unit_tests/test_main_model_type.cpp @@ -2,6 +2,7 @@ // // SPDX-License-Identifier: MPL-2.0 +#include #include #include #include @@ -30,7 +31,7 @@ static_assert(!is_main_model_type_v> static_assert(!is_main_model_type_v>); static_assert(std::constructible_from>, double, - meta_data::MetaData const&, MathSolverDispatcher const&>); + meta_data::MetaData const&, SolverPreparationContext>); static_assert(detail::validate_component_types_c); @@ -57,7 +58,7 @@ TEST_CASE("MainModelType") { static_assert(ModelType::n_types == 2); static_assert(is_main_model_type_v); static_assert(std::constructible_from, double, meta_data::MetaData const&, - MathSolverDispatcher const&>); + SolverPreparationContext>); CHECK(ModelType::run_functor_with_all_component_types_return_array([]() { return std::string_view(CompType::name); @@ -89,7 +90,7 @@ TEST_CASE("MainModelType") { static_assert(ModelType::n_types == 3); static_assert(is_main_model_type_v); static_assert(std::constructible_from, double, meta_data::MetaData const&, - MathSolverDispatcher const&>); + SolverPreparationContext>); CHECK(ModelType::run_functor_with_all_component_types_return_array([]() { return std::string_view(CompType::name); @@ -122,7 +123,7 @@ TEST_CASE("MainModelType") { static_assert(is_main_model_type_v); static_assert(std::constructible_from, double, meta_data::MetaData const&, - MathSolverDispatcher const&>); + SolverPreparationContext>); CHECK(ModelType::run_functor_with_all_component_types_return_array([]() { return std::string_view(CompType::name); @@ -155,7 +156,7 @@ TEST_CASE("MainModelType") { static_assert(ModelType::n_types == 3); static_assert(is_main_model_type_v); static_assert(std::constructible_from, double, meta_data::MetaData const&, - MathSolverDispatcher const&>); + SolverPreparationContext>); CHECK(ModelType::run_functor_with_all_component_types_return_array([]() { return std::string_view(CompType::name);