ryujin 2.1.1 revision 284c1ee75f38e11ba18808dd0d991d905cf7c040
geometry_rectangular_domain.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
9
10namespace ryujin
11{
12 namespace Geometries
13 {
34 template <int dim>
35 class RectangularDomain : public Geometry<dim>
36 {
37 public:
38 RectangularDomain(const std::string subsection)
39 : Geometry<dim>("rectangular domain", subsection)
40 {
41 this->add_parameter("position bottom left",
42 point_left_,
43 "Position of bottom left corner");
44
45 for (unsigned int d = 0; d < dim; ++d)
46 point_right_[d] = 20.0;
47 this->add_parameter(
48 "position top right", point_right_, "Position of top right corner");
49
50 grading_push_forward_ = dim == 1 ? "x" : (dim == 2 ? "x;y" : "x;y;z;");
51 this->add_parameter("grading push forward",
52 grading_push_forward_,
53 "push forward of grading manifold");
54
55 grading_pull_back_ = grading_push_forward_;
56 this->add_parameter("grading pull back",
57 grading_pull_back_,
58 "pull back of grading manifold");
59
60 subdivisions_x_ = 1;
61 subdivisions_y_ = 1;
62 subdivisions_z_ = 1;
63 boundary_back_ = Boundary::dirichlet;
64 boundary_bottom_ = Boundary::dirichlet;
65 boundary_front_ = Boundary::dirichlet;
66 boundary_left_ = Boundary::dirichlet;
67 boundary_right_ = Boundary::dirichlet;
68 boundary_top_ = Boundary::dirichlet;
69
70 this->add_parameter("subdivisions x",
71 subdivisions_x_,
72 "number of subdivisions in x direction");
73 this->add_parameter(
74 "boundary condition left",
75 boundary_left_,
76 "Type of boundary condition enforced on the left side of the "
77 "domain (faces with normal in negative x direction)");
78 this->add_parameter(
79 "boundary condition right",
80 boundary_right_,
81 "Type of boundary condition enforced on the right side of the "
82 "domain (faces with normal in positive x direction)");
83
84 if constexpr (dim >= 2) {
85 this->add_parameter("subdivisions y",
86 subdivisions_y_,
87 "number of subdivisions in y direction");
88 this->add_parameter(
89 "boundary condition bottom",
90 boundary_bottom_,
91 "Type of boundary condition enforced on the bottom side of the "
92 "domain (faces with normal in negative y direction)");
93 this->add_parameter(
94 "boundary condition top",
95 boundary_top_,
96 "Type of boundary condition enforced on the top side of the "
97 "domain (faces with normal in positive y direction)");
98 }
99
100 if constexpr (dim == 3) {
101 this->add_parameter("subdivisions y",
102 subdivisions_y_,
103 "number of subdivisions in z direction");
104 this->add_parameter(
105 "boundary condition back",
106 boundary_back_,
107 "Type of boundary condition enforced on the back side of the "
108 "domain (faces with normal in negative z direction)");
109 this->add_parameter(
110 "boundary condition front",
111 boundary_front_,
112 "Type of boundary condition enforced on the front side of the "
113 "domain (faces with normal in positive z direction)");
114 }
115 }
116
117
119 typename Geometry<dim>::Triangulation &triangulation) final
120 {
121 /* create mesh: */
122
123 dealii::Triangulation<dim, dim> tria1;
124 tria1.set_mesh_smoothing(triangulation.get_mesh_smoothing());
125
126 if constexpr (dim == 1) {
127 dealii::GridGenerator::subdivided_hyper_rectangle<dim, dim>(
128 tria1, {subdivisions_x_}, point_left_, point_right_);
129 } else if constexpr (dim == 2) {
130 dealii::GridGenerator::subdivided_hyper_rectangle(
131 tria1,
132 {subdivisions_x_, subdivisions_y_},
133 point_left_,
134 point_right_);
135 } else if constexpr (dim == 3) {
136 dealii::GridGenerator::subdivided_hyper_rectangle(
137 tria1,
138 {subdivisions_x_, subdivisions_y_, subdivisions_z_},
139 point_left_,
140 point_right_);
141 }
142
143 triangulation.copy_triangulation(tria1);
144
145 /* create grading: */
146
147 // FIXME: We should ideally check the push forward and pull back
148 // for compatiblity.
149 if (grading_push_forward_ != grading_pull_back_) {
150 dealii::FunctionManifold<dim> grading(grading_push_forward_,
151 grading_pull_back_);
152 triangulation.set_all_manifold_ids(1);
153 triangulation.set_manifold(1, grading);
154 }
155
156 /* set boundary ids: */
157
158 for (auto cell : triangulation.active_cell_iterators()) {
159 for (auto f : dealii::GeometryInfo<dim>::face_indices()) {
160 auto face = cell->face(f);
161 if (!face->at_boundary())
162 continue;
163 const auto position = face->center();
164
165 if (position[0] < point_left_[0] + 1.e-8)
166 face->set_boundary_id(boundary_left_);
167 if (position[0] > point_right_[0] - 1.e-8)
168 face->set_boundary_id(boundary_right_);
169
170 if constexpr (dim >= 2) {
171 if (position[1] < point_left_[1] + 1.e-8)
172 face->set_boundary_id(boundary_bottom_);
173 if (position[1] > point_right_[1] - 1.e-8)
174 face->set_boundary_id(boundary_top_);
175 }
176
177 if constexpr (dim == 3) {
178 if (position[2] < point_left_[2] + 1.e-8)
179 face->set_boundary_id(boundary_back_);
180 if (position[2] > point_right_[2] - 1.e-8)
181 face->set_boundary_id(boundary_front_);
182 }
183 } /*for*/
184 } /*for*/
185
186 std::vector<int> directions;
187
188 if (boundary_left_ == Boundary::periodic ||
189 boundary_right_ == Boundary::periodic) {
190 AssertThrow(boundary_left_ == boundary_right_,
191 dealii::ExcMessage(
192 "For prescribing periodic boundaries in x-direction, "
193 "both, the left and right boundary conditions must "
194 "be set to periodic"));
195 directions.push_back(0);
196 }
197
198 if (dim >= 2 && (boundary_bottom_ == Boundary::periodic ||
199 boundary_top_ == Boundary::periodic)) {
200 AssertThrow(boundary_bottom_ == boundary_top_,
201 dealii::ExcMessage(
202 "For prescribing periodic boundaries in y-direction, "
203 "both, the bottom and top boundary conditions must "
204 "be set to periodic"));
205 directions.push_back(1);
206 }
207
208 if (dim == 3 && (boundary_back_ == Boundary::periodic ||
209 boundary_front_ == Boundary::periodic)) {
210 AssertThrow(boundary_back_ == boundary_front_,
211 dealii::ExcMessage(
212 "For prescribing periodic boundaries in z-direction, "
213 "both, the back and front boundary conditions must "
214 "be set to periodic"));
215 directions.push_back(2);
216 }
217
218 if constexpr (dim != 1) {
219 if (!directions.empty()) {
220 std::vector<dealii::GridTools::PeriodicFacePair<
221 typename dealii::Triangulation<dim>::cell_iterator>>
222 periodic_faces;
223
224 for (const auto direction : directions)
225 dealii::GridTools::collect_periodic_faces(
226 triangulation,
227 /*b_id */ Boundary::periodic,
228 /*direction*/ direction,
229 periodic_faces);
230
231 triangulation.add_periodicity(periodic_faces);
232 }
233 }
234
235 AssertThrow(dim != 1 || directions.empty(),
236 dealii::ExcMessage("One dimensional periodic boundary "
237 "conditions are not implemented"));
238 }
239
240 private:
241 dealii::Point<dim> point_left_;
242 dealii::Point<dim> point_right_;
243
244 unsigned int subdivisions_x_;
245 unsigned int subdivisions_y_;
246 unsigned int subdivisions_z_;
247
248 std::string grading_push_forward_;
249 std::string grading_pull_back_;
250
251 Boundary boundary_back_;
252 Boundary boundary_bottom_;
253 Boundary boundary_front_;
254 Boundary boundary_left_;
255 Boundary boundary_right_;
256 Boundary boundary_top_;
257 };
258 } /* namespace Geometries */
259} /* namespace ryujin */
void create_triangulation(typename Geometry< dim >::Triangulation &triangulation) final
RectangularDomain(const std::string subsection)
typename Discretization< dim >::Triangulation Triangulation
Definition: geometry.h:38