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_mesh.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_MESH_HEADER
27
#define OOMPH_RECTANGLE_WITH_HOLE_MESH_HEADER
28
29
// Config header
30
#ifdef HAVE_CONFIG_H
31
#include <oomph-lib-config.h>
32
#endif
33
34
// OOMPH-LIB headers
35
#include "generic/mesh.h"
36
#include "generic/quadtree.h"
37
#include "generic/quad_mesh.h"
38
#include "generic/refineable_quad_mesh.h"
39
#include "
rectangle_with_hole_domain.h
"
40
41
namespace
oomph
42
{
43
//=============================================================
44
/// Domain-based mesh for rectangular mesh with circular hole
45
//=============================================================
46
template
<
class
ELEMENT>
47
class
RectangleWithHoleMesh
:
public
virtual
Mesh
48
{
49
public
:
50
/// Constructor: Pass pointer to geometric object that
51
/// represents the cylinder, the length and height of the domain.
52
/// The GeomObject must be parametrised such that
53
/// \f$\zeta \in [0,2\pi]\f$ sweeps around the circumference
54
/// in anticlockwise direction. Timestepper defaults to Steady
55
/// default timestepper.
56
RectangleWithHoleMesh
(
57
GeomObject
* cylinder_pt,
58
const
double
&
length
,
59
TimeStepper
*
time_stepper_pt
= &Mesh::Default_TimeStepper)
60
{
61
// Create the domain
62
Domain_pt
=
new
RectangleWithHoleDomain
(cylinder_pt,
length
);
63
64
// Initialise the node counter
65
unsigned
long
node_count
= 0;
66
67
// Vectors used to get data from domains
68
Vector<double>
s
(2),
r
(2);
69
70
// Setup temporary storage for the Node
71
Vector<Node*>
Tmp_node_pt
;
72
73
// Now blindly loop over the macro elements and associate and finite
74
// element with each
75
unsigned
nmacro_element
=
Domain_pt
->nmacro_element();
76
for
(
unsigned
e
= 0;
e
<
nmacro_element
;
e
++)
77
{
78
// Create the FiniteElement and add to the Element_pt Vector
79
Element_pt
.push_back(
new
ELEMENT
);
80
81
// Read out the number of linear points in the element
82
unsigned
np
=
dynamic_cast<
ELEMENT
*
>
(
finite_element_pt
(
e
))->
nnode_1d
();
83
84
// Loop over nodes in the column
85
for
(
unsigned
l1
= 0;
l1
<
np
;
l1
++)
86
{
87
// Loop over the nodes in the row
88
for
(
unsigned
l2
= 0;
l2
<
np
;
l2
++)
89
{
90
// Allocate the memory for the node
91
Tmp_node_pt
.push_back(
finite_element_pt
(
e
)->construct_node(
92
l1
*
np
+
l2
,
time_stepper_pt
));
93
94
// Read out the position of the node from the macro element
95
s
[0] = -1.0 + 2.0 * (
double
)
l2
/ (
double
)(
np
- 1);
96
s
[1] = -1.0 + 2.0 * (
double
)
l1
/ (
double
)(
np
- 1);
97
Domain_pt
->macro_element_pt(
e
)->macro_map(
s
,
r
);
98
99
// Set the position of the node
100
Tmp_node_pt
[
node_count
]->x(0) =
r
[0];
101
Tmp_node_pt
[
node_count
]->x(1) =
r
[1];
102
103
// Increment the node number
104
node_count
++;
105
}
106
}
107
}
// End of loop over macro elements
108
109
// Now the elements have been created, but there will be nodes in
110
// common, need to loop over the common edges and sort it, by reassigning
111
// pointers and the deleting excess nodes
112
113
// Read out the number of linear points in the element
114
unsigned
np
=
dynamic_cast<
ELEMENT
*
>
(
finite_element_pt
(0))->
nnode_1d
();
115
116
// Edge between Elements 0 and 1
117
for
(
unsigned
n
= 0;
n
<
np
;
n
++)
118
{
119
// Set the nodes in element 1 to be the same as in element 0
120
finite_element_pt
(1)->node_pt(
n
*
np
) =
121
finite_element_pt
(0)->node_pt((
np
- 1) *
np
+
np
- 1 -
n
);
122
123
// Remove the nodes in element 1 from the temporary node list
124
delete
Tmp_node_pt
[
np
*
np
+
n
*
np
];
125
Tmp_node_pt
[
np
*
np
+
n
*
np
] = 0;
126
}
127
128
// Edge between Elements 0 and 3
129
for
(
unsigned
n
= 0;
n
<
np
;
n
++)
130
{
131
// Set the nodes in element 3 to be the same as in element 0
132
finite_element_pt
(3)->node_pt(
n
*
np
) =
133
finite_element_pt
(0)->node_pt(
n
);
134
135
// Remove the nodes in element 3 from the temporary node list
136
delete
Tmp_node_pt
[3 *
np
*
np
+
n
*
np
];
137
Tmp_node_pt
[3 *
np
*
np
+
n
*
np
] = 0;
138
}
139
140
// Edge between Element 1 and 2
141
for
(
unsigned
n
= 0;
n
<
np
;
n
++)
142
{
143
// Set the nodes in element 2 to be the same as in element 1
144
finite_element_pt
(2)->node_pt(
np
* (
np
- 1) +
n
) =
145
finite_element_pt
(1)->node_pt(
np
*
n
+
np
- 1);
146
147
// Remove the nodes in element 2 from the temporary node list
148
delete
Tmp_node_pt
[2 *
np
*
np
+
np
* (
np
- 1) +
n
];
149
Tmp_node_pt
[2 *
np
*
np
+
np
* (
np
- 1) +
n
] = 0;
150
}
151
152
// Edge between Element 3 and 2
153
for
(
unsigned
n
= 0;
n
<
np
;
n
++)
154
{
155
// Set the nodes in element 2 to be the same as in element 3
156
finite_element_pt
(2)->node_pt(
n
) =
157
finite_element_pt
(3)->node_pt(
np
* (
np
-
n
- 1) +
np
- 1);
158
159
// Remove the nodes in element 2 from the temporary node list
160
delete
Tmp_node_pt
[2 *
np
*
np
+
n
];
161
Tmp_node_pt
[2 *
np
*
np
+
n
] = 0;
162
}
163
164
// Now set the actual true nodes
165
for
(
unsigned
long
n
= 0;
n
<
node_count
;
n
++)
166
{
167
if
(
Tmp_node_pt
[
n
] != 0)
168
{
169
Node_pt
.push_back(
Tmp_node_pt
[
n
]);
170
}
171
}
172
173
// Finally set the nodes on the boundaries
174
set_nboundary
(5);
175
176
for
(
unsigned
n
= 0;
n
<
np
;
n
++)
177
{
178
// Left hand side
179
Node
*
nod_pt
=
finite_element_pt
(0)->node_pt(
n
*
np
);
180
convert_to_boundary_node
(
nod_pt
);
181
add_boundary_node
(3,
nod_pt
);
182
183
// Right hand side
184
nod_pt
=
finite_element_pt
(2)->node_pt(
n
*
np
+
np
- 1);
185
convert_to_boundary_node
(
nod_pt
);
186
add_boundary_node
(1,
nod_pt
);
187
188
// First part of lower boundary
189
nod_pt
=
finite_element_pt
(3)->node_pt(
n
);
190
convert_to_boundary_node
(
nod_pt
);
191
add_boundary_node
(0,
nod_pt
);
192
193
// First part of upper boundary
194
nod_pt
=
finite_element_pt
(1)->node_pt(
np
* (
np
- 1) +
n
);
195
convert_to_boundary_node
(
nod_pt
);
196
add_boundary_node
(2,
nod_pt
);
197
198
// First part of hole boundary
199
nod_pt
=
finite_element_pt
(3)->node_pt(
np
* (
np
- 1) +
n
);
200
convert_to_boundary_node
(
nod_pt
);
201
add_boundary_node
(4,
nod_pt
);
202
}
203
204
for
(
unsigned
n
= 1;
n
<
np
;
n
++)
205
{
206
// Next part of hole
207
Node
*
nod_pt
=
finite_element_pt
(2)->node_pt(
n
*
np
);
208
convert_to_boundary_node
(
nod_pt
);
209
add_boundary_node
(4,
nod_pt
);
210
}
211
212
for
(
unsigned
n
= 1;
n
<
np
;
n
++)
213
{
214
// Next part of hole
215
Node
*
nod_pt
=
finite_element_pt
(1)->node_pt(
np
-
n
- 1);
216
convert_to_boundary_node
(
nod_pt
);
217
add_boundary_node
(4,
nod_pt
);
218
}
219
220
for
(
unsigned
n
= 1;
n
<
np
- 1;
n
++)
221
{
222
// Final part of hole
223
Node
*
nod_pt
=
224
finite_element_pt
(0)->node_pt(
np
* (
np
-
n
- 1) +
np
- 1);
225
convert_to_boundary_node
(
nod_pt
);
226
add_boundary_node
(4,
nod_pt
);
227
}
228
}
229
230
/// Access function to the domain
231
RectangleWithHoleDomain
*
domain_pt
()
232
{
233
return
Domain_pt
;
234
}
235
236
protected
:
237
/// Pointer to the domain
238
RectangleWithHoleDomain
*
Domain_pt
;
239
};
240
241
242
//////////////////////////////////////////////////////////////////////////
243
//////////////////////////////////////////////////////////////////////////
244
//////////////////////////////////////////////////////////////////////////
245
246
//===================================================================
247
/// Refineable version of RectangleWithHoleMesh. For some reason
248
/// this needs on uniform refinement to work...
249
//===================================================================
250
template
<
class
ELEMENT>
251
class
RefineableRectangleWithHoleMesh
:
public
RectangleWithHoleMesh
<ELEMENT>,
252
public
RefineableQuadMesh<ELEMENT>
253
{
254
public
:
255
/// Constructor. Pass pointer to geometric object that
256
/// represents the cylinder, the length and height of the domain.
257
/// The GeomObject must be parametrised such that
258
/// \f$\zeta \in [0,2\pi]\f$ sweeps around the circumference
259
/// in anticlockwise direction. Timestepper defaults to Steady
260
/// default timestepper.
261
RefineableRectangleWithHoleMesh
(
262
GeomObject
* cylinder_pt,
263
const
double
&
length
,
264
TimeStepper
*
time_stepper_pt
= &Mesh::Default_TimeStepper)
265
:
RectangleWithHoleMesh
<
ELEMENT
>(cylinder_pt,
length
,
time_stepper_pt
)
266
{
267
// Nodal positions etc. were created in constructor for
268
// Cylinder...<...>. Need to setup adaptive information.
269
270
// Loop over all elements and set macro element pointer
271
for
(
unsigned
e
= 0;
e
< 4;
e
++)
272
{
273
dynamic_cast<
ELEMENT
*
>
(this->
element_pt
(
e
))
274
->
set_macro_elem_pt
(this->
Domain_pt
->macro_element_pt(
e
));
275
}
276
277
// Setup boundary element lookup schemes
278
this->setup_boundary_element_info();
279
280
// Nodal positions etc. were created in constructor for
281
// RectangularMesh<...>. Only need to setup quadtree forest
282
this->
setup_quadtree_forest
();
283
}
284
285
/// Destructor: Empty
286
virtual
~RefineableRectangleWithHoleMesh
() {}
287
};
288
289
}
// namespace oomph
290
291
#include "
rectangle_with_hole_mesh.template.cc
"
292
#endif
oomph::RectangleWithHoleDomain
Rectangular domain with circular whole.
Definition
rectangle_with_hole_domain.h:41
oomph::RectangleWithHoleMesh
Domain-based mesh for rectangular mesh with circular hole.
Definition
rectangle_with_hole_mesh.h:48
oomph::RectangleWithHoleMesh::Domain_pt
RectangleWithHoleDomain * Domain_pt
Pointer to the domain.
Definition
rectangle_with_hole_mesh.h:238
oomph::RectangleWithHoleMesh::RectangleWithHoleMesh
RectangleWithHoleMesh(GeomObject *cylinder_pt, const double &length, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass pointer to geometric object that represents the cylinder, the length and height of ...
Definition
rectangle_with_hole_mesh.h:56
oomph::RectangleWithHoleMesh::domain_pt
RectangleWithHoleDomain * domain_pt()
Access function to the domain.
Definition
rectangle_with_hole_mesh.h:231
oomph::RefineableRectangleWithHoleMesh
Refineable version of RectangleWithHoleMesh. For some reason this needs on uniform refinement to work...
Definition
rectangle_with_hole_mesh.h:253
oomph::RefineableRectangleWithHoleMesh::~RefineableRectangleWithHoleMesh
virtual ~RefineableRectangleWithHoleMesh()
Destructor: Empty.
Definition
rectangle_with_hole_mesh.h:286
oomph::RefineableRectangleWithHoleMesh::RefineableRectangleWithHoleMesh
RefineableRectangleWithHoleMesh(GeomObject *cylinder_pt, const double &length, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor. Pass pointer to geometric object that represents the cylinder, the length and height of ...
Definition
rectangle_with_hole_mesh.h:261
oomph::RefineableTriangleMesh
Unstructured refineable Triangle Mesh.
Definition
triangle_mesh.h:2225
oomph
Definition
annular_domain.h:35
rectangle_with_hole_domain.h
rectangle_with_hole_mesh.template.cc