ExaDG
Loading...
Searching...
No Matches
deformed_cube_manifold.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 APPLICATIONS_GRID_TOOLS_DEFORMED_CUBE_MANIFOLD_H_
23#define APPLICATIONS_GRID_TOOLS_DEFORMED_CUBE_MANIFOLD_H_
24
25#include <deal.II/grid/manifold_lib.h>
26
27namespace ExaDG
28{
34template<int dim>
35class DeformedCubeManifold : public dealii::ChartManifold<dim, dim, dim>
36{
37public:
38 DeformedCubeManifold(double const left,
39 double const right,
40 double const deformation,
41 unsigned int const frequency = 1)
42 : left(left), right(right), deformation(deformation), frequency(frequency)
43 {
44 }
45
46 dealii::Point<dim>
47 push_forward(dealii::Point<dim> const & chart_point) const override
48 {
49 double sinval = deformation;
50 for(unsigned int d = 0; d < dim; ++d)
51 sinval *=
52 std::sin(frequency * dealii::numbers::PI * (chart_point(d) - left) / (right - left));
53 dealii::Point<dim> space_point;
54 for(unsigned int d = 0; d < dim; ++d)
55 space_point(d) = chart_point(d) + sinval;
56
57 return space_point;
58 }
59
60 dealii::Point<dim>
61 pull_back(dealii::Point<dim> const & space_point) const override
62 {
63 dealii::Point<dim> x = space_point;
64 dealii::Point<dim> one;
65 for(unsigned int d = 0; d < dim; ++d)
66 one(d) = 1.;
67
68 // Newton iteration to solve the nonlinear equation given by the point
69 dealii::Tensor<1, dim> sinvals, residual;
70
71 for(unsigned int d = 0; d < dim; ++d)
72 sinvals[d] = std::sin(frequency * dealii::numbers::PI * (x(d) - left) / (right - left));
73 double sinval = deformation;
74 for(unsigned int d = 0; d < dim; ++d)
75 sinval *= sinvals[d];
76 residual = space_point - (x + sinval * one);
77
78 unsigned int its = 0;
79 while(residual.norm() > 1e-12 and its < 100)
80 {
81 dealii::Tensor<2, dim> jacobian;
82 for(unsigned int d = 0; d < dim; ++d)
83 jacobian[d][d] = 1.;
84 for(unsigned int d = 0; d < dim; ++d)
85 {
86 double sinval_der =
87 deformation * frequency / (right - left) * dealii::numbers::PI *
88 std::cos(frequency * dealii::numbers::PI * (x(d) - left) / (right - left));
89 for(unsigned int e = 0; e < dim; ++e)
90 if(e != d)
91 sinval_der *= sinvals[e];
92 for(unsigned int e = 0; e < dim; ++e)
93 jacobian[e][d] += sinval_der;
94 }
95
96 x += invert(jacobian) * residual;
97
98 for(unsigned int d = 0; d < dim; ++d)
99 sinvals[d] = std::sin(frequency * dealii::numbers::PI * (x(d) - left) / (right - left));
100 sinval = deformation;
101 for(unsigned int d = 0; d < dim; ++d)
102 sinval *= sinvals[d];
103 residual = space_point - (x + sinval * one);
104
105 ++its;
106 }
107
108 AssertThrow(residual.norm() < 1e-12, dealii::ExcMessage("Newton for point did not converge."));
109
110 return x;
111 }
112
113 std::unique_ptr<dealii::Manifold<dim>>
114 clone() const override
115 {
116 return std::make_unique<DeformedCubeManifold<dim>>(left, right, deformation, frequency);
117 }
118
119private:
120 double const left;
121 double const right;
122 double const deformation;
123 unsigned int const frequency;
124};
125
126template<int dim>
127void
128apply_deformed_cube_manifold(dealii::Triangulation<dim> & triangulation,
129 double const left,
130 double const right,
131 double const deformation,
132 unsigned int const frequency)
133{
134 DeformedCubeManifold<dim> manifold(left, right, deformation, frequency);
135 triangulation.set_all_manifold_ids(1);
136 triangulation.set_manifold(1, manifold);
137
138 // the vertices need to be placed correctly according to the manifold description such that mesh
139 // refinements and high-order mappings are done correctly (which invoke pull-back and push-forward
140 // operations)
141 std::vector<bool> vertex_touched(triangulation.n_vertices(), false);
142
143 for(auto const & cell : triangulation.cell_iterators())
144 {
145 for(unsigned int const v : cell->vertex_indices())
146 {
147 if(vertex_touched[cell->vertex_index(v)] == false)
148 {
149 dealii::Point<dim> & vertex = cell->vertex(v);
150 dealii::Point<dim> new_point = manifold.push_forward(vertex);
151 vertex = new_point;
152 vertex_touched[cell->vertex_index(v)] = true;
153 }
154 }
155 }
156}
157
158} // namespace ExaDG
159
160#endif /* APPLICATIONS_GRID_TOOLS_DEFORMED_CUBE_MANIFOLD_H_ */
Definition deformed_cube_manifold.h:36
Definition driver.cpp:33