ExaDG
Loading...
Searching...
No Matches
solution_transfer.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2023 by the ExaDG authors
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * ______________________________________________________________________
20 */
21
22#ifndef INCLUDE_EXADG_OPERATORS_SOLUTION_TRANSFER_H
23#define INCLUDE_EXADG_OPERATORS_SOLUTION_TRANSFER_H
24
25// deal.II
26#include <deal.II/distributed/solution_transfer.h>
27#include <deal.II/distributed/tria.h>
28#include <deal.II/grid/tria.h>
29#include <deal.II/numerics/solution_transfer.h>
30
31namespace ExaDG
32{
33template<int dim, typename VectorType>
35{
36public:
37 /*
38 * Constructor.
39 */
40 SolutionTransfer(dealii::DoFHandler<dim> const & dof_handler_in)
41 {
42 dof_handler = &dof_handler_in;
43 }
44
45 void
46 prepare_coarsening_and_refinement(std::vector<VectorType *> & vectors)
47 {
48 // Container vectors_old_grid hold vectors for interpolation *REQUIRED* for
49 // interpolate_after_coarsening_and_refinement(). Thus makes an actual copy.
50 // In the case of parallel::distributed::Triangulation, pointers are sufficient.
51 vectors_old_grid.resize(vectors.size());
52 std::vector<VectorType const *> vectors_old_grid_ptr(vectors.size());
53 for(unsigned int i = 0; i < vectors.size(); ++i)
54 {
55 vectors[i]->update_ghost_values();
56
57 if(is_parallel_distributed_triangulation())
58 {
59 vectors_old_grid_ptr[i] = vectors[i];
60 }
61 else
62 {
63 VectorType const & vector = *vectors[i];
64 dealii::IndexSet indices(vector.size());
65 indices.add_range(0, vector.size());
66 vectors_old_grid[i].reinit(vector.locally_owned_elements(),
67 indices,
68 vector.get_mpi_communicator());
69 vectors_old_grid[i].copy_locally_owned_data_from(vector);
70 vectors_old_grid[i].update_ghost_values();
71 }
72 }
73
74 // SolutionTransfer object type depends on the triangulation type.
75 if(is_parallel_distributed_triangulation())
76 {
77 pd_solution_transfer =
78 std::make_shared<dealii::parallel::distributed::SolutionTransfer<dim, VectorType>>(
79 *dof_handler);
80
81 pd_solution_transfer->prepare_for_coarsening_and_refinement(vectors_old_grid_ptr);
82 }
83 else
84 {
85 solution_transfer = std::make_shared<dealii::SolutionTransfer<dim, VectorType>>(*dof_handler);
86 solution_transfer->prepare_for_coarsening_and_refinement(vectors_old_grid);
87 }
88 }
89
90 void
91 interpolate_after_coarsening_and_refinement(std::vector<VectorType *> & vectors)
92 {
93 // Note that the sequence of vectors per DofHandler/SolutionTransfer
94 // defined in Operator<dim, Number>::prepare_coarsening_and_refinement()
95 // and solution transfer calls here *need to match*.
96 if(is_parallel_distributed_triangulation())
97 {
98 pd_solution_transfer->interpolate(vectors);
99 }
100 else
101 {
102 // Initialize ghosted vectors for interpolation.
103 std::vector<VectorType> vectors_new_grid(vectors.size());
104 for(unsigned int i = 0; i < vectors.size(); ++i)
105 {
106 VectorType const & vector = *vectors[i];
107 dealii::IndexSet indices(vector.size());
108 indices.add_range(0, vector.size());
109 vectors_new_grid[i].reinit(vector.locally_owned_elements(),
110 indices,
111 vector.get_mpi_communicator());
112 }
113
114 solution_transfer->interpolate(vectors_old_grid, vectors_new_grid);
115
116 // Copy ghosted vectors to output.
117 for(unsigned int i = 0; i < vectors.size(); ++i)
118 {
119 vectors[i]->copy_locally_owned_data_from(vectors_new_grid[i]);
120 }
121 }
122
123 // Clear the containers holding actual copies or pointers depending
124 // on the SolutionTransfer type. In both cases, the containers need
125 // to be in scope when execute_coarsening_and_refinement() is called.
126 vectors_old_grid.clear();
127 }
128
129private:
130 bool
131 is_parallel_distributed_triangulation() const
132 {
133 return (dynamic_cast<dealii::parallel::distributed::Triangulation<dim> const *>(
134 &dof_handler->get_triangulation()));
135 }
136
137 std::vector<VectorType> vectors_old_grid;
138
139 std::shared_ptr<dealii::SolutionTransfer<dim, VectorType>> solution_transfer;
140 std::shared_ptr<dealii::parallel::distributed::SolutionTransfer<dim, VectorType>>
141 pd_solution_transfer;
142
143 dealii::SmartPointer<dealii::DoFHandler<dim> const> dof_handler;
144};
145} // namespace ExaDG
146
147#endif /* INCLUDE_EXADG_OPERATORS_SOLUTION_TRANSFER_H */
Definition solution_transfer.h:35
Definition driver.cpp:33