rectangle_with_hole_domain.h
Go to the documentation of this file.
1// LIC// ====================================================================
2// LIC// This file forms part of oomph-lib, the object-oriented,
3// LIC// multi-physics finite-element library, available
4// LIC// at http://www.oomph-lib.org.
5// LIC//
6// LIC// Copyright (C) 2006-2024 Matthias Heil and Andrew Hazel
7// LIC//
8// LIC// This library is free software; you can redistribute it and/or
9// LIC// modify it under the terms of the GNU Lesser General Public
10// LIC// License as published by the Free Software Foundation; either
11// LIC// version 2.1 of the License, or (at your option) any later version.
12// LIC//
13// LIC// This library is distributed in the hope that it will be useful,
14// LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16// LIC// Lesser General Public License for more details.
17// LIC//
18// LIC// You should have received a copy of the GNU Lesser General Public
19// LIC// License along with this library; if not, write to the Free Software
20// LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21// LIC// 02110-1301 USA.
22// LIC//
23// LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24// LIC//
25// LIC//====================================================================
26#ifndef OOMPH_RECTANGLE_WITH_HOLE_DOMAIN_HEADER
27#define OOMPH_RECTANGLE_WITH_HOLE_DOMAIN_HEADER
28
29
30// Generic includes
31#include "../generic/quadtree.h"
32#include "../generic/geom_objects.h"
33#include "../generic/macro_element.h"
34#include "../generic/domain.h"
35
36
37namespace oomph
38{
39 //===========================================================
40 /// Rectangular domain with circular whole
41 //===========================================================
42 class RectangleWithHoleDomain : public Domain
43 {
44 public:
45 /// Constructor. Pass pointer to geometric object that
46 /// represents the cylinder, the length of the (square) domain.
47 /// The GeomObject must be parametrised such that
48 /// \f$\zeta \in [0,2\pi]\f$ sweeps around the circumference
49 /// in anticlockwise direction.
50 RectangleWithHoleDomain(GeomObject* cylinder_pt, const double& length)
51 : Cylinder_pt(cylinder_pt)
52 {
53 // Vertices of rectangle
54 Lower_left.resize(2);
55 Lower_left[0] = -0.5 * length;
56 Lower_left[1] = -0.5 * length;
57
58 Upper_left.resize(2);
59 Upper_left[0] = -0.5 * length;
60 Upper_left[1] = 0.5 * length;
61
62 Lower_right.resize(2);
63 Lower_right[0] = 0.5 * length;
64 Lower_right[1] = -0.5 * length;
65
66 Upper_right.resize(2);
67 Upper_right[0] = 0.5 * length;
68 Upper_right[1] = 0.5 * length;
69
70
71 // Coordinates of points where the "radial" lines from central
72 // cylinder meet the upper and lower boundaries
73 Lower_mid_left.resize(2);
74 Lower_mid_left[0] = -0.5 * length;
75 Lower_mid_left[1] = -0.5 * length;
76
77 Upper_mid_left.resize(2);
78 Upper_mid_left[0] = -0.5 * length;
79 Upper_mid_left[1] = 0.5 * length;
80
81 Lower_mid_right.resize(2);
82 Lower_mid_right[0] = 0.5 * length;
83 Lower_mid_right[1] = -0.5 * length;
84
85 Upper_mid_right.resize(2);
86 Upper_mid_right[0] = 0.5 * length;
87 Upper_mid_right[1] = 0.5 * length;
88
89
90 // There are four macro elements
91 Macro_element_pt.resize(4);
92
93 // Build the 2D macro elements
94 for (unsigned i = 0; i < 4; i++)
95 {
97 }
98 }
99
100
101 /// Destructor: Empty; cleanup done in base class
103
104 /// Helper function to interpolate linearly between the
105 /// "right" and "left" points; \f$ s \in [-1,1] \f$
108 const double& s,
110 {
111 for (unsigned i = 0; i < 2; i++)
112 {
113 f[i] = left[i] + (right[i] - left[i]) * 0.5 * (s + 1.0);
114 }
115 }
116
117
118 /// Parametrisation of macro element boundaries: f(s) is the position
119 /// vector to macro-element m's boundary in the specified direction
120 /// [N/S/E/W] at the specfied discrete time level (time=0: present; time>0:
121 /// previous)
122 void macro_element_boundary(const unsigned& time,
123 const unsigned& m,
124 const unsigned& direction,
125 const Vector<double>& s,
127 {
128#ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES
129 // Warn about time argument being moved to the front
131 "Order of function arguments has changed between versions 0.8 and 0.85",
132 "RectangleWithHoleDomain::macro_element_boundary(...)",
134#endif
135
136 // Lagrangian coordinate along surface of cylinder
138
139 // Point on circle
141
142 using namespace QuadTreeNames;
143
144 // Switch on the macro element
145 switch (m)
146 {
147 // Macro element 0, is is immediately left of the cylinder
148 case 0:
149
150 switch (direction)
151 {
152 case N:
153 xi[0] = 3.0 * atan(1.0);
154 Cylinder_pt->position(time, xi, point_on_circle);
156 break;
157
158 case S:
159 xi[0] = -3.0 * atan(1.0);
160 Cylinder_pt->position(time, xi, point_on_circle);
162 break;
163
164 case W:
166 break;
167
168 case E:
169 xi[0] = 5.0 * atan(1.0) - 2.0 * atan(1.0) * 0.5 * (1.0 + s[0]);
170 Cylinder_pt->position(time, xi, f);
171 break;
172
173 default:
174
175 std::ostringstream error_stream;
176 error_stream << "Direction is incorrect: " << direction
177 << std::endl;
178 throw OomphLibError(error_stream.str(),
181 }
182
183 break;
184
185 // Macro element 1, is immediately above the cylinder
186 case 1:
187
188 switch (direction)
189 {
190 case N:
192 break;
193
194 case S:
195 xi[0] = 3.0 * atan(1.0) - 2.0 * atan(1.0) * 0.5 * (1.0 + s[0]);
196 Cylinder_pt->position(time, xi, f);
197 break;
198
199 case W:
200 xi[0] = 3.0 * atan(1.0);
201 Cylinder_pt->position(time, xi, point_on_circle);
203 break;
204
205 case E:
206 xi[0] = 1.0 * atan(1.0);
207 Cylinder_pt->position(time, xi, point_on_circle);
209 break;
210
211 default:
212
213 std::ostringstream error_stream;
214 error_stream << "Direction is incorrect: " << direction
215 << std::endl;
216 throw OomphLibError(error_stream.str(),
219 }
220
221 break;
222
223 // Macro element 2, is immediately right of the cylinder
224 case 2:
225
226 switch (direction)
227 {
228 case N:
229 xi[0] = 1.0 * atan(1.0);
230 Cylinder_pt->position(time, xi, point_on_circle);
232 break;
233
234 case S:
235 xi[0] = -1.0 * atan(1.0);
236 Cylinder_pt->position(time, xi, point_on_circle);
238 break;
239
240 case W:
241 xi[0] = -atan(1.0) + 2.0 * atan(1.0) * 0.5 * (1.0 + s[0]);
242 Cylinder_pt->position(time, xi, f);
243 break;
244
245 case E:
247 break;
248
249 default:
250
251 std::ostringstream error_stream;
252 error_stream << "Direction is incorrect: " << direction
253 << std::endl;
254 throw OomphLibError(error_stream.str(),
257 }
258
259 break;
260
261 // Macro element 3, is immediately below cylinder
262 case 3:
263
264 switch (direction)
265 {
266 case N:
267 xi[0] = -3.0 * atan(1.0) + 2.0 * atan(1.0) * 0.5 * (1.0 + s[0]);
268 Cylinder_pt->position(time, xi, f);
269 break;
270
271 case S:
273 break;
274
275 case W:
276 xi[0] = -3.0 * atan(1.0);
277 Cylinder_pt->position(time, xi, point_on_circle);
279 break;
280
281 case E:
282 xi[0] = -1.0 * atan(1.0);
283 Cylinder_pt->position(time, xi, point_on_circle);
285 break;
286
287 default:
288
289 std::ostringstream error_stream;
290 error_stream << "Direction is incorrect: " << direction
291 << std::endl;
292 throw OomphLibError(error_stream.str(),
295 }
296
297 break;
298
299 default:
300
301 std::ostringstream error_stream;
302 error_stream << "Wrong macro element number" << m << std::endl;
303 throw OomphLibError(error_stream.str(),
306 }
307 }
308
309
310 private:
311 /// Lower left corner of rectangle
313
314 /// Lower right corner of rectangle
316
317 /// Where the "radial" line from circle meets lower boundary on left
319
320 /// Where the "radial" line from circle meets lower boundary on right
322
323 /// Upper left corner of rectangle
325
326 /// Upper right corner of rectangle
328
329 /// Where the "radial" line from circle meets upper boundary on left
331
332 /// Where the "radial" line from circle meets upper boundary on right
334
335 /// Pointer to geometric object that represents the central cylinder
337 };
338
339
340} // namespace oomph
341#endif
Rectangular domain with circular whole.
Vector< double > Upper_mid_left
Where the "radial" line from circle meets upper boundary on left.
Vector< double > Upper_left
Upper left corner of rectangle.
Vector< double > Upper_right
Upper right corner of rectangle.
RectangleWithHoleDomain(GeomObject *cylinder_pt, const double &length)
Constructor. Pass pointer to geometric object that represents the cylinder, the length of the (square...
GeomObject * Cylinder_pt
Pointer to geometric object that represents the central cylinder.
void macro_element_boundary(const unsigned &time, const unsigned &m, const unsigned &direction, const Vector< double > &s, Vector< double > &f)
Parametrisation of macro element boundaries: f(s) is the position vector to macro-element m's boundar...
Vector< double > Lower_left
Lower left corner of rectangle.
void linear_interpolate(Vector< double > left, Vector< double > right, const double &s, Vector< double > &f)
Helper function to interpolate linearly between the "right" and "left" points; .
Vector< double > Lower_mid_right
Where the "radial" line from circle meets lower boundary on right.
Vector< double > Upper_mid_right
Where the "radial" line from circle meets upper boundary on right.
Vector< double > Lower_mid_left
Where the "radial" line from circle meets lower boundary on left.
Vector< double > Lower_right
Lower right corner of rectangle.
~RectangleWithHoleDomain()
Destructor: Empty; cleanup done in base class.
Simple rectangular 2D Quad mesh class. Nx : number of elements in the x direction.
////////////////////////////////////////////////////////////////////// //////////////////////////////...