PRISMS-PF Manual v3.0-pre
All Classes Functions Variables Enumerations Pages
nonexplicit_auxiliary_solver.h
1// SPDX-FileCopyrightText: © 2025 PRISMS Center at the University of Michigan
2// SPDX-License-Identifier: GNU Lesser General Public Version 2.1
3
4#ifndef nonexplicit_auxiliary_solver_h
5#define nonexplicit_auxiliary_solver_h
6
7#include <prismspf/config.h>
8#include <prismspf/core/constraint_handler.h>
9#include <prismspf/core/dof_handler.h>
10#include <prismspf/core/invm_handler.h>
11#include <prismspf/core/matrix_free_handler.h>
12#include <prismspf/core/solution_handler.h>
13#include <prismspf/core/type_enums.h>
14#include <prismspf/core/variable_attributes.h>
15#include <prismspf/solvers/nonexplicit_base.h>
16#include <prismspf/user_inputs/user_input_parameters.h>
17
18#ifdef PRISMS_PF_WITH_CALIPER
19# include <caliper/cali.h>
20#endif
21
22PRISMS_PF_BEGIN_NAMESPACE
23
27template <int dim, int degree, typename number>
28class customPDE;
29
33template <int dim, int degree>
35{
36public:
38 using VectorType = dealii::LinearAlgebra::distributed::Vector<double>;
39
44 const userInputParameters<dim> &_user_inputs,
45 const matrixfreeHandler<dim> &_matrix_free_handler,
46 const triangulationHandler<dim> &_triangulation_handler,
47 const invmHandler<dim, degree> &_invm_handler,
48 const constraintHandler<dim> &_constraint_handler,
49 const dofHandler<dim> &_dof_handler,
50 const dealii::MappingQ1<dim> &_mapping,
51 dealii::MGLevelObject<matrixfreeHandler<dim, float>> &_mg_matrix_free_handler,
52 solutionHandler<dim> &_solution_handler);
53
58
62 void
63 init() override;
64
68 void
69 solve() override;
70
71private:
75 std::map<
76 unsigned int,
77 std::unordered_map<std::pair<unsigned int, dependencyType>, unsigned int, pairHash>>
78 global_to_local_solution;
79
83 std::map<unsigned int, std::vector<VectorType *>> solution_subset;
84
88 std::map<unsigned int, std::vector<VectorType *>> new_solution_subset;
89
93 std::vector<std::map<unsigned int, variableAttributes>> subset_attributes_list;
94};
95
96template <int dim, int degree>
98 const userInputParameters<dim> &_user_inputs,
99 const matrixfreeHandler<dim> &_matrix_free_handler,
100 const triangulationHandler<dim> &_triangulation_handler,
101 const invmHandler<dim, degree> &_invm_handler,
102 const constraintHandler<dim> &_constraint_handler,
103 const dofHandler<dim> &_dof_handler,
104 const dealii::MappingQ1<dim> &_mapping,
105 dealii::MGLevelObject<matrixfreeHandler<dim, float>> &_mg_matrix_free_handler,
106 solutionHandler<dim> &_solution_handler)
107 : nonexplicitBase<dim, degree>(_user_inputs,
108 _matrix_free_handler,
109 _triangulation_handler,
110 _invm_handler,
111 _constraint_handler,
112 _dof_handler,
113 _mapping,
114 _mg_matrix_free_handler,
115 _solution_handler)
116{}
117
118template <int dim, int degree>
119inline void
121{
122 this->compute_subset_attributes(fieldSolveType::NONEXPLICIT_AUXILIARY);
123
124 // If the subset attribute is empty return early
125 if (this->subset_attributes.empty())
126 {
127 return;
128 }
129
130 for (const auto &[index, variable] : this->subset_attributes)
131 {
132 // Creating temporary map to match types
133 std::map<unsigned int, variableAttributes> temp;
134 temp.emplace(index, variable);
135 subset_attributes_list.push_back(temp);
136
137 // Create the implementation of customPDE with the subset of variable attributes
138 this->system_matrix[index] =
139 std::make_unique<SystemMatrixType>(this->user_inputs,
140 index,
141 subset_attributes_list.back());
142
143 // Set up the user-implemented equations and create the residual vectors
144 this->system_matrix.at(index)->clear();
145 this->system_matrix.at(index)->initialize(
146 this->matrix_free_handler.get_matrix_free());
147
148 // Create the subset of solution vectors and add the mapping to customPDE
149 new_solution_subset[index].push_back(
150 this->solution_handler.new_solution_set.at(index));
151 solution_subset[index].push_back(this->solution_handler.solution_set.at(
152 std::make_pair(index, dependencyType::NORMAL)));
153 global_to_local_solution[index].emplace(std::make_pair(index,
154 dependencyType::NORMAL),
155 0);
156 for (const auto &[variable_index, map] :
157 subset_attributes_list.back().begin()->second.dependency_set_RHS)
158 {
159 for (const auto &[dependency_type, field_type] : map)
160 {
161 const auto pair = std::make_pair(variable_index, dependency_type);
162
163 Assert(this->solution_handler.solution_set.find(pair) !=
164 this->solution_handler.solution_set.end(),
165 dealii::ExcMessage(
166 "There is no solution vector for the given index = " +
167 std::to_string(variable_index) +
168 " and type = " + to_string(dependency_type)));
169
170 Assert(this->solution_handler.new_solution_set.find(variable_index) !=
171 this->solution_handler.new_solution_set.end(),
172 dealii::ExcMessage(
173 "There is no new solution vector for the given index = " +
174 std::to_string(variable_index)));
175
176 solution_subset[index].push_back(
177 this->solution_handler.solution_set.at(pair));
178 global_to_local_solution[index].emplace(pair,
179 solution_subset.at(index).size() -
180 1);
181 }
182 }
183 this->system_matrix.at(index)->add_global_to_local_mapping(
184 global_to_local_solution.at(index));
185 }
186}
187
188template <int dim, int degree>
189inline void
191{
192 // If the subset attribute is empty return early
193 if (this->subset_attributes.empty())
194 {
195 return;
196 }
197
198 for (const auto &[index, variable] : this->subset_attributes)
199 {
200 // Compute the update
201 this->system_matrix.at(index)->compute_nonexplicit_auxiliary_update(
202 new_solution_subset.at(index),
203 solution_subset.at(index));
204
205 // Scale the update by the respective (SCALAR/VECTOR) invm.
206 new_solution_subset.at(index).at(0)->scale(this->invm_handler.get_invm(index));
207
208 // Update the solutions
209 this->solution_handler.update(fieldSolveType::NONEXPLICIT_AUXILIARY, index);
210
211 // Apply constraints
212 this->constraint_handler.get_constraint(index).distribute(
213 *(this->solution_handler.solution_set.at(
214 std::make_pair(index, dependencyType::NORMAL))));
215 }
216}
217
218PRISMS_PF_END_NAMESPACE
219
220#endif
The class handles the generation and application of boundary conditions based on the user-inputs.
Definition constraint_handler.h:25
Definition explicit_base.h:27
Class that manages the deal.II DoFHandlers.
Definition dof_handler.h:25
This class handles the computation and access of the inverted mass matrix for explicit solves.
Definition invm_handler.h:25
This class handlers the management and access of the matrix-free objects.
Definition matrix_free_handler.h:25
This class handles all auxiliary solves.
Definition nonexplicit_auxiliary_solver.h:35
void init() override
Initialize system.
Definition nonexplicit_auxiliary_solver.h:120
nonexplicitAuxiliarySolver(const userInputParameters< dim > &_user_inputs, const matrixfreeHandler< dim > &_matrix_free_handler, const triangulationHandler< dim > &_triangulation_handler, const invmHandler< dim, degree > &_invm_handler, const constraintHandler< dim > &_constraint_handler, const dofHandler< dim > &_dof_handler, const dealii::MappingQ1< dim > &_mapping, dealii::MGLevelObject< matrixfreeHandler< dim, float > > &_mg_matrix_free_handler, solutionHandler< dim > &_solution_handler)
Constructor.
Definition nonexplicit_auxiliary_solver.h:97
void solve() override
Solve a single update step.
Definition nonexplicit_auxiliary_solver.h:190
~nonexplicitAuxiliarySolver()=default
Destructor.
Base class for nonexplicit solves.
Definition nonexplicit_base.h:35
Class that manages solution initialization and swapping with old solutions.
Definition solution_handler.h:22
This class handlers the generation and manipulation of triangulations.
Definition triangulation_handler.h:24
Definition user_input_parameters.h:22
Simple hash function for pairs.
Definition variable_attributes.h:24