ryujin 2.1.1 revision dbf0e3ba7acdb60b6d558e4257815df4a8f8daf9
geometry_cylinder.h
Go to the documentation of this file.
1//
2// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
3// Copyright (C) 2022 - 2023 by the ryujin authors
4//
5
6#pragma once
7
8#include <compile_time_options.h>
9
11
12namespace ryujin
13{
14 namespace GridGenerator
15 {
30 template <int dim, int spacedim, template <int, int> class Triangulation>
31 void cylinder(Triangulation<dim, spacedim> &,
32 const double /*length*/,
33 const double /*height*/,
34 const double /*cylinder_position*/,
35 const double /*cylinder_height*/)
36 {
37 AssertThrow(false, dealii::ExcNotImplemented());
38 __builtin_trap();
39 }
40
41
42#ifndef DOXYGEN
43 template <template <int, int> class Triangulation>
44 void cylinder(Triangulation<2, 2> &triangulation,
45 const double length,
46 const double height,
47 const double cylinder_position,
48 const double cylinder_diameter)
49 {
50 constexpr int dim = 2;
51
52 using namespace dealii;
53
54 dealii::Triangulation<dim, dim> tria1, tria2, tria3, tria4, tria5, tria6,
55 tria7;
56
57 GridGenerator::hyper_cube_with_cylindrical_hole(
58 tria1, cylinder_diameter / 2., cylinder_diameter, 0.5, 1, false);
59
60 GridGenerator::subdivided_hyper_rectangle(
61 tria2,
62 {2, 1},
63 Point<2>(-cylinder_diameter, -cylinder_diameter),
64 Point<2>(cylinder_diameter, -height / 2.));
65
66 GridGenerator::subdivided_hyper_rectangle(
67 tria3,
68 {2, 1},
69 Point<2>(-cylinder_diameter, cylinder_diameter),
70 Point<2>(cylinder_diameter, height / 2.));
71
72 GridGenerator::subdivided_hyper_rectangle(
73 tria4,
74 {6, 2},
75 Point<2>(cylinder_diameter, -cylinder_diameter),
76 Point<2>(length - cylinder_position, cylinder_diameter));
77
78 GridGenerator::subdivided_hyper_rectangle(
79 tria5,
80 {6, 1},
81 Point<2>(cylinder_diameter, cylinder_diameter),
82 Point<2>(length - cylinder_position, height / 2.));
83
84 GridGenerator::subdivided_hyper_rectangle(
85 tria6,
86 {6, 1},
87 Point<2>(cylinder_diameter, -height / 2.),
88 Point<2>(length - cylinder_position, -cylinder_diameter));
89
90 tria7.set_mesh_smoothing(triangulation.get_mesh_smoothing());
91 GridGenerator::merge_triangulations(
92 {&tria1, &tria2, &tria3, &tria4, &tria5, &tria6},
93 tria7,
94 1.e-12,
95 true);
96 triangulation.copy_triangulation(tria7);
97
98 /* Restore polar manifold for disc: */
99
100 triangulation.set_manifold(0, PolarManifold<2>(Point<2>()));
101
102 /* Fix up position of left boundary: */
103
104 for (auto cell : triangulation.active_cell_iterators())
105 for (unsigned int v : cell->vertex_indices()) {
106 auto &vertex = cell->vertex(v);
107 if (vertex[0] <= -cylinder_diameter + 1.e-6)
108 vertex[0] = -cylinder_position;
109 }
110
111 /*
112 * Set boundary ids:
113 */
114
115 for (auto cell : triangulation.active_cell_iterators()) {
116 for (auto f : cell->face_indices()) {
117 const auto face = cell->face(f);
118
119 if (!face->at_boundary())
120 continue;
121
122 /*
123 * We want slip boundary conditions (i.e. indicator 1) at top and
124 * bottom of the channel, as well as on the obstacle. On the left
125 * side we set inflow conditions (indicator 2) and on the right
126 * side we set indicator 0, i.e. do nothing.
127 */
128
129 const auto center = face->center();
130
131 if (center[0] > length - cylinder_position - 1.e-6) {
132 face->set_boundary_id(Boundary::do_nothing);
133 continue;
134 }
135
136 if (center[0] < -cylinder_position + 1.e-6) {
137 face->set_boundary_id(Boundary::dirichlet);
138 continue;
139 }
140
141 // the rest:
142 face->set_boundary_id(Boundary::slip);
143 }
144 }
145 }
146
147
148 template <template <int, int> class Triangulation>
149 void cylinder(Triangulation<3, 3> &triangulation,
150 const double length,
151 const double height,
152 const double cylinder_position,
153 const double cylinder_diameter)
154 {
155 using namespace dealii;
156
157 dealii::Triangulation<2, 2> tria1;
158
159 cylinder(tria1, length, height, cylinder_position, cylinder_diameter);
160
161 dealii::Triangulation<3, 3> tria2;
162 tria2.set_mesh_smoothing(triangulation.get_mesh_smoothing());
163
164 GridGenerator::extrude_triangulation(tria1, 4, height, tria2, true);
165 GridTools::transform(
166 [height](auto point) {
167 return point - dealii::Tensor<1, 3>{{0, 0, height / 2.}};
168 },
169 tria2);
170
171 triangulation.copy_triangulation(tria2);
172
173 /*
174 * Reattach an appropriate manifold ID:
175 */
176
177 triangulation.set_manifold(
178 0, CylindricalManifold<3>(Tensor<1, 3>{{0., 0., 1.}}, Point<3>()));
179
180 /*
181 * Set boundary ids:
182 */
183
184 for (auto cell : triangulation.active_cell_iterators()) {
185 for (auto f : cell->face_indices()) {
186 const auto face = cell->face(f);
187
188 if (!face->at_boundary())
189 continue;
190
191 /*
192 * We want slip boundary conditions (i.e. indicator 1) almost
193 * everywhere except on the faces with normal in x-direction.
194 * There, on the left side we set inflow conditions (indicator 2)
195 * and on the right side we set indicator 0, i.e. do nothing.
196 */
197
198 const auto center = face->center();
199
200 if (center[0] > length - cylinder_position - 1.e-6) {
201 face->set_boundary_id(Boundary::do_nothing);
202 continue;
203 }
204
205 if (center[0] < -cylinder_position + 1.e-6) {
206 face->set_boundary_id(Boundary::dirichlet);
207 continue;
208 }
209
210 // the rest:
211 face->set_boundary_id(Boundary::slip);
212 }
213 }
214 }
215#endif
216 } /* namespace GridGenerator */
217
218
219 namespace Geometries
220 {
227 template <int dim>
228 class Cylinder : public Geometry<dim>
229 {
230 public:
231 Cylinder(const std::string &subsection)
232 : Geometry<dim>("cylinder", subsection)
233 {
234 length_ = 4.;
235 this->add_parameter(
236 "length", length_, "length of computational domain");
237
238 height_ = 2.;
239 this->add_parameter(
240 "height", height_, "height of computational domain");
241
242 object_position_ = 0.6;
243 this->add_parameter("object position",
244 object_position_,
245 "x position of immersed cylinder center point");
246
247 object_diameter_ = 0.5;
248 this->add_parameter("object diameter",
249 object_diameter_,
250 "diameter of immersed cylinder");
251 }
252
254 dealii::Triangulation<dim> &triangulation) const final
255 {
256 GridGenerator::cylinder(triangulation,
257 length_,
258 height_,
259 object_position_,
260 object_diameter_);
261 }
262
263 private:
264 double length_;
265 double height_;
266 double object_position_;
267 double object_diameter_;
268 };
269 } /* namespace Geometries */
270} /* namespace ryujin */
void create_coarse_triangulation(dealii::Triangulation< dim > &triangulation) const final
Cylinder(const std::string &subsection)
void cylinder(Triangulation< dim, spacedim > &, const double, const double, const double, const double)