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_cubic_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_CUBIC_SPINE_MESH_TEMPLATE_HEADER
27
#define OOMPH_SINGLE_LAYER_CUBIC_SPINE_MESH_TEMPLATE_HEADER
28
29
#ifndef OOMPH_SINGLE_LAYER_CUBIC_SPINE_MESH_HEADER
30
#error __FILE__ should only be included from single_layer_cubic_spine_mesh.h.
31
#endif
// OOMPH_SINGLE_LAYER_CUBIC_SPINE_MESH_HEADER
32
33
#include "
simple_cubic_mesh.h
"
34
35
namespace
oomph
36
{
37
//===========================================================================
38
/// Constructor for spine 3D mesh: Pass number of elements in x-direction,
39
/// number of elements in y-direction, number elements in z-direction,
40
/// length, width and height of layer,
41
/// and pointer to timestepper (defaults to Static timestepper).
42
//===========================================================================
43
template
<
class
ELEMENT>
44
SingleLayerCubicSpineMesh<ELEMENT>::SingleLayerCubicSpineMesh
(
45
const
unsigned
& nx,
46
const
unsigned
& ny,
47
const
unsigned
& nz,
48
const
double
&
lx
,
49
const
double
&
ly
,
50
const
double
& h,
51
TimeStepper
* time_stepper_pt)
52
:
SimpleCubicMesh
<ELEMENT>(nx, ny, nz,
lx
,
ly
, h, time_stepper_pt)
53
{
54
// Mesh can only be built with 3D Qelements.
55
MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(3);
56
57
// Mesh can only be built with spine elements
58
MeshChecker::assert_geometric_element<SpineFiniteElement, ELEMENT>(3);
59
60
// Now build the single layer mesh on top of the existing mesh
61
build_single_layer_mesh
(time_stepper_pt);
62
}
63
64
//===========================================================================
65
/// Helper function that actually builds the single-layer spine mesh
66
/// based on the parameters set in the various constructors
67
//===========================================================================
68
template
<
class
ELEMENT>
69
void
SingleLayerCubicSpineMesh<ELEMENT>::build_single_layer_mesh
(
70
TimeStepper
* time_stepper_pt)
71
{
72
// Read out the number of elements in the x-direction
73
unsigned
n_x
= this->Nx;
74
// Read out the number of elements in the y-direction
75
unsigned
n_y
= this->Ny;
76
// Read out the number of elements in the z-direction
77
unsigned
n_z
= this->Nz;
78
79
// Allocate memory for the spines and fractions along spines
80
81
// Read out number of linear points in the element
82
unsigned
n_p
=
dynamic_cast<
ELEMENT*
>
(finite_element_pt(0))->
nnode_1d
();
83
84
// Allocate store for the spines: (different in the case of periodic meshes
85
// !!)
86
Spine_pt.reserve(((
n_p
- 1) *
n_x
+ 1) * ((
n_p
- 1) *
n_y
+ 1));
87
88
// Now we loop over all the elements and attach the spines
89
90
// FIRST ELEMENT: Element 0
91
// Loop over the nodes on the base of the element
92
for
(
unsigned
l1
= 0;
l1
<
n_p
;
l1
++)
// y loop over the nodes
93
{
94
for
(
unsigned
l2
= 0;
l2
<
n_p
;
l2
++)
// x loop over the nodes
95
{
96
// Assign the new spine with length h
97
Spine
*
new_spine_pt
=
new
Spine
(1.0);
98
Spine_pt.push_back(
new_spine_pt
);
99
100
// Get pointer to node
101
SpineNode
*
nod_pt
= element_node_pt(0,
l2
+
l1
*
n_p
);
102
// Set the pointer to the spine
103
nod_pt
->spine_pt() =
new_spine_pt
;
104
// Set the fraction
105
nod_pt
->fraction() = 0.0;
106
// Pointer to the mesh that implements the update fct
107
nod_pt
->spine_mesh_pt() =
this
;
108
109
// Loop vertically along the spine
110
// Loop over the elements
111
for
(
unsigned
long
k
= 0;
k
<
n_z
;
k
++)
112
{
113
// Loop over the vertical nodes, apart from the first
114
for
(
unsigned
l3
= 1;
l3
<
n_p
;
l3
++)
115
{
116
// Get pointer to node
117
SpineNode
*
nod_pt
=
118
element_node_pt(
k
*
n_x
*
n_y
,
l3
*
n_p
*
n_p
+
l2
+
l1
*
n_p
);
119
// Set the pointer to the spine
120
nod_pt
->spine_pt() =
new_spine_pt
;
121
// Set the fraction
122
nod_pt
->fraction() =
123
(
double
(
k
) +
double
(
l3
) /
double
(
n_p
- 1)) /
double
(
n_z
);
124
// Pointer to the mesh that implements the update fct
125
nod_pt
->spine_mesh_pt() =
this
;
126
}
127
}
128
}
129
}
130
131
// LOOP OVER OTHER ELEMENTS IN THE FIRST ROW
132
//-----------------------------------------
133
134
// The procedure is the same but we have to identify the
135
// before defined spines for not defining them two times
136
137
for
(
unsigned
j
= 1;
j
<
n_x
;
j
++)
// loop over the elements in the first
138
// row
139
{
140
for
(
unsigned
l1
= 0;
l1
<
n_p
;
l1
++)
// y loop over the nodes
141
{
142
// First we copy the last row of nodes into the
143
// first row of the new element (and extend to the third dimension)
144
for
(
unsigned
l2
= 1;
l2
<
n_p
;
l2
++)
// x loop over the nodes
145
{
146
// Node j + i*np
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(
j
,
l2
+
l1
*
n_p
);
153
154
// Set the pointer to the spine
155
nod_pt
->spine_pt() =
new_spine_pt
;
156
// Set the fraction
157
nod_pt
->fraction() = 0.0;
158
// Pointer to the mesh that implements the update fct
159
nod_pt
->spine_mesh_pt() =
this
;
160
161
// Loop vertically along the spine
162
// Loop over the elements
163
for
(
unsigned
long
k
= 0;
k
<
n_z
;
k
++)
164
{
165
// Loop over the vertical nodes, apart from the first
166
for
(
unsigned
l3
= 1;
l3
<
n_p
;
l3
++)
167
{
168
// Get pointer to node
169
SpineNode
*
nod_pt
= element_node_pt(
170
j
+
k
*
n_x
*
n_y
,
l3
*
n_p
*
n_p
+
l2
+
l1
*
n_p
);
171
// Set the pointer to the spine
172
nod_pt
->spine_pt() =
new_spine_pt
;
173
// Set the fraction
174
nod_pt
->fraction() =
175
(
double
(
k
) +
double
(
l3
) /
double
(
n_p
- 1)) /
double
(
n_z
);
176
// Pointer to the mesh that implements the update fct
177
nod_pt
->spine_mesh_pt() =
this
;
178
}
179
}
180
}
181
}
182
}
183
184
// REST OF THE ELEMENTS
185
// Now we loop over the rest of the elements.
186
// We will separate the first of each row being al the rest equal
187
for
(
unsigned
long
i
= 1;
i
<
n_y
;
i
++)
188
{
189
// FIRST ELEMENT OF THE ROW
190
191
// First line of nodes is copied from the element of the bottom
192
for
(
unsigned
l1
= 1;
l1
<
n_p
;
l1
++)
// y loop over the nodes
193
{
194
for
(
unsigned
l2
= 0;
l2
<
n_p
;
l2
++)
// x loop over the nodes
195
{
196
// Node j + i*np
197
// Assign the new spine with unit length
198
Spine
*
new_spine_pt
=
new
Spine
(1.0);
199
Spine_pt.push_back(
new_spine_pt
);
200
201
// Get pointer to node
202
// Element i*n_x; node l2 + l1*n_p
203
SpineNode
*
nod_pt
= element_node_pt(
i
*
n_x
,
l2
+
l1
*
n_p
);
204
// Set the pointer to the spine
205
nod_pt
->spine_pt() =
new_spine_pt
;
206
// Set the fraction
207
nod_pt
->fraction() = 0.0;
208
// Pointer to the mesh that implements the update fct
209
nod_pt
->spine_mesh_pt() =
this
;
210
211
// Loop vertically along the spine
212
// Loop over the elements
213
for
(
unsigned
long
k
= 0;
k
<
n_z
;
k
++)
214
{
215
// Loop over the vertical nodes, apart from the first
216
for
(
unsigned
l3
= 1;
l3
<
n_p
;
l3
++)
217
{
218
// Get pointer to node
219
SpineNode
*
nod_pt
= element_node_pt(
220
i
*
n_x
+
k
*
n_x
*
n_y
,
l3
*
n_p
*
n_p
+
l2
+
l1
*
n_p
);
221
// Set the pointer to the spine
222
nod_pt
->spine_pt() =
new_spine_pt
;
223
// Set the fraction
224
nod_pt
->fraction() =
225
(
double
(
k
) +
double
(
l3
) /
double
(
n_p
- 1)) /
double
(
n_z
);
226
// Pointer to the mesh that implements the update fct
227
nod_pt
->spine_mesh_pt() =
this
;
228
}
229
}
230
}
231
}
232
233
// REST OF THE ELEMENTS OF THE ROW
234
for
(
unsigned
j
= 1;
j
<
n_x
;
j
++)
235
{
236
// First line of nodes is copied from the element of the bottom
237
for
(
unsigned
l1
= 1;
l1
<
n_p
;
l1
++)
// y loop over the nodes
238
{
239
for
(
unsigned
l2
= 1;
l2
<
n_p
;
l2
++)
// x loop over the nodes
240
{
241
// Node j + i*np
242
// Assign the new spine with unit length
243
Spine
*
new_spine_pt
=
new
Spine
(1.0);
244
Spine_pt.push_back(
new_spine_pt
);
245
246
// Get pointer to node
247
// Element j + i*n_x; node l2 + l1*n_p
248
SpineNode
*
nod_pt
= element_node_pt(
j
+
i
*
n_x
,
l2
+
l1
*
n_p
);
249
// Set the pointer to the spine
250
nod_pt
->spine_pt() =
new_spine_pt
;
251
// Set the fraction
252
nod_pt
->fraction() = 0.0;
253
// Pointer to the mesh that implements the update fct
254
nod_pt
->spine_mesh_pt() =
this
;
255
256
// Loop vertically along the spine
257
// Loop over the elements
258
for
(
unsigned
long
k
= 0;
k
<
n_z
;
k
++)
259
{
260
// Loop over the vertical nodes, apart from the first
261
for
(
unsigned
l3
= 1;
l3
<
n_p
;
l3
++)
262
{
263
// Get pointer to node
264
SpineNode
*
nod_pt
= element_node_pt(
265
j
+
i
*
n_x
+
k
*
n_x
*
n_y
,
l3
*
n_p
*
n_p
+
l2
+
l1
*
n_p
);
266
// Set the pointer to the spine
267
nod_pt
->spine_pt() =
new_spine_pt
;
268
// Set the fraction
269
nod_pt
->fraction() =
270
(
double
(
k
) +
double
(
l3
) /
double
(
n_p
- 1)) /
double
(
n_z
);
271
// Pointer to the mesh that implements the update fct
272
nod_pt
->spine_mesh_pt() =
this
;
273
}
274
}
275
}
276
}
277
}
278
}
279
}
280
281
}
// namespace oomph
282
#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::SimpleCubicMesh
Simple cubic 3D Brick mesh class.
Definition
simple_cubic_mesh.h:47
oomph::SingleLayerCubicSpineMesh::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_cubic_spine_mesh.template.cc:69
oomph::SingleLayerCubicSpineMesh::SingleLayerCubicSpineMesh
SingleLayerCubicSpineMesh(const unsigned &nx, const unsigned &ny, const unsigned &nz, const double &lx, const double &ly, 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_cubic_spine_mesh.template.cc:44
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
simple_cubic_mesh.h