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
Installation
Installation guide
Copyright
About
People
Contact/Get involved
Publications
Acknowledgements
Picture show
Go
src
meshes
circular_shell_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-2024 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_CIRCULAR_SHELL_MESH_TEMPLATE_CC
27
#define OOMPH_CIRCULAR_SHELL_MESH_TEMPLATE_CC
28
29
#include <float.h>
30
31
#include "
circular_shell_mesh.template.h
"
32
#include "
rectangular_quadmesh.template.cc
"
33
34
35
namespace
oomph
36
{
37
//=======================================================================
38
/// Mesh build fct
39
//=======================================================================
40
template
<
class
ELEMENT>
41
void
CircularCylindricalShellMesh<ELEMENT>::build_mesh
(
const
unsigned
& nx,
42
const
unsigned
& ny,
43
const
double
&
lx
,
44
const
double
&
ly
)
45
{
46
// Mesh can only be built with 2D Qelements.
47
MeshChecker::assert_geometric_element<QElementGeometricBase, ELEMENT>(2);
48
49
// Find out how many nodes there are
50
unsigned
n_node
=
nnode
();
51
52
// Now in this case it is the Lagrangian coordinates that we want to set,
53
// so we have to loop over all nodes and set them to the Eulerian
54
// coordinates that are set by the generic mesh generator
55
for
(
unsigned
i
= 0;
i
<
n_node
;
i
++)
56
{
57
node_pt
(
i
)->xi(0) = scaled_x(
node_pt
(
i
)->x(0));
58
node_pt
(
i
)->xi(1) =
node_pt
(
i
)->
x
(1);
59
}
60
61
62
// Loop over elements and nodes to find out min axial spacing
63
// for all nodes
64
65
// Initialise map
66
std::map<Node*, double>
min_dx
;
67
unsigned
nnod
=
nnode
();
68
for
(
unsigned
j
= 0;
j
<
nnod
;
j
++)
min_dx
[
node_pt
(
j
)] =
DBL_MAX
;
69
70
// Loop over elements
71
unsigned
nelem
= nelement();
72
for
(
unsigned
e
= 0;
e
<
nelem
;
e
++)
73
{
74
ELEMENT*
el_pt
=
dynamic_cast<
ELEMENT*
>
(element_pt(
e
));
75
unsigned
n_node
=
el_pt
->
nnode
();
76
for
(
unsigned
j
= 0;
j
<
n_node
;
j
++)
77
{
78
SolidNode
*
nod_pt
=
dynamic_cast<
SolidNode
*
>
(
el_pt
->
node_pt
(
j
));
79
double
x =
nod_pt
->xi(0);
80
for
(
unsigned
k
= 0;
k
<
n_node
;
k
++)
81
{
82
double
dx
=
83
fabs
(x -
dynamic_cast<
SolidNode
*
>
(
el_pt
->
node_pt
(
k
))->
xi
(0));
84
if
(
dx
<
min_dx
[
nod_pt
])
85
{
86
if
(
dx
!= 0.0)
min_dx
[
nod_pt
] =
dx
;
87
}
88
}
89
}
90
}
91
92
93
// Assign gradients, etc for the Lagrangian coordinates of
94
// Hermite-type elements
95
96
// Read out number of position dofs
97
unsigned
n_position_type
= finite_element_pt(0)->
nnodal_position_type
();
98
99
// Assign generalised Lagrangian positions (min slope, c.f. M. Heil's PhD
100
// thesis
101
if
(
n_position_type
> 1)
102
{
103
// Default spacing
104
double
xstep
= (this->Xmax - this->Xmin) / ((this->Np - 1) * this->Nx);
105
double
ystep
= (this->Ymax - this->Ymin) / ((this->Np - 1) * this->Ny);
106
107
// Adjust for non-uniform spacing
108
for
(
unsigned
j
= 0;
j
<
n_node
;
j
++)
109
{
110
SolidNode
*
nod_pt
=
node_pt
(
j
);
111
112
// Get min. spacing for non-uniform axial spacing
113
xstep
=
min_dx
[
nod_pt
];
114
115
// The factor 0.5 is because our reference element has length 2.0
116
nod_pt
->xi_gen(1, 0) = 0.5 *
xstep
;
117
nod_pt
->xi_gen(2, 1) = 0.5 *
ystep
;
118
}
119
}
120
}
121
122
123
//=======================================================================
124
/// Set the undeformed coordinates of the nodes
125
//=======================================================================
126
template
<
class
ELEMENT>
127
void
CircularCylindricalShellMesh<ELEMENT>::assign_undeformed_positions
(
128
GeomObject
*
const
& undeformed_midplane_pt)
129
{
130
// Loop over nodes in elements
131
unsigned
nelem
= nelement();
132
for
(
unsigned
e
= 0;
e
<
nelem
;
e
++)
133
{
134
ELEMENT*
el_pt
=
dynamic_cast<
ELEMENT*
>
(element_pt(
e
));
135
unsigned
n_node
=
el_pt
->
nnode
();
136
for
(
unsigned
n
= 0;
n
<
n_node
;
n
++)
137
{
138
// Get the Lagrangian coordinates
139
Vector<double>
xi(2);
140
xi[0] =
dynamic_cast<
SolidNode
*
>
(
el_pt
->
node_pt
(
n
))->xi(0);
141
xi[1] =
dynamic_cast<
SolidNode
*
>
(
el_pt
->
node_pt
(
n
))->xi(1);
142
143
// Assign memory for values of derivatives, etc
144
Vector<double>
R(3);
145
DenseMatrix<double>
a(2, 3);
146
RankThreeTensor<double>
dadxi
(2, 2, 3);
147
148
// Get the geometrical information from the geometric object
149
undeformed_midplane_pt->
d2position
(xi, R, a,
dadxi
);
150
151
152
// Get derivatives of Lagr coordinates w.r.t. local coords
153
DenseMatrix<double>
dxids
(2, 2);
154
Vector<double>
s
(2);
155
el_pt
->
local_coordinate_of_node
(
n
,
s
);
156
el_pt
->interpolated_dxids(
s
,
dxids
);
157
double
dxds
=
dxids
(0, 0);
158
159
// Loop over coordinate directions
160
for
(
unsigned
i
= 0;
i
< 3;
i
++)
161
{
162
// Set the position
163
el_pt
->
node_pt
(
n
)->
x_gen
(0,
i
) = R[
i
];
164
165
// Set generalised positions
166
el_pt
->
node_pt
(
n
)->
x_gen
(1,
i
) = a(0,
i
) *
dxds
;
167
el_pt
->
node_pt
(
n
)->
x_gen
(2,
i
) =
168
0.5 * a(1,
i
) * ((this->Ymax - this->Ymin) / this->Ny);
169
170
// Set the mixed derivative
171
el_pt
->
node_pt
(
n
)->
x_gen
(3,
i
) = 0.0;
172
173
// Check for warping
174
if
(
dadxi
(0, 1,
i
) != 0.0)
175
{
176
std::ostringstream
error_stream
;
177
error_stream
178
<<
"Undef. GeomObject for this shell mesh should not be warped!\n"
179
<<
"It may be possible to generalise the mesh generator to \n"
180
<<
"deal with this case -- feel free to have a go...\n"
;
181
throw
OomphLibError
(
error_stream
.str(),
182
OOMPH_CURRENT_FUNCTION
,
183
OOMPH_EXCEPTION_LOCATION
);
184
}
185
}
186
}
187
}
188
}
189
190
191
}
// namespace oomph
192
193
194
// namespace oomph
195
// {
196
197
198
// //=======================================================================
199
// /// Mesh constructor
200
// /// Argument list:
201
// /// nx : number of elements in the axial direction
202
// /// ny : number of elements in the azimuthal direction
203
// /// lx : length in the axial direction
204
// /// ly : length in theta direction
205
// //=======================================================================
206
// template <class ELEMENT>
207
// CircularCylindricalShellMesh<ELEMENT>::CircularCylindricalShellMesh(
208
// const unsigned &nx,
209
// const unsigned &ny,
210
// const double &lx,
211
// const double &ly,
212
// TimeStepper* time_stepper_pt) :
213
// RectangularQuadMesh<ELEMENT>(nx,ny,lx,ly,time_stepper_pt)
214
// {
215
// //Find out how many nodes there are
216
// unsigned n_node = nnode();
217
218
// //Now in this case it is the Lagrangian coordinates that we want to set,
219
// //so we have to loop over all nodes and set them to the Eulerian
220
// //coordinates that are set by the generic mesh generator
221
// for(unsigned i=0;i<n_node;i++)
222
// {
223
// node_pt(i)->xi(0) = node_pt(i)->x(0);
224
// node_pt(i)->xi(1) = node_pt(i)->x(1);
225
// }
226
227
228
// //Assign gradients, etc for the Lagrangian coordinates of
229
// //Hermite-type elements
230
231
// //Read out number of position dofs
232
// unsigned n_position_type = finite_element_pt(0)->nnodal_position_type();
233
234
// //If this is greater than 1 set the slopes, which are the distances between
235
// //nodes. If the spacing were non-uniform, this part would be more difficult
236
// if(n_position_type > 1)
237
// {
238
// double xstep = (this->Xmax - this->Xmin)/((this->Np-1)*this->Nx);
239
// double ystep = (this->Ymax - this->Ymin)/((this->Np-1)*this->Ny);
240
// for(unsigned n=0;n<n_node;n++)
241
// {
242
// //The factor 0.5 is because our reference element has length 2.0
243
// node_pt(n)->xi_gen(1,0) = 0.5*xstep;
244
// node_pt(n)->xi_gen(2,1) = 0.5*ystep;
245
// }
246
// }
247
// }
248
249
250
// //=======================================================================
251
// /// Set the undeformed coordinates of the nodes
252
// //=======================================================================
253
// template <class ELEMENT>
254
// void CircularCylindricalShellMesh<ELEMENT>::assign_undeformed_positions(
255
// GeomObject* const &undeformed_midplane_pt)
256
// {
257
// //Find out how many nodes there are
258
// unsigned n_node = nnode();
259
260
// //Loop over all the nodes
261
// for(unsigned n=0;n<n_node;n++)
262
// {
263
// //Get the Lagrangian coordinates
264
// Vector<double> xi(2);
265
// xi[0] = node_pt(n)->xi(0);
266
// xi[1] = node_pt(n)->xi(1);
267
268
// //Assign memory for values of derivatives, etc
269
// Vector<double> R(3);
270
// DenseMatrix<double> a(2,3);
271
// RankThreeTensor<double> dadxi(2,2,3);
272
273
// //Get the geometrical information from the geometric object
274
// undeformed_midplane_pt->d2position(xi,R,a,dadxi);
275
276
// //Loop over coordinate directions
277
// for(unsigned i=0;i<3;i++)
278
// {
279
// //Set the position
280
// node_pt(n)->x_gen(0,i) = R[i];
281
282
// //Set the derivative wrt Lagrangian coordinates
283
// //Note that we need to scale by the length of each element here!!
284
// node_pt(n)->x_gen(1,i) = 0.5*a(0,i)*((this->Xmax -
285
// this->Xmin)/this->Nx); node_pt(n)->x_gen(2,i) = 0.5*a(1,i)*((this->Ymax
286
// - this->Ymin)/this->Ny);
287
288
// //Set the mixed derivative
289
// //(symmetric so doesn't matter which one we use)
290
// node_pt(n)->x_gen(3,i) = 0.25*dadxi(0,1,i);
291
// }
292
// }
293
// }
294
295
296
// }
297
#endif
e
e
Definition
cfortran.h:571
s
static char t char * s
Definition
cfortran.h:568
i
cstr elem_len * i
Definition
cfortran.h:603
circular_shell_mesh.template.h
oomph::CircularCylindricalShellMesh::build_mesh
void build_mesh(const unsigned &nx, const unsigned &ny, const double &lx, const double &ly)
Mesh build helper fct.
Definition
circular_shell_mesh.template.cc:41
oomph::CircularCylindricalShellMesh::assign_undeformed_positions
void assign_undeformed_positions(GeomObject *const &undeformed_midplane_pt)
In all elastic problems, the nodes must be assigned an undeformed, or reference, position,...
Definition
circular_shell_mesh.template.cc:127
oomph::FiniteElement::local_coordinate_of_node
virtual void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Get local coordinates of node j in the element; vector sets its own size (broken virtual)
Definition
elements.h:1846
oomph::FiniteElement::nnodal_position_type
unsigned nnodal_position_type() const
Return the number of coordinate types that the element requires to interpolate the geometry between t...
Definition
elements.h:2467
oomph::FiniteElement::nnode
unsigned nnode() const
Return the number of nodes.
Definition
elements.h:2214
oomph::FiniteElement::node_pt
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition
elements.h:2179
oomph::GeomObject
/////////////////////////////////////////////////////////////////////
Definition
geom_objects.h:101
oomph::GeomObject::d2position
virtual void d2position(const Vector< double > &zeta, RankThreeTensor< double > &ddrdzeta) const
2nd derivative of position Vector w.r.t. to coordinates: = ddrdzeta(alpha,beta,i)....
Definition
geom_objects.h:341
oomph::Node::x
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition
nodes.h:1060
oomph::Node::x_gen
double & x_gen(const unsigned &k, const unsigned &i)
Reference to the generalised position x(k,i). ‘Type’: k; Coordinate direction: i.
Definition
nodes.h:1126
oomph::OomphLibError
An OomphLibError object which should be thrown when an run-time error is encountered....
Definition
oomph_definitions.h:222
oomph::SolidNode
A Class for nodes that deform elastically (i.e. position is an unknown in the problem)....
Definition
nodes.h:1686
oomph::SolidNode::xi
double & xi(const unsigned &i)
Reference to i-th Lagrangian position.
Definition
nodes.h:1883
oomph::TAdvectionDiffusionReactionElement
//////////////////////////////////////////////////////////////////////
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
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
Definition
advection_diffusion_elements.cc:30
rectangular_quadmesh.template.cc