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
i
cstr elem_len * i
Definition
cfortran.h:603
oomph::FiniteElement::nnode_1d
virtual unsigned nnode_1d() const
Return the number of nodes along one edge of the element Default is to return zero — must be overload...
Definition
elements.h:2222
oomph::GeomObject::time_stepper_pt
TimeStepper *& time_stepper_pt()
Access function for pointer to time stepper: Null if object is not time-dependent.
Definition
geom_objects.h:192
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::SpineNode
Class for nodes that live on spines. The assumption is that each Node lies at a fixed fraction on a s...
Definition
spines.h:328
oomph::Spine
Spines are used for algebraic node update operations in free-surface fluid problems: They form the ba...
Definition
spines.h:64
oomph::TAdvectionDiffusionReactionElement
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
Definition
Tadvection_diffusion_reaction_elements.h:66
oomph::TAdvectionDiffusionReactionElement::TAdvectionDiffusionReactionElement
TAdvectionDiffusionReactionElement()
Constructor: Call constructors for TElement and AdvectionDiffusionReaction equations.
Definition
Tadvection_diffusion_reaction_elements.h:70
oomph::TimeStepper
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
Definition
timesteppers.h:231
oomph
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition
advection_diffusion_elements.cc:30
rectangular_quadmesh.h