From 48a719cc872f7b98a8e0666c89c8920942900cfb Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Wed, 15 Oct 2025 11:11:07 -0600 Subject: [PATCH 01/11] Added StateParameters.number_of_constraints. --- include/micm/solver/rosenbrock.hpp | 8 +++++--- include/micm/solver/solver.hpp | 5 +++++ include/micm/solver/state.hpp | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/micm/solver/rosenbrock.hpp b/include/micm/solver/rosenbrock.hpp index bcfb2ccc8..d00a869bf 100644 --- a/include/micm/solver/rosenbrock.hpp +++ b/include/micm/solver/rosenbrock.hpp @@ -67,7 +67,8 @@ namespace micm LinearSolverPolicy&& linear_solver, RatesPolicy&& rates, auto& jacobian, - const size_t number_of_species) + const size_t number_of_species, + const size_t number_of_constraints) : linear_solver_(std::move(linear_solver)), rates_(std::move(rates)) { @@ -140,12 +141,13 @@ namespace micm /// @param jacobian Jacobian matrix /// /// Note: This constructor is not intended to be used directly. Instead, use the SolverBuilder to create a solver - RosenbrockSolver(LinearSolverPolicy&& linear_solver, RatesPolicy&& rates, auto& jacobian, const size_t number_of_species) + RosenbrockSolver(LinearSolverPolicy&& linear_solver, RatesPolicy&& rates, auto& jacobian, const size_t number_of_species, const size_t number_of_constraints) : AbstractRosenbrockSolver>( std::move(linear_solver), std::move(rates), jacobian, - number_of_species) + number_of_species, + number_of_constraints) { } RosenbrockSolver(const RosenbrockSolver&) = delete; diff --git a/include/micm/solver/solver.hpp b/include/micm/solver/solver.hpp index fb26c7e67..f4e426c26 100644 --- a/include/micm/solver/solver.hpp +++ b/include/micm/solver/solver.hpp @@ -105,6 +105,11 @@ namespace micm return state_parameters_.number_of_species_; } + std::size_t GetNumberOfConstraints() const + { + return state_parameters_.number_of_constraints_; + } + std::size_t GetNumberOfReactions() const { return state_parameters_.number_of_rate_constants_; diff --git a/include/micm/solver/state.hpp b/include/micm/solver/state.hpp index d4ba3113d..98d7642f8 100644 --- a/include/micm/solver/state.hpp +++ b/include/micm/solver/state.hpp @@ -26,6 +26,7 @@ namespace micm struct StateParameters { std::size_t number_of_species_{ 0 }; + std::size_t number_of_constraints_{ 0 }; std::size_t number_of_rate_constants_{ 0 }; std::vector variable_names_{}; std::vector custom_rate_parameter_labels_{}; From 1f10bba21faeca0924b325fc3898c75044ce78a4 Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Wed, 15 Oct 2025 11:32:14 -0600 Subject: [PATCH 02/11] Added number_of_constraints to solver_builder.inl. --- include/micm/solver/solver_builder.inl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/micm/solver/solver_builder.inl b/include/micm/solver/solver_builder.inl index d4d2e6255..4d1c20aa9 100644 --- a/include/micm/solver/solver_builder.inl +++ b/include/micm/solver/solver_builder.inl @@ -314,6 +314,7 @@ namespace micm auto species_map = this->GetSpeciesMap(); auto labels = this->GetCustomParameterLabels(); std::size_t number_of_species = this->system_.StateSize(); + std::size_t number_of_constraints = 0; if (number_of_species == 0) { throw std::system_error( @@ -340,6 +341,7 @@ namespace micm variable_names[species_pair.second] = species_pair.first; StateParameters state_parameters = { .number_of_species_ = number_of_species, + .number_of_constraints_ = number_of_constraints, .number_of_rate_constants_ = this->reactions_.size(), .variable_names_ = variable_names, .custom_rate_parameter_labels_ = labels, @@ -348,11 +350,12 @@ namespace micm this->SetAbsoluteTolerances(state_parameters.absolute_tolerance_, species_map); return Solver( - SolverPolicy(std::move(linear_solver), std::move(rates), jacobian, number_of_species), + SolverPolicy(std::move(linear_solver), std::move(rates), jacobian, + number_of_species, number_of_constraints), state_parameters, options, this->reactions_, this->system_); } -} // namespace micm \ No newline at end of file +} // namespace micm From 8acd5c9a3e178e5402747c3f39748db575da5955 Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Wed, 15 Oct 2025 11:39:22 -0600 Subject: [PATCH 03/11] Added number_of_constraints arguments to AbstractBackwardEuler. --- include/micm/solver/backward_euler.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/micm/solver/backward_euler.hpp b/include/micm/solver/backward_euler.hpp index f0b48e6f1..026a28874 100644 --- a/include/micm/solver/backward_euler.hpp +++ b/include/micm/solver/backward_euler.hpp @@ -44,7 +44,8 @@ namespace micm LinearSolverPolicy&& linear_solver, RatesPolicy&& rates, auto& jacobian, - const size_t number_of_species) + const size_t number_of_species, + const size_t number_of_constraints) : linear_solver_(std::move(linear_solver)), rates_(std::move(rates)) { From 30971c2b5cf8315fc85fdf0fd8055aaea84cd7e3 Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Wed, 15 Oct 2025 12:22:34 -0600 Subject: [PATCH 04/11] Use number_of_species + number_of_constraints in BuildJacobian. --- include/micm/solver/solver_builder.inl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/micm/solver/solver_builder.inl b/include/micm/solver/solver_builder.inl index 4d1c20aa9..40c767eb5 100644 --- a/include/micm/solver/solver_builder.inl +++ b/include/micm/solver/solver_builder.inl @@ -326,7 +326,8 @@ namespace micm RatesPolicy rates(this->reactions_, species_map); auto nonzero_elements = rates.NonZeroJacobianElements(); // The actual number of grid cells is not needed to construct the various solver objects - auto jacobian = BuildJacobian(nonzero_elements, 1, number_of_species, true); + auto jacobian = BuildJacobian(nonzero_elements, 1, + number_of_species + number_of_constraints, true); LinearSolverPolicy linear_solver(jacobian, 0); if constexpr (LuDecompositionInPlaceConcept) From 2117432fd797c450ae3094f9b2c306fa9026e9fa Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Fri, 17 Oct 2025 13:34:38 -0600 Subject: [PATCH 05/11] Added upper_left_diagonal_elements_. --- include/micm/solver/state.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/micm/solver/state.hpp b/include/micm/solver/state.hpp index 98d7642f8..87cd767ae 100644 --- a/include/micm/solver/state.hpp +++ b/include/micm/solver/state.hpp @@ -58,6 +58,8 @@ namespace micm DenseMatrixPolicy rate_constants_; /// @brief Atmospheric conditions, varies in time std::vector conditions_; + /// @brief The block matrix with an upper left identity, zeros elsewhere + std::vector upper_left_diagonal_elements_; /// @brief The jacobian structure, varies for each solve SparseMatrixPolicy jacobian_; std::vector jacobian_diagonal_elements_; @@ -89,6 +91,7 @@ namespace micm custom_rate_parameters_ = other.custom_rate_parameters_; rate_constants_ = other.rate_constants_; conditions_ = other.conditions_; + upper_left_diagonal_elements_ = other.upper_left_diagonal_elements_; jacobian_ = other.jacobian_; jacobian_diagonal_elements_ = other.jacobian_diagonal_elements_; variable_map_ = other.variable_map_; @@ -114,6 +117,7 @@ namespace micm custom_rate_parameters_ = other.custom_rate_parameters_; rate_constants_ = other.rate_constants_; conditions_ = other.conditions_; + upper_left_diagonal_elements_ = other.upper_left_diagonal_elements_; jacobian_ = other.jacobian_; jacobian_diagonal_elements_ = other.jacobian_diagonal_elements_; variable_map_ = other.variable_map_; @@ -137,6 +141,7 @@ namespace micm custom_rate_parameters_(std::move(other.custom_rate_parameters_)), rate_constants_(std::move(other.rate_constants_)), conditions_(std::move(other.conditions_)), + upper_left_diagonal_elements_(std::move(other.upper_left_diagonal_elements_)), jacobian_(std::move(other.jacobian_)), jacobian_diagonal_elements_(std::move(other.jacobian_diagonal_elements_)), variable_map_(std::move(other.variable_map_)), @@ -163,6 +168,7 @@ namespace micm custom_rate_parameters_ = std::move(other.custom_rate_parameters_); rate_constants_ = std::move(other.rate_constants_); conditions_ = std::move(other.conditions_); + upper_left_diagonal_elements_ = std::move(other.upper_left_diagonal_elements_); jacobian_ = std::move(other.jacobian_); jacobian_diagonal_elements_ = std::move(other.jacobian_diagonal_elements_); variable_map_ = std::move(other.variable_map_); From 51f7e27c23f07cac234f5f5805ddb0951208ffd0 Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Fri, 17 Oct 2025 13:58:38 -0600 Subject: [PATCH 06/11] Added upper_left_diagonal_elements_ in State constructors. --- include/micm/solver/state.inl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/micm/solver/state.inl b/include/micm/solver/state.inl index f160cd1e1..e91db4748 100644 --- a/include/micm/solver/state.inl +++ b/include/micm/solver/state.inl @@ -69,6 +69,7 @@ namespace micm custom_rate_parameters_(), rate_constants_(), conditions_(), + upper_left_diagonal_elements_(), jacobian_(), jacobian_diagonal_elements_(), variable_map_(), @@ -100,6 +101,7 @@ namespace micm variable_map_(), custom_rate_parameter_map_(), variable_names_(parameters.variable_names_), + upper_left_diagonal_elements_(), jacobian_(), jacobian_diagonal_elements_(), lower_matrix_(), From cd249cc8cab4b8b5261415827c5a88fd63aae55a Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Sun, 19 Oct 2025 10:45:01 -0600 Subject: [PATCH 07/11] Added constraint_size_ to State. --- include/micm/solver/state.hpp | 6 ++++++ include/micm/solver/state.inl | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/include/micm/solver/state.hpp b/include/micm/solver/state.hpp index 87cd767ae..6447f1bec 100644 --- a/include/micm/solver/state.hpp +++ b/include/micm/solver/state.hpp @@ -70,6 +70,7 @@ namespace micm LMatrixPolicy lower_matrix_; UMatrixPolicy upper_matrix_; std::size_t state_size_; + std::size_t constraint_size_; std::unique_ptr temporary_variables_; double relative_tolerance_; std::vector absolute_tolerance_; @@ -100,6 +101,7 @@ namespace micm lower_matrix_ = other.lower_matrix_; upper_matrix_ = other.upper_matrix_; state_size_ = other.state_size_; + constraint_size_ = other.constraint_size_; number_of_grid_cells_ = other.number_of_grid_cells_; temporary_variables_ = std::make_unique(*other.temporary_variables_); relative_tolerance_ = other.relative_tolerance_; @@ -126,6 +128,7 @@ namespace micm lower_matrix_ = other.lower_matrix_; upper_matrix_ = other.upper_matrix_; state_size_ = other.state_size_; + constraint_size_ = other.constraint_size_; number_of_grid_cells_ = other.number_of_grid_cells_; temporary_variables_ = std::make_unique(*other.temporary_variables_); relative_tolerance_ = other.relative_tolerance_; @@ -150,6 +153,7 @@ namespace micm lower_matrix_(std::move(other.lower_matrix_)), upper_matrix_(std::move(other.upper_matrix_)), state_size_(other.state_size_), + constraint_size_(other.constraint_size_), number_of_grid_cells_(other.number_of_grid_cells_), temporary_variables_(std::move(other.temporary_variables_)), relative_tolerance_(other.relative_tolerance_), @@ -177,12 +181,14 @@ namespace micm lower_matrix_ = std::move(other.lower_matrix_); upper_matrix_ = std::move(other.upper_matrix_); state_size_ = other.state_size_; + constraint_size_ = other.constraint_size_; number_of_grid_cells_ = other.number_of_grid_cells_; temporary_variables_ = std::move(other.temporary_variables_); relative_tolerance_ = other.relative_tolerance_; absolute_tolerance_ = std::move(other.absolute_tolerance_); other.state_size_ = 0; + other.constraint_size_ = 0; other.number_of_grid_cells_ = 0; } return *this; diff --git a/include/micm/solver/state.inl b/include/micm/solver/state.inl index e91db4748..0c2ef934b 100644 --- a/include/micm/solver/state.inl +++ b/include/micm/solver/state.inl @@ -78,6 +78,7 @@ namespace micm lower_matrix_(), upper_matrix_(), state_size_(0), + constraint_size_(0), number_of_grid_cells_(0), temporary_variables_(nullptr), relative_tolerance_(1e-06), @@ -107,6 +108,7 @@ namespace micm lower_matrix_(), upper_matrix_(), state_size_(parameters.variable_names_.size()), + constraint_size_(0), number_of_grid_cells_(number_of_grid_cells), relative_tolerance_(parameters.relative_tolerance_), absolute_tolerance_(parameters.absolute_tolerance_) @@ -118,6 +120,13 @@ namespace micm for (auto& label : parameters.custom_rate_parameter_labels_) custom_rate_parameter_map_[label] = index++; + for (std::size_t i = 0; i < state_size_; i++) { + upper_left_diagonal_elements_.push_back(1.0); + } + for (std::size_t i = 0; i < constraint_size_; i++) { + upper_left_diagonal_elements_.push_back(0.0); + } + if constexpr (LuDecompositionInPlaceConcept) { jacobian_ = From 98d15be695928d13edcd9e795e40836dad31b33f Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Sun, 19 Oct 2025 11:07:59 -0600 Subject: [PATCH 08/11] Renamed to upper_left_identity_diagonal_. --- include/micm/solver/state.hpp | 10 +++++----- include/micm/solver/state.inl | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/include/micm/solver/state.hpp b/include/micm/solver/state.hpp index 6447f1bec..ece645ea3 100644 --- a/include/micm/solver/state.hpp +++ b/include/micm/solver/state.hpp @@ -59,7 +59,7 @@ namespace micm /// @brief Atmospheric conditions, varies in time std::vector conditions_; /// @brief The block matrix with an upper left identity, zeros elsewhere - std::vector upper_left_diagonal_elements_; + std::vector upper_left_identity_diagonal_; /// @brief The jacobian structure, varies for each solve SparseMatrixPolicy jacobian_; std::vector jacobian_diagonal_elements_; @@ -92,7 +92,7 @@ namespace micm custom_rate_parameters_ = other.custom_rate_parameters_; rate_constants_ = other.rate_constants_; conditions_ = other.conditions_; - upper_left_diagonal_elements_ = other.upper_left_diagonal_elements_; + upper_left_identity_diagonal_ = other.upper_left_identity_diagonal_; jacobian_ = other.jacobian_; jacobian_diagonal_elements_ = other.jacobian_diagonal_elements_; variable_map_ = other.variable_map_; @@ -119,7 +119,7 @@ namespace micm custom_rate_parameters_ = other.custom_rate_parameters_; rate_constants_ = other.rate_constants_; conditions_ = other.conditions_; - upper_left_diagonal_elements_ = other.upper_left_diagonal_elements_; + upper_left_identity_diagonal_ = other.upper_left_identity_diagonal_; jacobian_ = other.jacobian_; jacobian_diagonal_elements_ = other.jacobian_diagonal_elements_; variable_map_ = other.variable_map_; @@ -144,7 +144,7 @@ namespace micm custom_rate_parameters_(std::move(other.custom_rate_parameters_)), rate_constants_(std::move(other.rate_constants_)), conditions_(std::move(other.conditions_)), - upper_left_diagonal_elements_(std::move(other.upper_left_diagonal_elements_)), + upper_left_identity_diagonal_(std::move(other.upper_left_identity_diagonal_)), jacobian_(std::move(other.jacobian_)), jacobian_diagonal_elements_(std::move(other.jacobian_diagonal_elements_)), variable_map_(std::move(other.variable_map_)), @@ -172,7 +172,7 @@ namespace micm custom_rate_parameters_ = std::move(other.custom_rate_parameters_); rate_constants_ = std::move(other.rate_constants_); conditions_ = std::move(other.conditions_); - upper_left_diagonal_elements_ = std::move(other.upper_left_diagonal_elements_); + upper_left_identity_diagonal_ = std::move(other.upper_left_identity_diagonal_); jacobian_ = std::move(other.jacobian_); jacobian_diagonal_elements_ = std::move(other.jacobian_diagonal_elements_); variable_map_ = std::move(other.variable_map_); diff --git a/include/micm/solver/state.inl b/include/micm/solver/state.inl index 0c2ef934b..cff4e37a3 100644 --- a/include/micm/solver/state.inl +++ b/include/micm/solver/state.inl @@ -69,7 +69,7 @@ namespace micm custom_rate_parameters_(), rate_constants_(), conditions_(), - upper_left_diagonal_elements_(), + upper_left_identity_diagonal_(), jacobian_(), jacobian_diagonal_elements_(), variable_map_(), @@ -102,7 +102,7 @@ namespace micm variable_map_(), custom_rate_parameter_map_(), variable_names_(parameters.variable_names_), - upper_left_diagonal_elements_(), + upper_left_identity_diagonal_(), jacobian_(), jacobian_diagonal_elements_(), lower_matrix_(), @@ -121,10 +121,10 @@ namespace micm custom_rate_parameter_map_[label] = index++; for (std::size_t i = 0; i < state_size_; i++) { - upper_left_diagonal_elements_.push_back(1.0); + upper_left_identity_diagonal_.push_back(1.0); } for (std::size_t i = 0; i < constraint_size_; i++) { - upper_left_diagonal_elements_.push_back(0.0); + upper_left_identity_diagonal_.push_back(0.0); } if constexpr (LuDecompositionInPlaceConcept) From 767addbbf383d3f14497390c769623eb9f932b30 Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Sun, 19 Oct 2025 11:40:40 -0600 Subject: [PATCH 09/11] BuildJacobian with state_size_ + constraint_size_ in State. --- include/micm/solver/state.inl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/micm/solver/state.inl b/include/micm/solver/state.inl index cff4e37a3..01e389d38 100644 --- a/include/micm/solver/state.inl +++ b/include/micm/solver/state.inl @@ -130,14 +130,14 @@ namespace micm if constexpr (LuDecompositionInPlaceConcept) { jacobian_ = - BuildJacobian(parameters.nonzero_jacobian_elements_, number_of_grid_cells, state_size_, true); + BuildJacobian(parameters.nonzero_jacobian_elements_, number_of_grid_cells, state_size_ + constraint_size_, true); auto lu = LuDecompositionPolicy::template GetLUMatrix(jacobian_, 0, false); jacobian_ = std::move(lu); } else { jacobian_ = - BuildJacobian(parameters.nonzero_jacobian_elements_, number_of_grid_cells, state_size_, false); + BuildJacobian(parameters.nonzero_jacobian_elements_, number_of_grid_cells, state_size_ + constraint_size_, false); auto lu = LuDecompositionPolicy::template GetLUMatrices( jacobian_, 0, false); auto lower_matrix = std::move(lu.first); From 255d3c7c3f523deba24783feea22f8710c1a0fd6 Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Fri, 21 Nov 2025 07:12:11 -0700 Subject: [PATCH 10/11] Added includes. --- test/unit/solver/test_linear_solver_in_place_policy.hpp | 1 + test/unit/solver/test_linear_solver_policy.hpp | 1 + test/unit/solver/test_lu_decomposition_in_place_policy.hpp | 3 ++- test/unit/solver/test_lu_decomposition_policy.hpp | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/test/unit/solver/test_linear_solver_in_place_policy.hpp b/test/unit/solver/test_linear_solver_in_place_policy.hpp index 8b536c4a2..583ddc7ce 100644 --- a/test/unit/solver/test_linear_solver_in_place_policy.hpp +++ b/test/unit/solver/test_linear_solver_in_place_policy.hpp @@ -4,6 +4,7 @@ #include #include +#include #include template diff --git a/test/unit/solver/test_linear_solver_policy.hpp b/test/unit/solver/test_linear_solver_policy.hpp index 8a329e2b7..861b7bb86 100644 --- a/test/unit/solver/test_linear_solver_policy.hpp +++ b/test/unit/solver/test_linear_solver_policy.hpp @@ -3,6 +3,7 @@ #include #include +#include #include // Define the following three functions that only work for the CudaMatrix; the if constexpr statement is evalauted at diff --git a/test/unit/solver/test_lu_decomposition_in_place_policy.hpp b/test/unit/solver/test_lu_decomposition_in_place_policy.hpp index 366dbce3d..39478be7a 100644 --- a/test/unit/solver/test_lu_decomposition_in_place_policy.hpp +++ b/test/unit/solver/test_lu_decomposition_in_place_policy.hpp @@ -4,6 +4,7 @@ #include #include +#include #include template @@ -227,4 +228,4 @@ void testDiagonalMatrix(std::size_t number_of_blocks) lud.template Decompose(ALU); check_results( A, ALU, [&](const double a, const double b) -> void { EXPECT_NEAR(a, b, 1.0e-10); }); -} \ No newline at end of file +} diff --git a/test/unit/solver/test_lu_decomposition_policy.hpp b/test/unit/solver/test_lu_decomposition_policy.hpp index eef598920..12c2f8425 100644 --- a/test/unit/solver/test_lu_decomposition_policy.hpp +++ b/test/unit/solver/test_lu_decomposition_policy.hpp @@ -4,6 +4,7 @@ #include #include +#include #include template @@ -202,4 +203,4 @@ void testDiagonalMatrix(std::size_t number_of_blocks) lud.template Decompose(A, LU.first, LU.second); check_results( A, LU.first, LU.second, [&](const double a, const double b) -> void { EXPECT_NEAR(a, b, 1.0e-10); }); -} \ No newline at end of file +} From 5c3e5875ea0a839813f02f83c9b65fee200adbf7 Mon Sep 17 00:00:00 2001 From: David Fillmore Date: Tue, 25 Nov 2025 09:16:09 -0700 Subject: [PATCH 11/11] =?UTF-8?q?Implemented=20builder-level=20support=20f?= =?UTF-8?q?or=20future=20constraints=20without=20changing=20current=20beha?= =?UTF-8?q?vior:=20added=20constraint=20count/name=20setters=20and=20used?= =?UTF-8?q?=20them=20to=20size=20Jacobian/state=20vectors=20and=20extend?= =?UTF-8?q?=20variable=20names,=20while=20carrying=20the=20count=20into=20?= =?UTF-8?q?StateParameters=20(include/micm/solver/solver=5Fbuilder.hpp,=20?= =?UTF-8?q?include/micm/solver/solver=5Fbuilder.inl).=20State=20now=20hono?= =?UTF-8?q?rs=20the=20provided=20constraint=20count=20when=20building=20id?= =?UTF-8?q?entity=20masks=20and=20Jacobian=20dimensions=20(include/micm/so?= =?UTF-8?q?lver/state.inl).=20AlphaMinusJacobian=20applies=20=CE=B1I=20usi?= =?UTF-8?q?ng=20a=20row-aware=20identity=20mask,=20preparing=20for=20maske?= =?UTF-8?q?d=20constraint=20rows=20(include/micm/solver/rosenbrock.inl).?= =?UTF-8?q?=20Tests:=20cmake=20--build=20build=20and=20ctest=20--output-on?= =?UTF-8?q?-failure=20(all=2048=20tests=20passed).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/micm/solver/rosenbrock.inl | 11 +++- include/micm/solver/solver_builder.hpp | 14 ++++- include/micm/solver/solver_builder.inl | 76 ++++++++++++++++++++++++-- include/micm/solver/state.inl | 4 +- 4 files changed, 96 insertions(+), 9 deletions(-) diff --git a/include/micm/solver/rosenbrock.inl b/include/micm/solver/rosenbrock.inl index 77ce6fa8f..e9c144680 100644 --- a/include/micm/solver/rosenbrock.inl +++ b/include/micm/solver/rosenbrock.inl @@ -211,11 +211,13 @@ namespace micm const double& alpha) const requires(!VectorizableSparse) { + // Only add alpha to rows flagged in the identity mask (currently all state variables) for (std::size_t i_block = 0; i_block < state.jacobian_.NumberOfBlocks(); ++i_block) { auto jacobian_vector = std::next(state.jacobian_.AsVector().begin(), i_block * state.jacobian_.FlatBlockSize()); + std::size_t diag_row = 0; for (const auto& i_elem : state.jacobian_diagonal_elements_) - jacobian_vector[i_elem] += alpha; + jacobian_vector[i_elem] += alpha * state.upper_left_identity_diagonal_[diag_row++]; } } @@ -227,12 +229,17 @@ namespace micm requires(VectorizableSparse) { constexpr std::size_t n_cells = SparseMatrixPolicy::GroupVectorSize(); + // Only add alpha to rows flagged in the identity mask (currently all state variables) for (std::size_t i_group = 0; i_group < state.jacobian_.NumberOfGroups(state.jacobian_.NumberOfBlocks()); ++i_group) { auto jacobian_vector = std::next(state.jacobian_.AsVector().begin(), i_group * state.jacobian_.GroupSize()); + std::size_t diag_row = 0; for (const auto& i_elem : state.jacobian_diagonal_elements_) + { for (std::size_t i_cell = 0; i_cell < n_cells; ++i_cell) - jacobian_vector[i_elem + i_cell] += alpha; + jacobian_vector[i_elem + i_cell] += alpha * state.upper_left_identity_diagonal_[diag_row]; + ++diag_row; + } } } diff --git a/include/micm/solver/solver_builder.hpp b/include/micm/solver/solver_builder.hpp index 934a7bf35..ba078789a 100644 --- a/include/micm/solver/solver_builder.hpp +++ b/include/micm/solver/solver_builder.hpp @@ -50,6 +50,8 @@ namespace micm SolverParametersPolicy options_; System system_; std::vector reactions_; + std::size_t constraint_count_ = 0; + std::vector constraint_names_{}; bool ignore_unused_species_ = true; bool reorder_state_ = true; bool valid_system_ = false; @@ -75,6 +77,16 @@ namespace micm /// @return Updated SolverBuilder SolverBuilder& SetReactions(const std::vector& reactions); + /// @brief Set the number of algebraic constraints (appended after state variables) + /// @param number_of_constraints Constraint count + /// @return Updated SolverBuilder + SolverBuilder& SetConstraintCount(std::size_t number_of_constraints); + + /// @brief Set constraint names (appended after state variables) + /// @param names Constraint variable names + /// @return Updated SolverBuilder + SolverBuilder& SetConstraintNames(const std::vector& names); + /// @brief Set whether to ignore unused species /// @param ignore_unused_species True if unused species should be ignored /// @return Updated SolverBuilder @@ -152,4 +164,4 @@ namespace micm } // namespace micm -#include "solver_builder.inl" \ No newline at end of file +#include "solver_builder.inl" diff --git a/include/micm/solver/solver_builder.inl b/include/micm/solver/solver_builder.inl index 40c767eb5..32d0fdbbc 100644 --- a/include/micm/solver/solver_builder.inl +++ b/include/micm/solver/solver_builder.inl @@ -63,6 +63,65 @@ namespace micm return *this; } + template< + class SolverParametersPolicy, + class DenseMatrixPolicy, + class SparseMatrixPolicy, + class RatesPolicy, + class LuDecompositionPolicy, + class LinearSolverPolicy, + class StatePolicy> + inline SolverBuilder< + SolverParametersPolicy, + DenseMatrixPolicy, + SparseMatrixPolicy, + RatesPolicy, + LuDecompositionPolicy, + LinearSolverPolicy, + StatePolicy>& + SolverBuilder< + SolverParametersPolicy, + DenseMatrixPolicy, + SparseMatrixPolicy, + RatesPolicy, + LuDecompositionPolicy, + LinearSolverPolicy, + StatePolicy>::SetConstraintCount(std::size_t number_of_constraints) + { + constraint_count_ = number_of_constraints; + return *this; + } + + template< + class SolverParametersPolicy, + class DenseMatrixPolicy, + class SparseMatrixPolicy, + class RatesPolicy, + class LuDecompositionPolicy, + class LinearSolverPolicy, + class StatePolicy> + inline SolverBuilder< + SolverParametersPolicy, + DenseMatrixPolicy, + SparseMatrixPolicy, + RatesPolicy, + LuDecompositionPolicy, + LinearSolverPolicy, + StatePolicy>& + SolverBuilder< + SolverParametersPolicy, + DenseMatrixPolicy, + SparseMatrixPolicy, + RatesPolicy, + LuDecompositionPolicy, + LinearSolverPolicy, + StatePolicy>::SetConstraintNames(const std::vector& names) + { + constraint_names_ = names; + constraint_count_ = names.size(); + return *this; + } + template< class SolverParametersPolicy, class DenseMatrixPolicy, @@ -314,7 +373,7 @@ namespace micm auto species_map = this->GetSpeciesMap(); auto labels = this->GetCustomParameterLabels(); std::size_t number_of_species = this->system_.StateSize(); - std::size_t number_of_constraints = 0; + std::size_t number_of_constraints = constraint_count_; if (number_of_species == 0) { throw std::system_error( @@ -326,8 +385,7 @@ namespace micm RatesPolicy rates(this->reactions_, species_map); auto nonzero_elements = rates.NonZeroJacobianElements(); // The actual number of grid cells is not needed to construct the various solver objects - auto jacobian = BuildJacobian(nonzero_elements, 1, - number_of_species + number_of_constraints, true); + auto jacobian = BuildJacobian(nonzero_elements, 1, number_of_species + number_of_constraints, true); LinearSolverPolicy linear_solver(jacobian, 0); if constexpr (LuDecompositionInPlaceConcept) @@ -340,9 +398,19 @@ namespace micm std::vector variable_names{ number_of_species }; for (auto& species_pair : species_map) variable_names[species_pair.second] = species_pair.first; + if (number_of_constraints > 0) + { + std::vector names = constraint_names_; + if (names.size() < number_of_constraints) + { + for (std::size_t i = names.size(); i < number_of_constraints; ++i) + names.push_back("constraint_" + std::to_string(i)); + } + variable_names.insert(variable_names.end(), names.begin(), names.begin() + number_of_constraints); + } StateParameters state_parameters = { .number_of_species_ = number_of_species, - .number_of_constraints_ = number_of_constraints, + .number_of_constraints_ = number_of_constraints, .number_of_rate_constants_ = this->reactions_.size(), .variable_names_ = variable_names, .custom_rate_parameter_labels_ = labels, diff --git a/include/micm/solver/state.inl b/include/micm/solver/state.inl index 01e389d38..14b0afd5b 100644 --- a/include/micm/solver/state.inl +++ b/include/micm/solver/state.inl @@ -107,8 +107,8 @@ namespace micm jacobian_diagonal_elements_(), lower_matrix_(), upper_matrix_(), - state_size_(parameters.variable_names_.size()), - constraint_size_(0), + state_size_(parameters.number_of_species_), + constraint_size_(parameters.number_of_constraints_), number_of_grid_cells_(number_of_grid_cells), relative_tolerance_(parameters.relative_tolerance_), absolute_tolerance_(parameters.absolute_tolerance_)