PRISMS-PF Manual v3.0-pre
All Classes Functions Variables Enumerations Pages
spatial_discretization.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 spatial_discretization_h
5#define spatial_discretization_h
6
7#include <prismspf/config.h>
8#include <prismspf/core/conditional_ostreams.h>
9#include <prismspf/core/exceptions.h>
10#include <prismspf/core/refinement_criterion.h>
11#include <prismspf/utilities/utilities.h>
12
13PRISMS_PF_BEGIN_NAMESPACE
14
18template <int dim>
20{
21public:
25 enum TriangulationType : std::uint8_t
26 {
27 rectangular,
28 spherical
29 };
30
35 : subdivisions(dim, 1) {};
36
40 void
42
46 void
48
49 // Triangulation type
50 TriangulationType type = TriangulationType::rectangular;
51
52 // Domain extents in each cartesian direction
53 dealii::Tensor<1, dim, double> size;
54
55 // Radius of the spherical domain
56 double radius = 0.0;
57
58 // Mesh subdivisions in each cartesian direction
59 std::vector<unsigned int> subdivisions;
60
61 // Global refinement of mesh
62 unsigned int global_refinement = 0;
63
64 // Element polynomial degree
65 unsigned int degree = 1;
66
67 // Whether adaptive meshing (AMR) is enabled
68 bool has_adaptivity = false;
69
70 // Maximum global refinement for AMR
71 unsigned int max_refinement = 0;
72
73 // Minimum global refinement for AMR
74 unsigned int min_refinement = 0;
75
76 // The number of steps between remeshing
77 unsigned int remeshing_period = UINT_MAX;
78
79 // The criteria used for remeshing
80 std::vector<GridRefinement::RefinementCriterion> refinement_criteria;
81};
82
83template <int dim>
84inline void
86{
87 // Assign the triangulation type
88 if (radius != 0.0 && size.norm() == 0.0)
89 {
90 type = TriangulationType::spherical;
91 }
92 else if (radius == 0.0 && size.norm() != 0.0)
93 {
94 type = TriangulationType::rectangular;
95 }
96 else
97 {
98 AssertThrow(false, UnreachableCode());
99 }
100
101 // Check that AMR is not enabled for 1D
102 AssertThrow(
103 (!has_adaptivity || dim != 1),
104 dealii::ExcMessage(
105 "Adaptive meshing for the matrix-free method is not currently supported."));
106
107 // Some check if AMR is enabled
108 if (has_adaptivity)
109 {
110 // Check that the minimum and maximum refinement levels are valid
111 AssertThrow((max_refinement >= global_refinement),
112 dealii::ExcMessage(
113 "The maximum refinement level must be greater than or equal to the "
114 "global refinement level."));
115 AssertThrow((min_refinement <= global_refinement),
116 dealii::ExcMessage(
117 "The minimum refinement level must be less than or equal to the "
118 "global refinement level."));
119 AssertThrow((max_refinement >= min_refinement),
120 dealii::ExcMessage(
121 "The maximum refinement level must be greater than or equal to the "
122 "minimum refinement level."));
123
124 // Check that the refinement criteria are valid for the lower and upper bounds
125 for (const auto &criterion : refinement_criteria)
126 {
127 AssertThrow((criterion.value_lower_bound <= criterion.value_upper_bound),
128 dealii::ExcMessage(
129 "The lower bound of the value-based refinement "
130 "criteria must be less than or equal to the upper bound."));
131 }
132 }
133}
134
135template <int dim>
136inline void
138{
140 << "================================================\n"
141 << " Spatial Discretization\n"
142 << "================================================\n";
143
144 if (type == TriangulationType::spherical)
145 {
146 conditionalOStreams::pout_summary() << "Domain radius: " << radius << "\n";
147 }
148 else if (type == TriangulationType::rectangular)
149 {
150 if constexpr (dim == 1)
151 {
153 << "Domain size: x=" << size[0] << "\n"
154 << "Subdivisions: x=" << subdivisions[0] << "\n";
155 }
156 else if constexpr (dim == 2)
157 {
159 << "Domain size: x=" << size[0] << ", y=" << size[1] << "\n"
160 << "Subdivisions: x=" << subdivisions[0] << ", y=" << subdivisions[1] << "\n";
161 }
162 else if constexpr (dim == 3)
163 {
165 << "Domain size: x=" << size[0] << ", y=" << size[1] << ", z=" << size[2]
166 << "\n"
167 << "Subdivisions: x=" << subdivisions[0] << ", y=" << subdivisions[1]
168 << ", z=" << subdivisions[2] << "\n";
169 }
170 }
171 else
172 {
173 AssertThrow(false, UnreachableCode());
174 }
175
177 << "Global refinement: " << global_refinement << "\n"
178 << "Degree: " << degree << "\n"
179 << "Adaptivity enabled: " << bool_to_string(has_adaptivity) << "\n"
180 << "Max refinement: " << max_refinement << "\n"
181 << "Min refinement: " << min_refinement << "\n"
182 << "Remeshing period: " << remeshing_period << "\n";
183
184 if (!refinement_criteria.empty())
185 {
186 conditionalOStreams::pout_summary() << "Refinement criteria:\n";
187 }
188 for (const auto &criterion : refinement_criteria)
189 {
191 << " Variable name: " << criterion.variable_name << "\n"
192 << " Variable index: " << criterion.variable_index << "\n"
193 << " Criterion type: " << criterion.criterion_to_string() << "\n"
194 << " Value lower bound: " << criterion.value_lower_bound << "\n"
195 << " Value upper bound: " << criterion.value_upper_bound << "\n"
196 << " Gradient lower bound: " << criterion.gradient_lower_bound << "\n\n";
197 }
198 conditionalOStreams::pout_summary() << "\n" << std::flush;
199}
200
201PRISMS_PF_END_NAMESPACE
202
203#endif
static dealii::ConditionalOStream & pout_summary()
Log output stream for writing a summary.log file.
Definition conditional_ostreams.cc:22
Struct that holds spatial discretization parameters.
Definition spatial_discretization.h:20
TriangulationType
Internal enum for various triangulation types.
Definition spatial_discretization.h:26
void postprocess_and_validate()
Postprocess and validate parameters.
Definition spatial_discretization.h:85
void print_parameter_summary() const
Print parameters to summary.log.
Definition spatial_discretization.h:137
spatialDiscretization()
Constructor.
Definition spatial_discretization.h:34