ExaDG
Loading...
Searching...
No Matches
solution_interpolation_between_triangulations.h
1/* ______________________________________________________________________
2 *
3 * ExaDG - High-Order Discontinuous Galerkin for the Exa-Scale
4 *
5 * Copyright (C) 2021 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_INTERPOLATION_BETWEEN_TRIANGULATIONS_H
23#define INCLUDE_EXADG_OPERATORS_SOLUTION_INTERPOLATION_BETWEEN_TRIANGULATIONS_H
24
25// deal.II
26#include <deal.II/base/mpi_remote_point_evaluation.h>
27#include <deal.II/dofs/dof_handler.h>
28#include <deal.II/fe/mapping.h>
29#include <deal.II/numerics/vector_tools.h>
30
31namespace ExaDG
32{
37template<int dim>
39{
40public:
49 void
50 reinit(dealii::DoFHandler<dim> const & dof_handler_dst_in,
51 dealii::Mapping<dim> const & mapping_dst_in,
52 dealii::DoFHandler<dim> const & dof_handler_src_in,
53 dealii::Mapping<dim> const & mapping_src_in)
54 {
55 AssertThrow(
56 dof_handler_dst_in.get_fe().has_generalized_support_points(),
57 dealii::ExcMessage(
58 "Solution can only be interpolated to finite elements that have support points."));
59
60 dof_handler_dst = &dof_handler_dst_in;
61 dof_handler_src = &dof_handler_src_in;
62
63 rpe.reinit(collect_mapped_support_points(dof_handler_dst_in, mapping_dst_in),
64 dof_handler_src_in.get_triangulation(),
65 mapping_src_in);
66 }
67
76 template<int n_components, typename VectorType1, typename VectorType2>
77 void
78 interpolate_solution(VectorType1 & dst,
79 VectorType2 const & src,
80 dealii::VectorTools::EvaluationFlags::EvaluationFlags const flags =
81 dealii::VectorTools::EvaluationFlags::avg) const
82 {
83 AssertThrow(src.size() == dof_handler_src->n_dofs(),
84 dealii::ExcMessage("Dimensions do not fit."));
85 AssertThrow(dst.size() == dof_handler_dst->n_dofs(),
86 dealii::ExcMessage("Dimensions do not fit."));
87
88 src.update_ghost_values();
89 auto const values =
90 dealii::VectorTools::point_values<n_components>(rpe, *dof_handler_src, src, flags);
91 src.zero_out_ghost_values();
92
93 fill_dof_vector_with_values<n_components>(dst, *dof_handler_dst, values);
94 }
95
96private:
97 std::vector<dealii::Point<dim>>
98 collect_mapped_support_points(dealii::DoFHandler<dim> const & dof_handler,
99 dealii::Mapping<dim> const & mapping) const
100 {
101 std::vector<dealii::Point<dim>> support_points;
102
103 for(auto const & cell : dof_handler.active_cell_iterators())
104 {
105 if(cell->is_locally_owned())
106 {
107 auto cellwise_support_points = cell->get_fe().get_generalized_support_points();
108
109 for(auto & csp : cellwise_support_points)
110 csp = mapping.transform_unit_to_real_cell(cell, csp);
111
112 support_points.insert(support_points.end(),
113 cellwise_support_points.begin(),
114 cellwise_support_points.end());
115 }
116 }
117
118 return support_points;
119 }
120
121 template<int n_components, typename VectorType, typename value_type>
122 void
123 fill_dof_vector_with_values(VectorType & dst,
124 dealii::DoFHandler<dim> const & dof_handler,
125 std::vector<value_type> const & values) const
126 {
127 auto ptr = values.begin();
128 for(auto const & cell : dof_handler.active_cell_iterators())
129 {
130 if(cell->is_locally_owned())
131 {
132 auto const & fe = cell->get_fe();
133
134 std::vector<double> dof_values(fe.n_dofs_per_cell());
135 unsigned int const n_support_points = fe.get_generalized_support_points().size();
136 std::vector<dealii::Vector<double>> component_dof_values(
137 n_support_points, dealii::Vector<double>(n_components));
138
139 for(unsigned int i = 0; i < n_support_points; ++i)
140 {
141 if constexpr(n_components == 1)
142 {
143 component_dof_values[i] = *ptr;
144 }
145 else
146 {
147 component_dof_values[i] =
148 std::move(dealii::Vector<double>(ptr->begin_raw(), ptr->end_raw()));
149 }
150
151 ++ptr;
152 }
153
154 fe.convert_generalized_support_point_values_to_dof_values(component_dof_values, dof_values);
155
156 cell->set_dof_values(dealii::Vector<typename VectorType::value_type>(dof_values.begin(),
157 dof_values.end()),
158 dst);
159 }
160 }
161 }
162
163 dealii::SmartPointer<dealii::DoFHandler<dim> const> dof_handler_dst;
164 dealii::SmartPointer<dealii::DoFHandler<dim> const> dof_handler_src;
165 dealii::Utilities::MPI::RemotePointEvaluation<dim> rpe;
166};
167
168} // namespace ExaDG
169
170#endif /* INCLUDE_EXADG_OPERATORS_SOLUTION_INTERPOLATION_BETWEEN_TRIANGULATIONS_H */
Definition solution_interpolation_between_triangulations.h:39
void reinit(dealii::DoFHandler< dim > const &dof_handler_dst_in, dealii::Mapping< dim > const &mapping_dst_in, dealii::DoFHandler< dim > const &dof_handler_src_in, dealii::Mapping< dim > const &mapping_src_in)
Definition solution_interpolation_between_triangulations.h:50
void interpolate_solution(VectorType1 &dst, VectorType2 const &src, dealii::VectorTools::EvaluationFlags::EvaluationFlags const flags=dealii::VectorTools::EvaluationFlags::avg) const
Definition solution_interpolation_between_triangulations.h:78
Definition driver.cpp:33