PRISMS-PF Manual
Loading...
Searching...
No Matches
spatial_discretization.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2025 PRISMS Center at the University of Michigan
2// SPDX-License-Identifier: GNU Lesser General Public Version 2.1
3
4#pragma once
5
6#include <deal.II/distributed/tria.h>
7#include <deal.II/grid/grid_generator.h>
8#include <deal.II/grid/grid_tools.h>
9#include <deal.II/grid/tria.h>
10
14#include <prismspf/core/types.h>
15
17
18#include <prismspf/config.h>
19
21
31
32template <unsigned int dim>
34 std::conditional_t<dim == 1,
35 dealii::Triangulation<dim>,
36 dealii::parallel::distributed::Triangulation<dim>>;
37
41template <unsigned int dim>
43{
47 RectangularMesh() = default;
48
52 RectangularMesh(dealii::Tensor<1, dim, double> _size,
53 dealii::Tensor<1, dim, double> _lower_bound,
54 std::array<unsigned int, dim> _subdivisions)
55 : size(_size)
58
62 void
63 generate_mesh(Triangulation<dim> &triangulation) const
64 {
65 validate();
66 dealii::GridGenerator::subdivided_hyper_rectangle(triangulation,
68 dealii::Point<dim>(lower_bound),
69 dealii::Point<dim>(size));
70 mark_boundaries(triangulation);
71 mark_periodic(triangulation);
72 };
73
77 void
78 validate() const
79 {}
80
84 dealii::Tensor<1, dim, double> size;
85
89 dealii::Tensor<1, dim, double> lower_bound;
90
94 std::vector<unsigned int> subdivisions = std::vector<unsigned int>(dim, 1);
95
99 std::set<unsigned int> periodic_directions;
100
104 void
106 {
107 // Loop through the cells
108 for (const auto &cell : triangulation.active_cell_iterators())
109 {
110 // Mark the faces (faces_per_cell = 2*dim)
111 for (unsigned int face_number = 0;
113 ++face_number)
114 {
115 // Direction for quad and hex cells
116 unsigned int direction = face_number / 2;
117
118 // Mark the boundary id for x=0, y=0, z=0 and x=max, y=max, z=max
119 if (std::fabs(cell->face(face_number)->center()(direction)) <
121 std::fabs(cell->face(face_number)->center()(direction) -
123 {
124 cell->face(face_number)->set_boundary_id(face_number);
125 }
126 }
127 }
128 }
129
133 void
134 mark_periodic(Triangulation<dim> &triangulation) const
135 {
136 // Create a vector of matched pairs that we fill and enforce upon the
137 // constraints
138 std::vector<
139 dealii::GridTools::PeriodicFacePair<typename Triangulation<dim>::cell_iterator>>
140 periodicity_vector;
141 collect_periodic_faces(triangulation, periodicity_vector);
142
143 // Add periodicity
144 triangulation.add_periodicity(periodicity_vector);
145 }
146
150 template <typename MeshType> // triangulation or dofhandler
151 void
153 const MeshType &triangulation,
154 std::vector<dealii::GridTools::PeriodicFacePair<typename MeshType::cell_iterator>>
155 &periodicity_vector) const
156 {
157 for (unsigned int direction : periodic_directions)
158 {
159 // Collect the matched pairs on the coarsest level of the mesh
160 unsigned int boundary_id = direction * 2;
161 dealii::GridTools::collect_periodic_faces(triangulation,
162 boundary_id,
163 boundary_id + 1,
164 direction,
165 periodicity_vector);
166 }
167 }
168};
169
173template <unsigned int dim>
175{
179 SphericalMesh() = default;
180
184 explicit SphericalMesh(double _radius)
185 : radius(_radius)
186 {}
187
191 void
192 generate_mesh(Triangulation<dim> &triangulation) const
193 {
194 validate();
195 // TODO: can we just generate a 1d mesh using
196 // dealii::GridGenerator::subdivided_hyper_rectangle instead of throwing an exception?
197 AssertThrow(dim != 1, dealii::ExcMessage("Spherical mesh not valid in 1D"));
198 dealii::GridGenerator::hyper_ball(triangulation, dealii::Point<dim>(), radius);
199 mark_boundaries(triangulation);
200 };
201
205 void
206 validate() const
207 {}
208
212 double radius = 1.0;
213
214private:
218 void
220 {
221 // TODO mark all as 0, or come up with something complicated
222 }
223};
224
228template <unsigned int dim>
230{
234 void
236
240 void
242 { // Check that AMR is not enabled for 1D
244 (!has_adaptivity || dim != 1),
245 dealii::ExcMessage(
246 "Adaptive meshing for the matrix-free method is not currently supported."));
247
248 // Some check if AMR is enabled
249 if (has_adaptivity)
250 {
251 // Check that the minimum and maximum refinement levels are valid
253 dealii::ExcMessage(
254 "The maximum refinement level must be greater than or equal to the "
255 "global refinement level."));
257 dealii::ExcMessage(
258 "The minimum refinement level must be less than or equal to the "
259 "global refinement level."));
261 dealii::ExcMessage(
262 "The maximum refinement level must be greater than or equal to the "
263 "minimum refinement level."));
264 }
265 // Validate whichever mesh generator is being used
267 {
268 rectangular_mesh.validate();
269 }
271 {
272 spherical_mesh.validate();
273 }
275 {
276 return;
277 }
278 AssertThrow(false, UnreachableCode("Invalid TriangulationType"));
279 }
280
284 [[nodiscard]] bool
285 should_refine_mesh(unsigned int increment) const
286 {
287 return increment % remeshing_period == 0;
288 }
289
290 // Triangulation type
292
293 // Rectangular mesh parameters
295
296 // Spherical mesh parameters
298
299 // Global refinement of mesh
300 unsigned int global_refinement = 0;
301
302 // Element polynomial degree
303 unsigned int degree = 1;
304
305 // Whether adaptive meshing (AMR) is enabled
306 bool has_adaptivity = false;
307
308 // Maximum global refinement for AMR
309 unsigned int max_refinement = 0;
310
311 // Minimum global refinement for AMR
312 unsigned int min_refinement = 0;
313
314 // The number of steps between remeshing
316
317 // The criteria used for remeshing
318 std::map<std::string, RefinementCriterion> refinement_criteria;
319};
320
321template <unsigned int dim>
322inline void
324{
326 << "================================================\n"
327 << " Spatial Discretization\n"
328 << "================================================\n";
329
331 {
332 }
333 else if (type == TriangulationType::Rectangular)
334 {
335 }
336 else if (type == TriangulationType::Custom)
337 {
338 }
339
341 << "Global refinement: " << global_refinement << "\n"
342 << "Degree: " << degree << "\n"
343 << "Adaptivity enabled: " << bool_to_string(has_adaptivity) << "\n"
344 << "Max refinement: " << max_refinement << "\n"
345 << "Min refinement: " << min_refinement << "\n"
346 << "Remeshing period: " << remeshing_period << "\n";
347
348 if (!refinement_criteria.empty())
349 {
350 ConditionalOStreams::pout_summary() << "Refinement criteria:\n";
351 for (const auto &[field_name, criterion] : refinement_criteria)
352 {
354 << " Field name: " << field_name << "\n"
355 << " Criterion type: " << criterion.criterion_string() << "\n"
356 << " Value lower bound: " << criterion.value_lower_bound << "\n"
357 << " Value upper bound: " << criterion.value_upper_bound << "\n"
358 << " Gradient lower bound: " << criterion.gradient_lower_bound << "\n\n";
359 }
360 }
361
362 ConditionalOStreams::pout_summary() << "\n" << std::flush;
363}
364
static dealii::ConditionalOStream & pout_summary()
Log output stream for writing a summary.log file.
Definition conditional_ostreams.cc:34
@ Value
Use value of the variable as a criterion for refinement.
Definition grid_refiner_criterion.h:31
static const double mesh_tolerance
Default mesh tolerance.
Definition types.h:62
Definition conditional_ostreams.cc:20
TriangulationType
Internal enum for various triangulation types.
Definition spatial_discretization.h:26
@ Custom
Definition spatial_discretization.h:29
@ Rectangular
Definition spatial_discretization.h:27
@ Spherical
Definition spatial_discretization.h:28
std::conditional_t< dim==1, dealii::Triangulation< dim >, dealii::parallel::distributed::Triangulation< dim > > Triangulation
Definition spatial_discretization.h:36
Class for rectangular mesh parameters.
Definition spatial_discretization.h:43
void mark_periodic(Triangulation< dim > &triangulation) const
Mark the periodic faces of the mesh.
Definition spatial_discretization.h:134
RectangularMesh(dealii::Tensor< 1, dim, double > _size, dealii::Tensor< 1, dim, double > _lower_bound, std::array< unsigned int, dim > _subdivisions)
Constructor.
Definition spatial_discretization.h:52
void mark_boundaries(Triangulation< dim > &triangulation) const
Mark the boundaries of the mesh.
Definition spatial_discretization.h:105
dealii::Tensor< 1, dim, double > lower_bound
Domain extents in each cartesian direction.
Definition spatial_discretization.h:89
dealii::Tensor< 1, dim, double > size
Domain extents in each cartesian direction.
Definition spatial_discretization.h:84
void generate_mesh(Triangulation< dim > &triangulation) const
Generate the mesh.
Definition spatial_discretization.h:63
std::set< unsigned int > periodic_directions
Which directions have periodic conditions.
Definition spatial_discretization.h:99
std::vector< unsigned int > subdivisions
Mesh subdivisions in each cartesian direction.
Definition spatial_discretization.h:94
void collect_periodic_faces(const MeshType &triangulation, std::vector< dealii::GridTools::PeriodicFacePair< typename MeshType::cell_iterator > > &periodicity_vector) const
Get the periodic face pairs.
Definition spatial_discretization.h:152
RectangularMesh()=default
Constructor.
void validate() const
Validate.
Definition spatial_discretization.h:78
Struct that holds spatial discretization parameters.
Definition spatial_discretization.h:230
unsigned int min_refinement
Definition spatial_discretization.h:312
unsigned int degree
Definition spatial_discretization.h:303
TriangulationType type
Definition spatial_discretization.h:291
RectangularMesh< dim > rectangular_mesh
Definition spatial_discretization.h:294
std::map< std::string, RefinementCriterion > refinement_criteria
Definition spatial_discretization.h:318
void validate()
Validate.
Definition spatial_discretization.h:241
SphericalMesh< dim > spherical_mesh
Definition spatial_discretization.h:297
unsigned int remeshing_period
Definition spatial_discretization.h:315
unsigned int global_refinement
Definition spatial_discretization.h:300
bool should_refine_mesh(unsigned int increment) const
Whether the provided increment is a valid grid refinement step.
Definition spatial_discretization.h:285
unsigned int max_refinement
Definition spatial_discretization.h:309
bool has_adaptivity
Definition spatial_discretization.h:306
void print_parameter_summary() const
Print parameters to summary.log.
Definition spatial_discretization.h:323
Class for spherical mesh parameters.
Definition spatial_discretization.h:175
SphericalMesh()=default
Constructor.
double radius
Radius of the spherical domain.
Definition spatial_discretization.h:212
void generate_mesh(Triangulation< dim > &triangulation) const
Generate the mesh.
Definition spatial_discretization.h:192
void mark_boundaries(Triangulation< dim > &triangulation) const
Mark the boundaries of the mesh.
Definition spatial_discretization.h:219
void validate() const
Validate.
Definition spatial_discretization.h:206
SphericalMesh(double _radius)
Constructor.
Definition spatial_discretization.h:184
const char * bool_to_string(bool boolean)
Convert bool to string.
Definition utilities.h:232