PRISMS-PF Manual
Loading...
Searching...
No Matches
group_solution_handler.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/solution_transfer.h>
7#include <deal.II/lac/affine_constraints.h>
8#include <deal.II/lac/la_parallel_block_vector.h>
9#include <deal.II/lac/la_parallel_vector.h>
10#include <deal.II/matrix_free/matrix_free.h>
11#include <deal.II/multigrid/mg_transfer_global_coarsening.h>
12
20#include <prismspf/core/timer.h>
22#include <prismspf/core/types.h>
23
24#include <prismspf/config.h>
25
26#include <vector>
27
29
44template <unsigned int dim, typename number>
46{
48 std::vector<BlockVector<number>> old_solutions;
49};
50
54template <unsigned int dim, typename number>
56{
57public:
58#if DEAL_II_VERSION_MAJOR >= 9 && DEAL_II_VERSION_MINOR >= 7
59 using SolutionTransfer = dealii::SolutionTransfer<dim, SolutionVector<number>>;
60#else
62 dealii::parallel::distributed::SolutionTransfer<dim, SolutionVector<number>>;
63#endif
64
69 const std::vector<FieldAttributes> &_attributes_list,
70 const MatrixFreeManager<dim, number> &_matrix_free_manager);
71
76 [[nodiscard]] BlockVector<number> &
78
83 [[nodiscard]] const BlockVector<number> &
85
89 [[nodiscard]] SolutionVector<number> &
90 get_solution_vector(unsigned int global_index);
91
95 [[nodiscard]] const SolutionVector<number> &
96 get_solution_vector(unsigned int global_index) const;
97
101 [[nodiscard]] BlockVector<number> &
102 get_old_solution_full_vector(unsigned int age);
103
107 [[nodiscard]] const BlockVector<number> &
108 get_old_solution_full_vector(unsigned int age) const;
109
113 [[nodiscard]] SolutionVector<number> &
114 get_old_solution_vector(unsigned int age, unsigned int global_index);
115
119 [[nodiscard]] const SolutionVector<number> &
120 get_old_solution_vector(unsigned int age, unsigned int global_index) const;
121
125 [[nodiscard]] SolutionLevel<dim, number> &
127
131 [[nodiscard]] const SolutionLevel<dim, number> &
132 get_primary_solutions() const;
133
137 [[nodiscard]] SolutionLevel<dim, number> &
138 get_solution_level(unsigned int relative_level = -1);
139
143 [[nodiscard]] const SolutionLevel<dim, number> &
144 get_solution_level(unsigned int relative_level = -1) const;
145
149 const std::vector<MatrixFree<dim, number>> &
151
155 [[nodiscard]] unsigned int
156 get_block_index(unsigned int global_index) const;
157
161 [[nodiscard]] const SolveBlock &
162 get_solve_block() const;
163
167 [[nodiscard]] const std::vector<unsigned int> &
169
173 [[nodiscard]] const std::vector<unsigned int> &
175
180 void
181 init(const NewDependencyExtents &extents);
182
187 void
188 reinit();
189
193 void
194 update_ghosts() const;
195
199 void
200 zero_out_ghosts() const;
201
205 void
207
211 void
212 apply_constraints(BlockVector<number> &solution_vectors);
213
217 void
219
224 void
226
230 void
231 update();
232
236 void
238
242 void
244
248 void
250
254 template <unsigned int degree>
255 void
257
261 template <unsigned int degree>
262 void
263 mg_transfer_down(const DoFManager<dim, degree> &dof_manager,
264 unsigned int finest_level,
265 bool transfer_old_solutions = false);
266
270 [[nodiscard]] unsigned int
271 num_levels();
272
276 void
277 print_solution_full_vector(std::ostream &out) const;
278
279private:
284
288 std::vector<unsigned int> block_to_global_index;
289
293 std::vector<unsigned int> global_to_block_index;
294
299
303 std::vector<SolutionLevel<dim, number>> solution_levels;
304
309
319 std::vector<SolutionTransfer> block_solution_transfer;
320
324 std::vector<dealii::MGConstrainedDoFs> mg_constraints;
325
329 std::vector<dealii::MGTransferMatrixFree<dim, number>> mg_transfer;
330};
331
332template <unsigned int dim, typename number>
333template <unsigned int degree>
334inline void
336 const DoFManager<dim, degree> &dof_manager)
337{
338 // 1. Initialize constraints
339 const unsigned int num_blocks = solve_block.field_indices.size();
340 mg_constraints = std::vector<dealii::MGConstrainedDoFs>(num_blocks);
341 mg_transfer = std::vector<dealii::MGTransferMatrixFree<dim, number>>(num_blocks);
342 for (unsigned int block_index = 0; block_index < num_blocks; block_index++)
343 {
344 unsigned int field_index = block_to_global_index[block_index];
345 mg_constraints[block_index].initialize(
346 dof_manager.get_field_dof_handler(field_index));
347 // 2. Initialize MG Transfer
348 mg_transfer[block_index].initialize_constraints(mg_constraints[block_index]);
349 mg_transfer[block_index].build(dof_manager.get_field_dof_handler(field_index));
350 }
351}
352
353template <unsigned int dim, typename number>
354template <unsigned int degree>
355inline void
357 const DoFManager<dim, degree> &dof_manager,
358 unsigned int finest_level,
359 bool transfer_old_solutions)
360{
361 Timer::start_section("MG Transfer LHS Dependencies");
362 const unsigned int num_blocks = solve_block.field_indices.size();
363 for (unsigned int block_index = 0; block_index < num_blocks; block_index++)
364 {
365 unsigned int field_index = block_to_global_index[block_index];
366 dealii::MGLevelObject<SolutionVector<number>> temp_mg_solutions(
367 1 + finest_level - solution_levels.size(),
368 finest_level);
369
370 const auto &dof_handler = dof_manager.get_field_dof_handler(field_index);
371
372 // transfer regular solutions to mg levels
373 mg_transfer[block_index].interpolate_to_mg(dof_handler,
374 temp_mg_solutions,
375 primary_solutions.solutions.block(
376 block_index));
377 // swap to actual mg solution vectors
378 for (unsigned int relative_level = 0; relative_level < solution_levels.size();
379 ++relative_level)
380 {
381 unsigned int level = finest_level - relative_level;
382 solution_levels[relative_level]
383 .solutions.block(block_index)
384 .swap(temp_mg_solutions[level]);
385 Timer::start_section("MG LHS Dependencies Update Ghosts");
386 solution_levels[relative_level].solutions.update_ghost_values();
387 Timer::end_section("MG LHS Dependencies Update Ghosts");
388 }
389
390 if (!transfer_old_solutions)
391 {
392 Timer::end_section("MG Transfer LHS Dependencies");
393 return;
394 }
395 // Transfer old solutions
396 for (unsigned int age_index = 0;
397 age_index < solution_levels[0].old_solutions.size();
398 ++age_index)
399 {
400 mg_transfer[block_index].interpolate_to_mg(
401 dof_handler,
402 temp_mg_solutions,
403 solution_levels[0].old_solutions[age_index].block(block_index));
404 for (unsigned int relative_level = 0; relative_level < solution_levels.size();
405 ++relative_level)
406 {
407 unsigned int level = finest_level - relative_level;
408 if (age_index < solution_levels[relative_level].old_solutions.size())
409 {
410 solution_levels[relative_level]
411 .old_solutions[age_index]
412 .block(block_index)
413 .swap(temp_mg_solutions[level]);
414 Timer::start_section("MG LHS Dependencies Update Ghosts");
415 solution_levels[relative_level]
416 .old_solutions[age_index]
417 .update_ghost_values();
418 Timer::end_section("MG LHS Dependencies Update Ghosts");
419 }
420 }
421 }
422 }
423 Timer::end_section("MG Transfer LHS Dependencies");
424}
425
426PRISMS_PF_END_NAMESPACE
Class that manages the deal.II DoFHandlers.
Definition dof_manager.h:25
const dealii::DoFHandler< dim > & get_field_dof_handler(Types::Index field_index) const
Getter function for the DoFHandler (reference).
Definition dof_manager.cc:53
SolutionLevel< dim, number > & get_primary_solutions()
Get the solutions object at a level.
Definition group_solution_handler.cc:106
const SolveBlock & get_solve_block() const
Get the underlying solve block object.
Definition group_solution_handler.cc:149
SolutionVector< number > & get_solution_vector(unsigned int global_index)
Get a solution vector of a given field index.
Definition group_solution_handler.cc:56
void update()
Update and propagate the old solutions.
Definition group_solution_handler.cc:372
SolutionLevel< dim, number > & get_solution_level(unsigned int relative_level=-1)
Get the solutions object at a level.
Definition group_solution_handler.cc:120
BlockVector< number > & get_old_solution_full_vector(unsigned int age)
Get the old solution vector set at a given age.
Definition group_solution_handler.cc:72
void apply_constraints_to_all()
Apply the given constraints to all the solution vectors, including old.
Definition group_solution_handler.cc:318
void reinit_mg_transfer(const DoFManager< dim, degree > &dof_manager)
Reinit the solution transfer objects.
Definition group_solution_handler.h:335
unsigned int num_levels()
Number of refinement levels that will be tracked.
Definition group_solution_handler.cc:416
void init(const NewDependencyExtents &extents)
Initialize the solution set.
Definition group_solution_handler.cc:170
void reinit()
Reinitialize the solution set.
Definition group_solution_handler.cc:201
std::vector< SolutionLevel< dim, number > > solution_levels
Solutions projected to each mg level as dependencies.
Definition group_solution_handler.h:303
std::vector< unsigned int > block_to_global_index
Mapping from block index to global field index.
Definition group_solution_handler.h:288
std::vector< unsigned int > global_to_block_index
Mapping from global field index to block index.
Definition group_solution_handler.h:293
void apply_constraints()
Apply the constraints to the solution vector.
Definition group_solution_handler.cc:337
SolutionLevel< dim, number > primary_solutions
Primary solutions.
Definition group_solution_handler.h:298
void print_solution_full_vector(std::ostream &out) const
Print the solution vector set.
Definition group_solution_handler.cc:408
void prepare_for_solution_transfer()
Prepare for solution transfer.
Definition group_solution_handler.cc:257
const std::vector< unsigned int > & get_block_to_global_index() const
Get the global index from the block index.
Definition group_solution_handler.cc:163
const std::vector< MatrixFree< dim, number > > & get_matrix_free_levels() const
Get the underlying matrix_free objects.
Definition group_solution_handler.cc:134
void apply_initial_condition_for_old_fields()
Apply initial condition to the old fields. For now, this simply copies the values in the normal field...
Definition group_solution_handler.cc:359
BlockVector< number > & get_solution_full_vector()
Get the solution vector set. This contains all the normal fields and is typically used for output.
Definition group_solution_handler.cc:41
const MatrixFreeManager< dim, number > * matrix_free_manager
Pointer to MatrixFree manager.
Definition group_solution_handler.h:308
void execute_solution_transfer()
Transfer solutions.
Definition group_solution_handler.cc:277
void init_solution_transfer()
Reinit the solution transfer objects.
Definition group_solution_handler.cc:243
void zero_out_ghosts() const
Zero out the ghost values.
Definition group_solution_handler.cc:311
std::vector< dealii::MGTransferMatrixFree< dim, number > > mg_transfer
Utility object to transfer solutions between multigrid levels.
Definition group_solution_handler.h:329
SolveBlock solve_block
Information about the solve block this handler is responsible for.
Definition group_solution_handler.h:283
dealii::parallel::distributed::SolutionTransfer< dim, SolutionVector< number > > SolutionTransfer
Definition group_solution_handler.h:61
void update_ghosts() const
Update the ghost values.
Definition group_solution_handler.cc:300
GroupSolutionHandler(SolveBlock _solve_block, const std::vector< FieldAttributes > &_attributes_list, const MatrixFreeManager< dim, number > &_matrix_free_manager)
Constructor.
Definition group_solution_handler.cc:22
SolutionVector< number > & get_old_solution_vector(unsigned int age, unsigned int global_index)
Get a solution vector of a given field index at a given age.
Definition group_solution_handler.cc:88
std::vector< SolutionTransfer > block_solution_transfer
Utility for solution transfer to different mesh (for AMR). Can only work on one block at a time.
Definition group_solution_handler.h:319
std::vector< dealii::MGConstrainedDoFs > mg_constraints
Constraints needed for mg transfer object.
Definition group_solution_handler.h:324
const std::vector< unsigned int > & get_global_to_block_index() const
Get the block index from the global index.
Definition group_solution_handler.cc:156
unsigned int get_block_index(unsigned int global_index) const
Get the block index from the global field index.
Definition group_solution_handler.cc:142
void mg_transfer_down(const DoFManager< dim, degree > &dof_manager, unsigned int finest_level, bool transfer_old_solutions=false)
Transfer solutions to mg levels.
Definition group_solution_handler.h:356
Containers for matrix free objects.
Definition matrix_free_manager.h:45
Structure to hold the attributes of a solve-block.
Definition solve_block.h:59
static void start_section(const char *name)
Start a new timer section.
Definition timer.cc:116
static void end_section(const char *name)
End the timer section.
Definition timer.cc:127
typename BlockVector< number >::BlockType SolutionVector
Typedef for solution vector.
Definition matrix_free_manager.h:38
dealii::LinearAlgebra::distributed::BlockVector< number > BlockVector
Typedef for solution block vector.
Definition matrix_free_manager.h:32
Definition conditional_ostreams.cc:20
Definition dependency_extents.h:76
The solution vectors with respect to on some multigrid level.
Definition group_solution_handler.h:46
std::vector< BlockVector< number > > old_solutions
Definition group_solution_handler.h:48
BlockVector< number > solutions
Definition group_solution_handler.h:47