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
full_circle_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
27
#ifndef OOMPH_FULL_CIRCLE_DOMAIN_HEADER
28
#define OOMPH_FULL_CIRCLE_DOMAIN_HEADER
29
30
// Generic oomph-lib includes
31
#include "
generic/quadtree.h
"
32
#include "
generic/domain.h
"
33
#include "
generic/geom_objects.h
"
34
35
namespace
oomph
36
{
37
//=================================================================
38
/// Topologically circular domain, e.g. a tube cross section.
39
/// The entire domain must be defined by a GeomObject with the
40
/// following convention: zeta[0] is the radial coordinate and
41
/// zeta[1] is the theta coordinate around the cross-sectin.
42
/// The outer boundary must lie at zeta[0] = 1.
43
///
44
/// The domain is
45
/// parametrised by five macro elements (a central box surrounded by
46
/// four curved elements). The labelling of the macro elements is shown
47
/// below.
48
///
49
/// ----------------------------
50
/// |\ /|
51
/// | \ Macro / |
52
/// | 3 Element 3 2 |
53
/// | \ / |
54
/// | \----------------/ |
55
/// | | | |
56
/// | 4 | Macro | |
57
/// | | Element 0 | 2 |
58
/// | | | |
59
/// | ----------------- |
60
/// | / \ |
61
/// | 0 Macro 1 |
62
/// | / Element 1 \ |
63
/// | / \|
64
/// |/-------------------------|
65
///
66
///
67
//=================================================================
68
class
FullCircleDomain
:
public
Domain
69
{
70
public
:
71
/// Constructor: Pass geometric object; the theta locations
72
/// marking the division between
73
/// the elements of the outer ring, labelled from the lower left to the
74
/// upper left in order, theta should be in the range \f$-\pi\f$ to
75
/// \f$\pi\f$; and the corresponding fractions of the
76
/// radius at which the central box is to be placed.
77
FullCircleDomain
(
GeomObject
*
area_geom_object_pt
,
78
const
Vector<double>
&
theta_positions
,
79
const
Vector<double>
&
radius_box
)
80
:
Theta_positions
(
theta_positions
),
81
Radius_box
(
radius_box
),
82
Area_pt
(
area_geom_object_pt
)
83
{
84
// There are five macro elements
85
const
unsigned
n_macro
= 5;
86
Macro_element_pt
.resize(
n_macro
);
87
88
// Create the macro elements
89
for
(
unsigned
i
= 0;
i
<
n_macro
;
i
++)
90
{
91
Macro_element_pt
[
i
] =
new
QMacroElement<2>
(
this
,
i
);
92
}
93
}
94
95
/// Broken copy constructor
96
FullCircleDomain
(
const
FullCircleDomain
&) =
delete
;
97
98
/// Broken assignment operator
99
void
operator=
(
const
FullCircleDomain
&) =
delete
;
100
101
/// Destructor: Empty; cleanup done in base class
102
~FullCircleDomain
() {}
103
104
105
/// Vector representation of the i_macro-th macro element
106
/// boundary i_direct (N/S/W/E) at time level t
107
/// (t=0: present; t>0: previous):
108
/// f(s).
109
void
macro_element_boundary
(
const
unsigned
&
t
,
110
const
unsigned
&
i_macro
,
111
const
unsigned
&
i_direct
,
112
const
Vector<double>
&
s
,
113
Vector<double>
& f);
114
115
private
:
116
/// Storage for the dividing lines on the boundary
117
/// starting from the lower left and proceeding anticlockwise to
118
/// the upper left
119
Vector<double>
Theta_positions
;
120
121
/// Storage for the fraction of the radius at which the central box
122
/// should be located corresponding to the chosen values of theta.
123
Vector<double>
Radius_box
;
124
125
/// Pointer to geometric object that represents the domain
126
GeomObject
*
Area_pt
;
127
128
/// A very little linear interpolation helper.
129
/// Interpolate from the low
130
/// point to the high point using the coordinate s, which is
131
/// assumed to run from -1 to 1.
132
void
lin_interpolate
(
const
Vector<double>
&
low
,
133
const
Vector<double>
&
high
,
134
const
double
&
s
,
135
Vector<double>
& f)
136
{
137
// Loop over all coordinates (we are working in 2D)
138
for
(
unsigned
i
= 0;
i
< 2;
i
++)
139
{
140
f[
i
] =
low
[
i
] + (
high
[
i
] -
low
[
i
]) * 0.5 * (
s
+ 1.0);
141
}
142
}
143
};
144
145
146
/////////////////////////////////////////////////////////////////////////
147
/////////////////////////////////////////////////////////////////////////
148
/////////////////////////////////////////////////////////////////////////
149
150
//=================================================================
151
/// Vector representation of the imacro-th macro element
152
/// boundary idirect (N/S/W/E) at time level t
153
/// (t=0: present; t>0: previous): f(s)
154
//=================================================================
155
void
FullCircleDomain::macro_element_boundary
(
const
unsigned
&
t
,
156
const
unsigned
&
imacro
,
157
const
unsigned
&
idirect
,
158
const
Vector<double>
&
s
,
159
Vector<double>
& f)
160
{
161
using namespace
QuadTreeNames;
162
163
// Get the coordinates of the corners of the box
164
Vector<Vector<double>
>
Box
(4);
165
// Get the corresponding coordinates on the boundary
166
Vector<Vector<double>
>
Wall
(4);
167
168
// Storage for position in the area
169
Vector<double>
zeta
(2);
170
171
// Loop over the angles
172
for
(
unsigned
j
= 0;
j
< 4;
j
++)
173
{
174
// Set up the storage
175
Box
[
j
].resize(2);
176
Wall
[
j
].resize(2);
177
178
// Set the other values of zeta
179
zeta
[0] =
Radius_box
[
j
];
180
zeta
[1] =
Theta_positions
[
j
];
181
// Now get the values
182
Area_pt
->
position
(
t
,
zeta
,
Box
[
j
]);
183
184
// Now get the position on the boundary
185
zeta
[0] = 1.0;
186
Area_pt
->
position
(
t
,
zeta
,
Wall
[
j
]);
187
}
188
189
// Define pi
190
const
double
pi
=
MathematicalConstants::Pi
;
191
192
// Which macro element?
193
// --------------------
194
switch
(
imacro
)
195
{
196
// Macro element 0: Central box
197
case
0:
198
199
// Choose a direction
200
switch
(
idirect
)
201
{
202
case
N:
203
// Linearly interpolate between the two corners of the box
204
lin_interpolate
(
Box
[3],
Box
[2],
s
[0], f);
205
break
;
206
207
case
S:
208
// Linearly interpolate between the two corners of the box
209
lin_interpolate
(
Box
[0],
Box
[1],
s
[0], f);
210
211
case
W:
212
// Linearly interpolate between the two corners of the box
213
lin_interpolate
(
Box
[0],
Box
[3],
s
[0], f);
214
break
;
215
216
case
E:
217
// Linearly interpolate between the two corners of the box
218
lin_interpolate
(
Box
[1],
Box
[2],
s
[0], f);
219
break
;
220
221
default
:
222
std::ostringstream
error_stream
;
223
error_stream
<<
"idirect is "
<<
idirect
<<
" not one of N, S, E, W"
224
<< std::endl;
225
226
throw
OomphLibError
(
error_stream
.str(),
227
OOMPH_CURRENT_FUNCTION
,
228
OOMPH_EXCEPTION_LOCATION
);
229
break
;
230
}
231
232
break
;
233
234
// Macro element 1: Bottom
235
case
1:
236
237
// Choose a direction
238
switch
(
idirect
)
239
{
240
case
N:
241
// Linearly interpolate between the two corners of the box
242
lin_interpolate
(
Box
[0],
Box
[1],
s
[0], f);
243
break
;
244
245
case
S:
246
// Get the position on the wall by linearly interpolating in theta
247
zeta
[0] = 1.0;
248
zeta
[1] =
249
Theta_positions
[0] +
250
(
Theta_positions
[1] -
Theta_positions
[0]) * 0.5 * (
s
[0] + 1.0);
251
252
Area_pt
->
position
(
t
,
zeta
, f);
253
break
;
254
255
case
W:
256
// Now linearly interpolate between the wall and the box
257
lin_interpolate
(
Wall
[0],
Box
[0],
s
[0], f);
258
break
;
259
260
case
E:
261
// Linearly interpolate between the wall and the box
262
lin_interpolate
(
Wall
[1],
Box
[1],
s
[0], f);
263
break
;
264
265
default
:
266
267
std::ostringstream
error_stream
;
268
error_stream
<<
"idirect is "
<<
idirect
<<
" not one of N, S, E, W"
269
<< std::endl;
270
271
throw
OomphLibError
(
error_stream
.str(),
272
OOMPH_CURRENT_FUNCTION
,
273
OOMPH_EXCEPTION_LOCATION
);
274
break
;
275
}
276
277
break
;
278
279
// Macro element 2:Right
280
case
2:
281
282
// Which direction?
283
switch
(
idirect
)
284
{
285
case
N:
286
// Linearly interpolate between the box and the wall
287
lin_interpolate
(
Box
[2],
Wall
[2],
s
[0], f);
288
break
;
289
290
case
S:
291
// Linearly interpolate between the box and the wall
292
lin_interpolate
(
Box
[1],
Wall
[1],
s
[0], f);
293
break
;
294
295
case
W:
296
// Linearly interpolate between the two corners of the box
297
lin_interpolate
(
Box
[1],
Box
[2],
s
[0], f);
298
break
;
299
300
case
E:
301
// Get the position on the wall by linearly interpolating in theta
302
zeta
[0] = 1.0;
303
zeta
[1] =
304
Theta_positions
[1] +
305
(
Theta_positions
[2] -
Theta_positions
[1]) * 0.5 * (
s
[0] + 1.0);
306
307
Area_pt
->
position
(
t
,
zeta
, f);
308
break
;
309
310
default
:
311
std::ostringstream
error_stream
;
312
error_stream
<<
"idirect is "
<<
idirect
<<
" not one of N, S, W, E"
313
<< std::endl;
314
315
throw
OomphLibError
(
error_stream
.str(),
316
OOMPH_CURRENT_FUNCTION
,
317
OOMPH_EXCEPTION_LOCATION
);
318
}
319
320
break
;
321
322
// Macro element 3: Top
323
case
3:
324
325
// Which direction?
326
switch
(
idirect
)
327
{
328
case
N:
329
// Get the position on the wall by linearly interpolating in theta
330
zeta
[0] = 1.0;
331
zeta
[1] =
332
Theta_positions
[3] +
333
(
Theta_positions
[2] -
Theta_positions
[3]) * 0.5 * (
s
[0] + 1.0);
334
335
Area_pt
->
position
(
t
,
zeta
, f);
336
break
;
337
338
case
S:
339
// Linearly interpolate between the two corners of the box
340
lin_interpolate
(
Box
[3],
Box
[1],
s
[0], f);
341
break
;
342
343
case
W:
344
// Linearly interpolate between the box and the wall
345
lin_interpolate
(
Box
[3],
Wall
[3],
s
[0], f);
346
break
;
347
348
case
E:
349
// Linearly interpolate between the box and the wall
350
lin_interpolate
(
Box
[2],
Wall
[2],
s
[0], f);
351
break
;
352
353
default
:
354
std::ostringstream
error_stream
;
355
error_stream
<<
"idirect is "
<<
idirect
<<
" not one of N, S, E, W"
356
<< std::endl;
357
358
throw
OomphLibError
(
error_stream
.str(),
359
OOMPH_CURRENT_FUNCTION
,
360
OOMPH_EXCEPTION_LOCATION
);
361
}
362
363
break
;
364
365
// Macro element 4: Left
366
case
4:
367
368
// Which direction?
369
switch
(
idirect
)
370
{
371
case
N:
372
// Linearly interpolate between the wall and the box
373
lin_interpolate
(
Wall
[3],
Box
[3],
s
[0], f);
374
break
;
375
376
case
S:
377
// Linearly interpolate between the wall and the box
378
lin_interpolate
(
Wall
[0],
Box
[0],
s
[0], f);
379
break
;
380
381
case
W:
382
// Entirely on the wall, Need to be careful
383
// because this is the point at which theta passes through the
384
//"branch cut"
385
zeta
[0] = 1.0;
386
zeta
[1] =
Theta_positions
[0] + 2.0 *
pi
+
387
(
Theta_positions
[3] - (
Theta_positions
[0] + 2.0 *
pi
)) *
388
0.5 * (
s
[0] + 1.0);
389
390
Area_pt
->
position
(
t
,
zeta
, f);
391
break
;
392
393
case
E:
394
// Linearly interpolate between the two corners of the box
395
lin_interpolate
(
Box
[0],
Box
[3],
s
[0], f);
396
break
;
397
398
default
:
399
std::ostringstream
error_stream
;
400
error_stream
<<
"idirect is "
<<
idirect
<<
" not one of N, S, W, E"
401
<< std::endl;
402
403
throw
OomphLibError
(
error_stream
.str(),
404
OOMPH_CURRENT_FUNCTION
,
405
OOMPH_EXCEPTION_LOCATION
);
406
}
407
break
;
408
409
default
:
410
// Error
411
std::ostringstream
error_stream
;
412
error_stream
<<
"Wrong imacro "
<<
imacro
<< std::endl;
413
throw
OomphLibError
(
414
error_stream
.str(),
OOMPH_CURRENT_FUNCTION
,
OOMPH_EXCEPTION_LOCATION
);
415
}
416
}
417
418
}
// namespace oomph
419
420
#endif
s
static char t char * s
Definition
cfortran.h:568
i
cstr elem_len * i
Definition
cfortran.h:603
t
char t
Definition
cfortran.h:568
oomph::Domain
Base class for Domains with curvilinear and/or time-dependent boundaries. Domain boundaries are typic...
Definition
domain.h:67
oomph::Domain::Macro_element_pt
Vector< MacroElement * > Macro_element_pt
Vector of pointers to macro elements.
Definition
domain.h:301
oomph::FullCircleDomain
Topologically circular domain, e.g. a tube cross section. The entire domain must be defined by a Geom...
Definition
full_circle_domain.h:69
oomph::FullCircleDomain::FullCircleDomain
FullCircleDomain(const FullCircleDomain &)=delete
Broken copy constructor.
oomph::FullCircleDomain::FullCircleDomain
FullCircleDomain(GeomObject *area_geom_object_pt, const Vector< double > &theta_positions, const Vector< double > &radius_box)
Constructor: Pass geometric object; the theta locations marking the division between the elements of ...
Definition
full_circle_domain.h:77
oomph::FullCircleDomain::Area_pt
GeomObject * Area_pt
Pointer to geometric object that represents the domain.
Definition
full_circle_domain.h:126
oomph::FullCircleDomain::lin_interpolate
void lin_interpolate(const Vector< double > &low, const Vector< double > &high, const double &s, Vector< double > &f)
A very little linear interpolation helper. Interpolate from the low point to the high point using the...
Definition
full_circle_domain.h:132
oomph::FullCircleDomain::macro_element_boundary
void macro_element_boundary(const unsigned &t, const unsigned &i_macro, const unsigned &i_direct, const Vector< double > &s, Vector< double > &f)
Vector representation of the i_macro-th macro element boundary i_direct (N/S/W/E) at time level t (t=...
Definition
full_circle_domain.h:155
oomph::FullCircleDomain::Radius_box
Vector< double > Radius_box
Storage for the fraction of the radius at which the central box should be located corresponding to th...
Definition
full_circle_domain.h:123
oomph::FullCircleDomain::operator=
void operator=(const FullCircleDomain &)=delete
Broken assignment operator.
oomph::FullCircleDomain::Theta_positions
Vector< double > Theta_positions
Storage for the dividing lines on the boundary starting from the lower left and proceeding anticlockw...
Definition
full_circle_domain.h:119
oomph::FullCircleDomain::~FullCircleDomain
~FullCircleDomain()
Destructor: Empty; cleanup done in base class.
Definition
full_circle_domain.h:102
oomph::GeomObject
A geometric object is an object that provides a parametrised description of its shape via the functio...
Definition
geom_objects.h:101
oomph::GeomObject::position
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
oomph::OomphLibError
An OomphLibError object which should be thrown when an run-time error is encountered....
Definition
oomph_definitions.h:229
oomph::TAdvectionDiffusionReactionElement
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
Definition
Tadvection_diffusion_reaction_elements.h:66
domain.h
geom_objects.h
oomph::MathematicalConstants::Pi
const double Pi
50 digits from maple
Definition
oomph_utilities.h:167
oomph
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition
advection_diffusion_elements.cc:30
quadtree.h