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
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::CollapsibleChannelMesh::Ny
unsigned Ny
Number of element rows across channel.
Definition
collapsible_channel_mesh.template.h:159
oomph::MacroElementNodeUpdateCollapsibleChannelMesh
////////////////////////////////////////////////////////////////// //////////////////////////////////...
Definition
collapsible_channel_mesh.template.h:241
oomph
////////////////////////////////////////////////////////////////////// //////////////////////////////...
Definition
annular_domain.h:35
rectangular_quadmesh.template.cc