Toggle navigation
Documentation
Big picture
The finite element method
The data structure
Not-so-quick guide
Optimisation
Order of action functions
Example codes and tutorials
List of example codes and tutorials
Meshing
Solvers
MPI parallel processing
Post-processing/visualisation
Other
Change log
Creating documentation
Coding conventions
Index
FAQ
About
People
Contact/Get involved
Publications
Acknowledgements
Copyright
Picture show
Go
src
meshes
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"
31
#include "generic/geom_objects.h"
32
#include "generic/macro_element.h"
33
#include "generic/domain.h"
34
35
namespace
oomph
36
{
37
//===========================================================
38
/// Rectangular domain with circular whole
39
//===========================================================
40
class
RectangleWithHoleDomain
:
public
Domain
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
{
92
Macro_element_pt
[
i
] =
new
QMacroElement<2>
(
this
,
i
);
93
}
94
}
95
96
/// Destructor: Empty; cleanup done in base class
97
~RectangleWithHoleDomain
() {}
98
99
/// Helper function to interpolate linearly between the
100
/// "right" and "left" points; \f$ s \in [-1,1] \f$
101
void
linear_interpolate
(
Vector<double>
left
,
102
Vector<double>
right
,
103
const
double
&
s
,
104
Vector<double>
&
f
)
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
,
121
Vector<double>
&
f
)
122
{
123
#ifdef WARN_ABOUT_SUBTLY_CHANGED_OOMPH_INTERFACES
124
// Warn about time argument being moved to the front
125
OomphLibWarning
(
126
"Order of function arguments has changed between versions 0.8 and 0.85"
,
127
"RectangleWithHoleDomain::macro_element_boundary(...)"
,
128
OOMPH_EXCEPTION_LOCATION
);
129
#endif
130
131
// Lagrangian coordinate along surface of cylinder
132
Vector<double>
xi
(1);
133
134
// Point on circle
135
Vector<double>
point_on_circle
(2);
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);
149
Cylinder_pt
->position(
time
,
xi
,
point_on_circle
);
150
linear_interpolate
(
Upper_mid_left
,
point_on_circle
,
s
[0],
f
);
151
break
;
152
153
case
S
:
154
xi
[0] = -3.0 *
atan
(1.0);
155
Cylinder_pt
->position(
time
,
xi
,
point_on_circle
);
156
linear_interpolate
(
Lower_mid_left
,
point_on_circle
,
s
[0],
f
);
157
break
;
158
159
case
W
:
160
linear_interpolate
(
Lower_mid_left
,
Upper_mid_left
,
s
[0],
f
);
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(),
174
OOMPH_CURRENT_FUNCTION
,
175
OOMPH_EXCEPTION_LOCATION
);
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:
186
linear_interpolate
(
Upper_mid_left
,
Upper_mid_right
,
s
[0],
f
);
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);
196
Cylinder_pt
->position(
time
,
xi
,
point_on_circle
);
197
linear_interpolate
(
point_on_circle
,
Upper_mid_left
,
s
[0],
f
);
198
break
;
199
200
case
E
:
201
xi
[0] = 1.0 *
atan
(1.0);
202
Cylinder_pt
->position(
time
,
xi
,
point_on_circle
);
203
linear_interpolate
(
point_on_circle
,
Upper_mid_right
,
s
[0],
f
);
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(),
212
OOMPH_CURRENT_FUNCTION
,
213
OOMPH_EXCEPTION_LOCATION
);
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);
225
Cylinder_pt
->position(
time
,
xi
,
point_on_circle
);
226
linear_interpolate
(
point_on_circle
,
Upper_mid_right
,
s
[0],
f
);
227
break
;
228
229
case
S
:
230
xi
[0] = -1.0 *
atan
(1.0);
231
Cylinder_pt
->position(
time
,
xi
,
point_on_circle
);
232
linear_interpolate
(
point_on_circle
,
Lower_mid_right
,
s
[0],
f
);
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
:
241
linear_interpolate
(
Lower_mid_right
,
Upper_mid_right
,
s
[0],
f
);
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(),
250
OOMPH_CURRENT_FUNCTION
,
251
OOMPH_EXCEPTION_LOCATION
);
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
:
267
linear_interpolate
(
Lower_mid_left
,
Lower_mid_right
,
s
[0],
f
);
268
break
;
269
270
case
W
:
271
xi
[0] = -3.0 *
atan
(1.0);
272
Cylinder_pt
->position(
time
,
xi
,
point_on_circle
);
273
linear_interpolate
(
Lower_mid_left
,
point_on_circle
,
s
[0],
f
);
274
break
;
275
276
case
E
:
277
xi
[0] = -1.0 *
atan
(1.0);
278
Cylinder_pt
->position(
time
,
xi
,
point_on_circle
);
279
linear_interpolate
(
Lower_mid_right
,
point_on_circle
,
s
[0],
f
);
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(),
288
OOMPH_CURRENT_FUNCTION
,
289
OOMPH_EXCEPTION_LOCATION
);
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(),
299
OOMPH_CURRENT_FUNCTION
,
300
OOMPH_EXCEPTION_LOCATION
);
301
}
302
}
303
304
private
:
305
/// Lower left corner of rectangle
306
Vector<double>
Lower_left
;
307
308
/// Lower right corner of rectangle
309
Vector<double>
Lower_right
;
310
311
/// Where the "radial" line from circle meets lower boundary on left
312
Vector<double>
Lower_mid_left
;
313
314
/// Where the "radial" line from circle meets lower boundary on right
315
Vector<double>
Lower_mid_right
;
316
317
/// Upper left corner of rectangle
318
Vector<double>
Upper_left
;
319
320
/// Upper right corner of rectangle
321
Vector<double>
Upper_right
;
322
323
/// Where the "radial" line from circle meets upper boundary on left
324
Vector<double>
Upper_mid_left
;
325
326
/// Where the "radial" line from circle meets upper boundary on right
327
Vector<double>
Upper_mid_right
;
328
329
/// Pointer to geometric object that represents the central cylinder
330
GeomObject
*
Cylinder_pt
;
331
};
332
333
}
// namespace oomph
334
#endif
oomph::RectangleWithHoleDomain
Rectangular domain with circular whole.
Definition
rectangle_with_hole_domain.h:41
oomph::RectangleWithHoleDomain::Upper_mid_left
Vector< double > Upper_mid_left
Where the "radial" line from circle meets upper boundary on left.
Definition
rectangle_with_hole_domain.h:324
oomph::RectangleWithHoleDomain::Upper_left
Vector< double > Upper_left
Upper left corner of rectangle.
Definition
rectangle_with_hole_domain.h:318
oomph::RectangleWithHoleDomain::Upper_right
Vector< double > Upper_right
Upper right corner of rectangle.
Definition
rectangle_with_hole_domain.h:321
oomph::RectangleWithHoleDomain::RectangleWithHoleDomain
RectangleWithHoleDomain(GeomObject *cylinder_pt, const double &length)
Constructor. Pass pointer to geometric object that represents the cylinder, the length of the (square...
Definition
rectangle_with_hole_domain.h:48
oomph::RectangleWithHoleDomain::Cylinder_pt
GeomObject * Cylinder_pt
Pointer to geometric object that represents the central cylinder.
Definition
rectangle_with_hole_domain.h:330
oomph::RectangleWithHoleDomain::macro_element_boundary
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...
Definition
rectangle_with_hole_domain.h:117
oomph::RectangleWithHoleDomain::Lower_left
Vector< double > Lower_left
Lower left corner of rectangle.
Definition
rectangle_with_hole_domain.h:306
oomph::RectangleWithHoleDomain::linear_interpolate
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; .
Definition
rectangle_with_hole_domain.h:101
oomph::RectangleWithHoleDomain::Lower_mid_right
Vector< double > Lower_mid_right
Where the "radial" line from circle meets lower boundary on right.
Definition
rectangle_with_hole_domain.h:315
oomph::RectangleWithHoleDomain::Upper_mid_right
Vector< double > Upper_mid_right
Where the "radial" line from circle meets upper boundary on right.
Definition
rectangle_with_hole_domain.h:327
oomph::RectangleWithHoleDomain::Lower_mid_left
Vector< double > Lower_mid_left
Where the "radial" line from circle meets lower boundary on left.
Definition
rectangle_with_hole_domain.h:312
oomph::RectangleWithHoleDomain::Lower_right
Vector< double > Lower_right
Lower right corner of rectangle.
Definition
rectangle_with_hole_domain.h:309
oomph::RectangleWithHoleDomain::~RectangleWithHoleDomain
~RectangleWithHoleDomain()
Destructor: Empty; cleanup done in base class.
Definition
rectangle_with_hole_domain.h:97
oomph::RefineableTriangleMesh
Unstructured refineable Triangle Mesh.
Definition
triangle_mesh.h:2225
oomph
Definition
annular_domain.h:35