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
single_layer_spine_mesh.template.cc
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_SINGLE_LAYER_SPINE_MESH_TEMPLATE_HEADER
27
#define OOMPH_SINGLE_LAYER_SPINE_MESH_TEMPLATE_HEADER
28
29
#ifndef OOMPH_SINGLE_LAYER_SPINE_MESH_HEADER
30
#error __FILE__ should only be included from single_layer_spine_mesh.h.
31
#endif
// OOMPH_SINGLE_LAYER_SPINE_MESH_HEADER
32
33
#include "
rectangular_quadmesh.h
"
34
35
namespace
oomph
36
{
37
//===========================================================================
38
/// Constructor for spine 2D mesh: Pass number of elements in x-direction,
39
/// number of elements in y-direction, axial length and height of layer,
40
/// and pointer to timestepper (defaults to Static timestepper).
41
///
42
/// The mesh must be called with spinified elements and it
43
/// constructs the spines and contains the information on how to update
44
/// the nodal positions within the mesh as a function of the spine lengths.
45
/// Equations that determine the spine heights (even if they are pinned)
46
/// must be specified externally or else there will be problems.
47
48
//===========================================================================
49
template
<
class
ELEMENT>
50
SingleLayerSpineMesh<ELEMENT>::SingleLayerSpineMesh
(
51
const
unsigned
& nx,
52
const
unsigned
& ny,
53
const
double
&
lx
,
54
const
double
&
h
,
55
TimeStepper
*
time_stepper_pt
)
56
:
RectangularQuadMesh
<
ELEMENT
>(
57
nx, ny, 0.0,
lx
, 0.0,
h
,
false
,
false
,
time_stepper_pt
)
58
{
59
// Mesh can only be built with 2D Qelements.
60
MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
61
62
// Mesh can only be built with spine elements
63
MeshChecker::assert_geometric_element<SpineFiniteElement, ELEMENT>(2);
64
65
// We've called the "generic" constructor for the RectangularQuadMesh
66
// which doesn't do much...
67
68
// Now build the mesh:
69
build_single_layer_mesh
(
time_stepper_pt
);
70
}
71
72
//===========================================================================
73
/// Constuctor for spine 2D mesh: Pass number of elements in x-direction,
74
/// number of elements in y-direction, axial length and height of layer,
75
/// a boolean flag to make the mesh periodic in the x-direction,
76
/// and pointer to timestepper (defaults to Static timestepper).
77
///
78
/// The mesh must be called with spinified elements and it
79
/// constructs the spines and contains the information on how to update
80
/// the nodal positions within the mesh as a function of the spine lengths.
81
/// Equations that determine the spine heights (even if they are pinned)
82
/// must be specified externally or else there will be problems.
83
//===========================================================================
84
template
<
class
ELEMENT>
85
SingleLayerSpineMesh<ELEMENT>::SingleLayerSpineMesh
(
86
const
unsigned
& nx,
87
const
unsigned
& ny,
88
const
double
&
lx
,
89
const
double
&
h
,
90
const
bool
&
periodic_in_x
,
91
TimeStepper
*
time_stepper_pt
)
92
:
RectangularQuadMesh
<
ELEMENT
>(
93
nx, ny, 0.0,
lx
, 0.0,
h
,
periodic_in_x
,
false
,
time_stepper_pt
)
94
{
95
// Mesh can only be built with 2D Qelements.
96
MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
97
98
// Mesh can only be built with spine elements
99
MeshChecker::assert_geometric_element<SpineFiniteElement, ELEMENT>(2);
100
101
// We've called the "generic" constructor for the RectangularQuadMesh
102
// which doesn't do much...
103
104
// Now build the mesh:
105
build_single_layer_mesh
(
time_stepper_pt
);
106
}
107
108
//===========================================================================
109
/// Helper function that actually builds the single-layer spine mesh
110
/// based on the parameters set in the various constructors
111
//===========================================================================
112
template
<
class
ELEMENT>
113
void
SingleLayerSpineMesh<ELEMENT>::build_single_layer_mesh
(
114
TimeStepper
*
time_stepper_pt
)
115
{
116
// Mesh can only be built with 2D Qelements.
117
MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
118
119
// Build the underlying quad mesh:
120
RectangularQuadMesh<ELEMENT>::build_mesh
(
time_stepper_pt
);
121
122
// Read out the number of elements in the x-direction
123
unsigned
n_x
= this->Nx;
124
unsigned
n_y
= this->Ny;
125
126
// Allocate memory for the spines and fractions along spines
127
//---------------------------------------------------------
128
129
// Read out number of linear points in the element
130
unsigned
n_p
=
dynamic_cast<
ELEMENT
*
>
(
finite_element_pt
(0))->
nnode_1d
();
131
132
// Allocate store for the spines:
133
if
(this->Xperiodic)
134
{
135
Spine_pt
.reserve((
n_p
- 1) *
n_x
);
136
}
137
else
138
{
139
Spine_pt
.reserve((
n_p
- 1) *
n_x
+ 1);
140
}
141
142
// FIRST SPINE
143
//-----------
144
145
// Element 0
146
// Node 0
147
// Assign the new spine with unit length
148
Spine
*
new_spine_pt
=
new
Spine
(1.0);
149
Spine_pt
.push_back(
new_spine_pt
);
150
151
// Get pointer to node
152
SpineNode
*
nod_pt
=
element_node_pt
(0, 0);
153
// Set the pointer to the spine
154
nod_pt
->spine_pt() =
new_spine_pt
;
155
// Set the fraction
156
nod_pt
->fraction() = 0.0;
157
// Pointer to the mesh that implements the update fct
158
nod_pt
->spine_mesh_pt() =
this
;
159
160
// Loop vertically along the spine
161
// Loop over the elements
162
for
(
unsigned
long
i
= 0;
i
<
n_y
;
i
++)
163
{
164
// Loop over the vertical nodes, apart from the first
165
for
(
unsigned
l1
= 1;
l1
<
n_p
;
l1
++)
166
{
167
// Get pointer to node
168
SpineNode
*
nod_pt
=
element_node_pt
(
i
*
n_x
,
l1
*
n_p
);
169
// Set the pointer to the spine
170
nod_pt
->spine_pt() =
new_spine_pt
;
171
// Set the fraction
172
nod_pt
->fraction() =
173
(
double
(
i
) +
double
(
l1
) /
double
(
n_p
- 1)) /
double
(
n_y
);
174
// Pointer to the mesh that implements the update fct
175
nod_pt
->spine_mesh_pt() =
this
;
176
}
177
}
178
179
// LOOP OVER OTHER SPINES
180
//----------------------
181
182
// Now loop over the elements horizontally
183
for
(
unsigned
long
j
= 0;
j
<
n_x
;
j
++)
184
{
185
// Loop over the nodes in the elements horizontally, ignoring
186
// the first column
187
188
// Last spine needs special treatment in x-periodic meshes:
189
unsigned
n_pmax
=
n_p
;
190
if
((this->Xperiodic) && (
j
==
n_x
- 1))
n_pmax
=
n_p
- 1;
191
192
for
(
unsigned
l2
= 1;
l2
<
n_pmax
;
l2
++)
193
{
194
// Assign the new spine with unit height
195
new_spine_pt
=
new
Spine
(1.0);
196
Spine_pt
.push_back(
new_spine_pt
);
197
198
// Get the node
199
SpineNode
*
nod_pt
=
element_node_pt
(
j
,
l2
);
200
// Set the pointer to spine
201
nod_pt
->spine_pt() =
new_spine_pt
;
202
// Set the fraction
203
nod_pt
->fraction() = 0.0;
204
// Pointer to the mesh that implements the update fct
205
nod_pt
->spine_mesh_pt() =
this
;
206
207
// Loop vertically along the spine
208
// Loop over the elements
209
for
(
unsigned
long
i
= 0;
i
<
n_y
;
i
++)
210
{
211
// Loop over the vertical nodes, apart from the first
212
for
(
unsigned
l1
= 1;
l1
<
n_p
;
l1
++)
213
{
214
// Get the node
215
SpineNode
*
nod_pt
=
element_node_pt
(
i
*
n_x
+
j
,
l1
*
n_p
+
l2
);
216
// Set the pointer to the spine
217
nod_pt
->spine_pt() =
new_spine_pt
;
218
// Set the fraction
219
nod_pt
->fraction() =
220
(
double
(
i
) +
double
(
l1
) /
double
(
n_p
- 1)) /
double
(
n_y
);
221
// Pointer to the mesh that implements the update fct
222
nod_pt
->spine_mesh_pt() =
this
;
223
}
224
}
225
}
226
}
227
228
// Last spine needs special treatment for periodic meshes
229
// because it's the same as the first one...
230
if
(this->Xperiodic)
231
{
232
// Last spine is the same as first one...
233
Spine
*
final_spine_pt
=
Spine_pt
[0];
234
235
// Get the node
236
SpineNode
*
nod_pt
=
element_node_pt
((
n_x
- 1), (
n_p
- 1));
237
238
// Set the pointer for the first node
239
nod_pt
->spine_pt() =
final_spine_pt
;
240
// Set the fraction to be the same as for the nodes on the first row
241
nod_pt
->fraction() =
element_node_pt
(0, 0)->fraction();
242
// Pointer to the mesh that implements the update fct
243
nod_pt
->spine_mesh_pt() =
element_node_pt
(0, 0)->spine_mesh_pt();
244
245
// Now loop vertically along the spine
246
for
(
unsigned
i
= 0;
i
<
n_y
;
i
++)
247
{
248
// Loop over the vertical nodes, apart from the first
249
for
(
unsigned
l1
= 1;
l1
<
n_p
;
l1
++)
250
{
251
// Get the node
252
SpineNode
*
nod_pt
=
253
element_node_pt
(
i
*
n_x
+ (
n_x
- 1),
l1
*
n_p
+ (
n_p
- 1));
254
255
// Set the pointer to the spine
256
nod_pt
->spine_pt() =
final_spine_pt
;
257
// Set the fraction to be the same as in first row
258
nod_pt
->fraction() =
element_node_pt
(
i
*
n_x
,
l1
*
n_p
)->fraction();
259
// Pointer to the mesh that implements the update fct
260
nod_pt
->spine_mesh_pt() =
261
element_node_pt
(
i
*
n_x
,
l1
*
n_p
)->spine_mesh_pt();
262
}
263
}
264
}
265
}
266
267
}
// namespace oomph
268
#endif
oomph::RectangularQuadMesh
RectangularQuadMesh is a two-dimensional mesh of Quad elements with Nx elements in the "x" (horizonal...
Definition
rectangular_quadmesh.h:59
oomph::RectangularQuadMesh::build_mesh
void build_mesh(TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Generic mesh construction function: contains all the hard work.
Definition
rectangular_quadmesh.template.cc:44
oomph::SingleLayerSpineMesh::SingleLayerSpineMesh
SingleLayerSpineMesh(const unsigned &nx, const unsigned &ny, const double &lx, const double &h, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in x-direction, number of elements in y-direction,...
Definition
single_layer_spine_mesh.template.cc:50
oomph::SingleLayerSpineMesh::build_single_layer_mesh
virtual void build_single_layer_mesh(TimeStepper *time_stepper_pt)
Helper function to actually build the single-layer spine mesh (called from various constructors)
Definition
single_layer_spine_mesh.template.cc:113
oomph::TetgenMesh
Unstructured tet mesh based on output from Tetgen: http://wias-berlin.de/software/tetgen/.
Definition
tetgen_mesh.h:51
oomph::TetgenMesh::TetgenMesh
TetgenMesh()
Empty constructor.
Definition
tetgen_mesh.h:54
oomph
Definition
annular_domain.h:35
rectangular_quadmesh.h