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-2025 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// Generic includes
30#include "generic/quadtree.h"
33#include "generic/domain.h"
34
35namespace oomph
36{
37 //===========================================================
38 /// Rectangular domain with circular whole
39 //===========================================================
41 {
42 public:
43 /// Constructor. Pass pointer to geometric object that
44 /// represents the cylinder, the length of the (square) domain.
45 /// The GeomObject must be parametrised such that
46 /// \f$\zeta \in [0,2\pi]\f$ sweeps around the circumference
47 /// in anticlockwise direction.
48 RectangleWithHoleDomain(GeomObject* cylinder_pt, const double& length)
49 : Cylinder_pt(cylinder_pt)
50 {
51 // Vertices of rectangle
52 Lower_left.resize(2);
53 Lower_left[0] = -0.5 * length;
54 Lower_left[1] = -0.5 * length;
55
56 Upper_left.resize(2);
57 Upper_left[0] = -0.5 * length;
58 Upper_left[1] = 0.5 * length;
59
60 Lower_right.resize(2);
61 Lower_right[0] = 0.5 * length;
62 Lower_right[1] = -0.5 * length;
63
64 Upper_right.resize(2);
65 Upper_right[0] = 0.5 * length;
66 Upper_right[1] = 0.5 * length;
67
68 // Coordinates of points where the "radial" lines from central
69 // cylinder meet the upper and lower boundaries
70 Lower_mid_left.resize(2);
71 Lower_mid_left[0] = -0.5 * length;
72 Lower_mid_left[1] = -0.5 * length;
73
74 Upper_mid_left.resize(2);
75 Upper_mid_left[0] = -0.5 * length;
76 Upper_mid_left[1] = 0.5 * length;
77
78 Lower_mid_right.resize(2);
79 Lower_mid_right[0] = 0.5 * length;
80 Lower_mid_right[1] = -0.5 * length;
81
82 Upper_mid_right.resize(2);
83 Upper_mid_right[0] = 0.5 * length;
84 Upper_mid_right[1] = 0.5 * length;
85
86 // There are four macro elements
87 Macro_element_pt.resize(4);
88
89 // Build the 2D macro elements
90 for (unsigned i = 0; i < 4; i++)
91 {
93 }
94 }
95
96 /// Destructor: Empty; cleanup done in base class
98
99 /// Helper function to interpolate linearly between the
100 /// "right" and "left" points; \f$ s \in [-1,1] \f$
103 const double& s,
105 {
106 for (unsigned i = 0; i < 2; i++)
107 {
108 f[i] = left[i] + (right[i] - left[i]) * 0.5 * (s + 1.0);
109 }
110 }
111
112
113 /// Parametrisation of macro element boundaries: f(s) is the position
114 /// vector to macro-element m's boundary in the specified direction
115 /// [N/S/E/W] at the specfied discrete time level (time=0: present; time>0:
116 /// previous)
117 void macro_element_boundary(const unsigned& time,
118 const unsigned& m,
119 const unsigned& direction,
120 const Vector<double>& s,
122 {
123#ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES
124 // Warn about time argument being moved to the front
126 "Order of function arguments has changed between versions 0.8 and 0.85",
127 "RectangleWithHoleDomain::macro_element_boundary(...)",
129#endif
130
131 // Lagrangian coordinate along surface of cylinder
132 Vector<double> xi(1);
133
134 // Point on circle
136
137 using namespace QuadTreeNames;
138
139 // Switch on the macro element
140 switch (m)
141 {
142 // Macro element 0, is is immediately left of the cylinder
143 case 0:
144
145 switch (direction)
146 {
147 case N:
148 xi[0] = 3.0 * atan(1.0);
151 break;
152
153 case S:
154 xi[0] = -3.0 * atan(1.0);
157 break;
158
159 case W:
161 break;
162
163 case E:
164 xi[0] = 5.0 * atan(1.0) - 2.0 * atan(1.0) * 0.5 * (1.0 + s[0]);
165 Cylinder_pt->position(time, xi, f);
166 break;
167
168 default:
169
170 std::ostringstream error_stream;
171 error_stream << "Direction is incorrect: " << direction
172 << std::endl;
173 throw OomphLibError(error_stream.str(),
176 }
177
178 break;
179
180 // Macro element 1, is immediately above the cylinder
181 case 1:
182
183 switch (direction)
184 {
185 case N:
187 break;
188
189 case S:
190 xi[0] = 3.0 * atan(1.0) - 2.0 * atan(1.0) * 0.5 * (1.0 + s[0]);
191 Cylinder_pt->position(time, xi, f);
192 break;
193
194 case W:
195 xi[0] = 3.0 * atan(1.0);
198 break;
199
200 case E:
201 xi[0] = 1.0 * atan(1.0);
204 break;
205
206 default:
207
208 std::ostringstream error_stream;
209 error_stream << "Direction is incorrect: " << direction
210 << std::endl;
211 throw OomphLibError(error_stream.str(),
214 }
215
216 break;
217
218 // Macro element 2, is immediately right of the cylinder
219 case 2:
220
221 switch (direction)
222 {
223 case N:
224 xi[0] = 1.0 * atan(1.0);
227 break;
228
229 case S:
230 xi[0] = -1.0 * atan(1.0);
233 break;
234
235 case W:
236 xi[0] = -atan(1.0) + 2.0 * atan(1.0) * 0.5 * (1.0 + s[0]);
237 Cylinder_pt->position(time, xi, f);
238 break;
239
240 case E:
242 break;
243
244 default:
245
246 std::ostringstream error_stream;
247 error_stream << "Direction is incorrect: " << direction
248 << std::endl;
249 throw OomphLibError(error_stream.str(),
252 }
253
254 break;
255
256 // Macro element 3, is immediately below cylinder
257 case 3:
258
259 switch (direction)
260 {
261 case N:
262 xi[0] = -3.0 * atan(1.0) + 2.0 * atan(1.0) * 0.5 * (1.0 + s[0]);
263 Cylinder_pt->position(time, xi, f);
264 break;
265
266 case S:
268 break;
269
270 case W:
271 xi[0] = -3.0 * atan(1.0);
274 break;
275
276 case E:
277 xi[0] = -1.0 * atan(1.0);
280 break;
281
282 default:
283
284 std::ostringstream error_stream;
285 error_stream << "Direction is incorrect: " << direction
286 << std::endl;
287 throw OomphLibError(error_stream.str(),
290 }
291
292 break;
293
294 default:
295
296 std::ostringstream error_stream;
297 error_stream << "Wrong macro element number" << m << std::endl;
298 throw OomphLibError(error_stream.str(),
301 }
302 }
303
304 private:
305 /// Lower left corner of rectangle
307
308 /// Lower right corner of rectangle
310
311 /// Where the "radial" line from circle meets lower boundary on left
313
314 /// Where the "radial" line from circle meets lower boundary on right
316
317 /// Upper left corner of rectangle
319
320 /// Upper right corner of rectangle
322
323 /// Where the "radial" line from circle meets upper boundary on left
325
326 /// Where the "radial" line from circle meets upper boundary on right
328
329 /// Pointer to geometric object that represents the central cylinder
331 };
332
333} // namespace oomph
334#endif
static char t char * s
Definition cfortran.h:568
cstr elem_len * i
Definition cfortran.h:603
Base class for Domains with curvilinear and/or time-dependent boundaries. Domain boundaries are typic...
Definition domain.h:67
Vector< MacroElement * > Macro_element_pt
Vector of pointers to macro elements.
Definition domain.h:301
A geometric object is an object that provides a parametrised description of its shape via the functio...
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
An OomphLibError object which should be thrown when an run-time error is encountered....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
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.
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).