PRISMS-PF Manual v3.0-pre
All Classes Functions Variables Enumerations Pages
linear_solver_base.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 linear_solver_base_h
5#define linear_solver_base_h
6
7#include <deal.II/base/quadrature_lib.h>
8#include <deal.II/fe/fe_q.h>
9#include <deal.II/fe/mapping_q1.h>
10#include <deal.II/lac/la_parallel_vector.h>
11#include <deal.II/lac/solver_control.h>
12
13#include <prismspf/config.h>
14#include <prismspf/core/conditional_ostreams.h>
15#include <prismspf/core/constraint_handler.h>
16#include <prismspf/core/matrix_free_handler.h>
17#include <prismspf/core/solution_handler.h>
18#include <prismspf/core/triangulation_handler.h>
19#include <prismspf/core/type_enums.h>
20#include <prismspf/core/variable_attributes.h>
21#include <prismspf/user_inputs/user_input_parameters.h>
22
23PRISMS_PF_BEGIN_NAMESPACE
24
28template <int dim, int degree, typename number>
29class customPDE;
30
34template <int dim, int degree>
36{
37public:
39 using VectorType = dealii::LinearAlgebra::distributed::Vector<double>;
40
45 const variableAttributes &_variable_attributes,
46 const matrixfreeHandler<dim> &_matrix_free_handler,
47 const constraintHandler<dim> &_constraint_handler,
48 solutionHandler<dim> &_solution_handler);
49
53 virtual ~linearSolverBase() = default;
54
58 virtual void
59 init() = 0;
60
64 virtual void
65 reinit() = 0;
66
70 virtual void
71 solve(const double step_length = 1.0) = 0;
72
73protected:
77 void
79
84
89
94
99
104
108 const unsigned int field_index;
109
113 std::unordered_map<std::pair<unsigned int, dependencyType>, unsigned int, pairHash>
115
119 std::vector<VectorType *> residual_src;
120
124 VectorType *residual;
125
129 std::unordered_map<std::pair<unsigned int, dependencyType>, unsigned int, pairHash>
131
135 std::vector<VectorType *> newton_update_src;
136
140 VectorType *newton_update;
141
145 std::unique_ptr<SystemMatrixType> system_matrix;
146
150 std::unique_ptr<SystemMatrixType> update_system_matrix;
151
155 std::map<unsigned int, variableAttributes> subset_attributes;
156
160 dealii::SolverControl solver_control;
161
165 double tolerance = 0.0;
166};
167
168template <int dim, int degree>
170 const userInputParameters<dim> &_user_inputs,
171 const variableAttributes &_variable_attributes,
172 const matrixfreeHandler<dim> &_matrix_free_handler,
173 const constraintHandler<dim> &_constraint_handler,
174 solutionHandler<dim> &_solution_handler)
175 : user_inputs(_user_inputs)
176 , variable_attributes(_variable_attributes)
177 , matrix_free_handler(_matrix_free_handler)
178 , constraint_handler(_constraint_handler)
179 , solution_handler(_solution_handler)
180 , field_index(_variable_attributes.field_index)
181 , residual(solution_handler.new_solution_set.at(field_index))
182 , newton_update(solution_handler.solution_set.at(
183 std::make_pair(field_index, dependencyType::CHANGE)))
184 , solver_control(
185 _user_inputs.linear_solve_parameters.linear_solve.at(field_index).max_iterations)
186{
187 // Creating map to match types
189
190 // Create the implementation of customPDE with the subset of variable attributes
192 std::make_unique<SystemMatrixType>(user_inputs, field_index, subset_attributes);
194 std::make_unique<SystemMatrixType>(user_inputs, field_index, subset_attributes);
195
196 // Create the residual subset of solution vectors and add the mapping to customPDE
197 residual_src.push_back(solution_handler.solution_set.at(
198 std::make_pair(field_index, dependencyType::NORMAL)));
199 residual_global_to_local_solution.emplace(std::make_pair(field_index,
200 dependencyType::NORMAL),
201 0);
202 for (const auto &[variable_index, map] : variable_attributes.dependency_set_RHS)
203 {
204 for (const auto &[dependency_type, field_type] : map)
205 {
206 const auto pair = std::make_pair(variable_index, dependency_type);
207
208 Assert(solution_handler.solution_set.find(pair) !=
209 solution_handler.solution_set.end(),
210 dealii::ExcMessage("There is no solution vector for the given index = " +
211 std::to_string(variable_index) +
212 " and type = " + to_string(dependency_type)));
213
214 Assert(solution_handler.new_solution_set.find(variable_index) !=
215 solution_handler.new_solution_set.end(),
216 dealii::ExcMessage(
217 "There is no new solution vector for the given index = " +
218 std::to_string(variable_index)));
219
220 residual_src.push_back(solution_handler.solution_set.at(pair));
221 residual_global_to_local_solution.emplace(pair, residual_src.size() - 1);
222 }
223 }
224
225 // Create the newton update subset of solution vectors and add the mapping to
226 // customPDE. For this one we consider the singular src vector as the residual
227 // vector above and the src subset all other dependencies vectors. This is
228 // complicated, but has to do with the way deal.II's solvers (like CG) handle
229 // iterative updates. For this reason, we have to pass the residual vector as
230 // VectorType src and all other dependencies for the LHS as std::vector<VectorType*>
231 // src_subset.
232 newton_update_src.push_back(solution_handler.new_solution_set.at(field_index));
234 dependencyType::CHANGE),
235 0);
236 for (const auto &[variable_index, map] : variable_attributes.dependency_set_LHS)
237 {
238 for (const auto &[dependency_type, field_type] : map)
239 {
240 if (dependency_type == dependencyType::CHANGE)
241 {
242 continue;
243 }
244 const auto pair = std::make_pair(variable_index, dependency_type);
245
246 Assert(solution_handler.solution_set.find(pair) !=
247 solution_handler.solution_set.end(),
248 dealii::ExcMessage("There is no solution vector for the given index = " +
249 std::to_string(variable_index) +
250 " and type = " + to_string(dependency_type)));
251
252 Assert(solution_handler.new_solution_set.find(variable_index) !=
253 solution_handler.new_solution_set.end(),
254 dealii::ExcMessage(
255 "There is no new solution vector for the given index = " +
256 std::to_string(variable_index)));
257
258 newton_update_src.push_back(solution_handler.solution_set.at(pair));
260 newton_update_src.size() - 1);
261 }
262 }
263}
264
265template <int dim, int degree>
266inline void
268{
269 tolerance =
270 user_inputs.linear_solve_parameters.linear_solve.at(field_index).tolerance_type ==
271 solverToleranceType::RELATIVE_RESIDUAL_CHANGE
272 ? user_inputs.linear_solve_parameters.linear_solve.at(field_index).tolerance *
273 residual->l2_norm()
274 : user_inputs.linear_solve_parameters.linear_solve.at(field_index).tolerance;
275}
276
277PRISMS_PF_END_NAMESPACE
278
279#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
Base class that handles the assembly and linear solving of a field.
Definition linear_solver_base.h:36
void compute_solver_tolerance()
Compute the solver tolerance based on the specified tolerance type.
Definition linear_solver_base.h:267
std::vector< VectorType * > newton_update_src
Subset of fields that are necessary for the source of the newton update.
Definition linear_solver_base.h:135
std::vector< VectorType * > residual_src
Subset of fields that are necessary for the source of the residual solve.
Definition linear_solver_base.h:119
VectorType * residual
Residual vector.
Definition linear_solver_base.h:124
virtual void init()=0
Initialize the system.
const userInputParameters< dim > & user_inputs
User-inputs.
Definition linear_solver_base.h:83
std::unique_ptr< SystemMatrixType > system_matrix
PDE operator for the residual side.
Definition linear_solver_base.h:145
VectorType * newton_update
Newton update vector.
Definition linear_solver_base.h:140
virtual ~linearSolverBase()=default
Destructor.
std::unique_ptr< SystemMatrixType > update_system_matrix
PDE operator for the newton update side.
Definition linear_solver_base.h:150
std::unordered_map< std::pair< unsigned int, dependencyType >, unsigned int, pairHash > newton_update_global_to_local_solution
Mapping from global solution vectors to the local ones for the newton update.
Definition linear_solver_base.h:130
std::map< unsigned int, variableAttributes > subset_attributes
Subset attributes.
Definition linear_solver_base.h:155
const unsigned int field_index
The field index we are solving.
Definition linear_solver_base.h:108
virtual void solve(const double step_length=1.0)=0
Solve the system Ax=b.
double tolerance
Solver tolerance.
Definition linear_solver_base.h:165
virtual void reinit()=0
Reinitialize the system.
const matrixfreeHandler< dim > & matrix_free_handler
Matrix-free object handler for non-multigrid data.
Definition linear_solver_base.h:93
const variableAttributes & variable_attributes
Variable attributes for field.
Definition linear_solver_base.h:88
solutionHandler< dim > & solution_handler
Solution handler.
Definition linear_solver_base.h:103
const constraintHandler< dim > & constraint_handler
Constraint handler.
Definition linear_solver_base.h:98
dealii::SolverControl solver_control
Solver control.
Definition linear_solver_base.h:160
linearSolverBase(const userInputParameters< dim > &_user_inputs, const variableAttributes &_variable_attributes, const matrixfreeHandler< dim > &_matrix_free_handler, const constraintHandler< dim > &_constraint_handler, solutionHandler< dim > &_solution_handler)
Constructor.
Definition linear_solver_base.h:169
std::unordered_map< std::pair< unsigned int, dependencyType >, unsigned int, pairHash > residual_global_to_local_solution
Mapping from global solution vectors to the local ones for the residual solve.
Definition linear_solver_base.h:114
This class handlers the management and access of the matrix-free objects.
Definition matrix_free_handler.h:25
Class that manages solution initialization and swapping with old solutions.
Definition solution_handler.h:22
Definition user_input_parameters.h:22
Simple hash function for pairs.
Definition variable_attributes.h:24
Structure to hold the variable attributes of a field. This includes things like the name,...
Definition variable_attributes.h:39
std::map< unsigned int, std::map< dependencyType, fieldType > > dependency_set_RHS
A dependency set where the RHS evaluation flags that are not 0 (not nothing) are included....
Definition variable_attributes.h:149
std::map< unsigned int, std::map< dependencyType, fieldType > > dependency_set_LHS
A dependency set where the LHS evaluation flags that are not 0 (not nothing) are included....
Definition variable_attributes.h:156