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
demo_drivers
solid
unstructured_solid
unstructured_two_d_solid.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
// Driver code for a simple unstructured solid problem using a mesh
27
// generated from an input file generated by the triangle mesh generator
28
// Triangle.
29
30
//Generic routines
31
#include "generic.h"
32
#include "solid.h"
33
#include "constitutive.h"
34
35
36
// The mesh
37
#include "meshes/triangle_mesh.h"
38
39
using namespace
std;
40
using namespace
oomph;
41
42
43
//================start_mesh===============================================
44
/// Triangle-based mesh upgraded to become a solid mesh
45
//=========================================================================
46
template
<
class
ELEMENT>
47
class
ElasticTriangleMesh
:
public
virtual
TriangleMesh<ELEMENT>,
48
public
virtual
SolidMesh
49
{
50
51
public
:
52
53
/// Constructor:
54
ElasticTriangleMesh
(
const
std::string&
node_file_name
,
55
const
std::string&
element_file_name
,
56
const
std::string&
poly_file_name
,
57
TimeStepper
*
time_stepper_pt
=
58
&
Mesh::Default_TimeStepper
) :
59
TriangleMesh<
ELEMENT
>(
node_file_name
,
element_file_name
,
60
poly_file_name
,
time_stepper_pt
)
61
{
62
//Assign the Lagrangian coordinates
63
set_lagrangian_nodal_coordinates
();
64
65
// Identify special boundaries
66
set_nboundary
(3);
67
68
unsigned
n_node
=this->
nnode
();
69
for
(
unsigned
j
=0;
j
<
n_node
;
j
++)
70
{
71
Node
*
nod_pt
=this->
node_pt
(
j
);
72
73
// Boundary 1 is lower boundary
74
if
(
nod_pt
->x(1)<0.15)
75
{
76
this->
remove_boundary_node
(0,
nod_pt
);
77
this->
add_boundary_node
(1,
nod_pt
);
78
}
79
80
// Boundary 2 is upper boundary
81
if
(
nod_pt
->x(1)>2.69)
82
{
83
this->
remove_boundary_node
(0,
nod_pt
);
84
this->
add_boundary_node
(2,
nod_pt
);
85
}
86
}
87
88
std::cout <<
"About to setup the boundary elements"
<< std::endl;
89
// Re-setup boundary info, i.e. elements next to boundaries
90
TriangleMesh<ELEMENT>::setup_boundary_element_info();
91
//This is the bit that has gone wrong
92
}
93
94
/// Empty Destructor
95
virtual
~ElasticTriangleMesh
() { }
96
97
};
98
99
///////////////////////////////////////////////////////////////////////
100
///////////////////////////////////////////////////////////////////////
101
///////////////////////////////////////////////////////////////////////
102
103
104
105
//=======start_namespace==========================================
106
/// Global variables
107
//================================================================
108
namespace
Global_Physical_Variables
109
{
110
/// Poisson's ratio
111
double
Nu
=0.3;
112
113
/// Pointer to constitutive law
114
ConstitutiveLaw
*
Constitutive_law_pt
=0;
115
116
/// Non-dim gravity
117
double
Gravity
=0.0;
118
119
/// Non-dimensional gravity as body force
120
void
gravity
(
const
double
&
time
,
121
const
Vector<double>
&
xi
,
122
Vector<double>
&
b
)
123
{
124
b
[0]=0.0;
125
b
[1]=-
Gravity
;
126
}
127
128
/// Uniform pressure
129
double
P
= 0.0;
130
131
/// Constant pressure load. The arguments to this function are imposed
132
/// on us by the SolidTractionElements which allow the traction to
133
/// depend on the Lagrangian and Eulerian coordinates x and xi, and on the
134
/// outer unit normal to the surface. Here we only need the outer unit
135
/// normal.
136
void
constant_pressure
(
const
Vector<double>
&
xi
,
const
Vector<double>
&
x
,
137
const
Vector<double>
&
n
,
Vector<double>
&
traction
)
138
{
139
unsigned
dim
=
traction
.size();
140
for
(
unsigned
i
=0;
i
<
dim
;
i
++)
141
{
142
traction
[
i
] = -
P
*
n
[
i
];
143
}
144
}
145
146
}
//end namespace
147
148
149
150
151
152
153
//==============start_problem=========================================
154
/// Unstructured solid problem
155
//====================================================================
156
template
<
class
ELEMENT>
157
class
UnstructuredSolidProblem
:
public
Problem
158
{
159
160
public
:
161
162
/// Constructor:
163
UnstructuredSolidProblem
();
164
165
/// Destructor (empty)
166
~UnstructuredSolidProblem
(){}
167
168
/// Doc the solution
169
void
doc_solution
(
DocInfo
&
doc_info
);
170
171
private
:
172
173
/// Bulk mesh
174
ElasticTriangleMesh<ELEMENT>
*
Solid_mesh_pt
;
175
176
/// Pointer to mesh of traction elements
177
SolidMesh*
Traction_mesh_pt
;
178
179
};
180
181
182
183
//===============start_constructor========================================
184
/// Constructor for unstructured solid problem
185
//========================================================================
186
template
<
class
ELEMENT>
187
UnstructuredSolidProblem<ELEMENT>::UnstructuredSolidProblem
()
188
{
189
190
//Create solid mesh
191
string
node_file_name
=
"solid.fig.1.node"
;
192
string
element_file_name
=
"solid.fig.1.ele"
;
193
string
poly_file_name
=
"solid.fig.1.poly"
;
194
Solid_mesh_pt =
new
ElasticTriangleMesh<ELEMENT>
(
node_file_name
,
195
element_file_name
,
196
poly_file_name
);
197
198
// Traction elements are located on boundary 2:
199
unsigned
b
=2;
200
201
// Make traction mesh
202
Traction_mesh_pt=
new
SolidMesh;
203
204
// How many bulk elements are adjacent to boundary b?
205
unsigned
n_element
= Solid_mesh_pt->nboundary_element(
b
);
206
207
// Loop over the bulk elements adjacent to boundary b
208
for
(
unsigned
e
=0;
e
<
n_element
;
e
++)
209
{
210
// Get pointer to the bulk element that is adjacent to boundary b
211
ELEMENT
*
bulk_elem_pt
=
dynamic_cast<
ELEMENT
*
>
(
212
Solid_mesh_pt->boundary_element_pt(
b
,
e
));
213
214
//Find the index of the face of element e along boundary b
215
int
face_index
= Solid_mesh_pt->face_index_at_boundary(
b
,
e
);
216
217
//Create solid traction element
218
SolidTractionElement<ELEMENT>
*
el_pt
=
219
new
SolidTractionElement<ELEMENT>
(
bulk_elem_pt
,
face_index
);
220
221
// Add to mesh
222
Traction_mesh_pt->add_element_pt(
el_pt
);
223
224
//Set the traction function
225
el_pt
->traction_fct_pt() =
Global_Physical_Variables::constant_pressure
;
226
}
227
228
// Add sub meshes
229
add_sub_mesh
(Solid_mesh_pt);
230
add_sub_mesh
(Traction_mesh_pt);
231
232
// Build global mesh
233
build_global_mesh
();
234
235
// Doc pinned solid nodes
236
std::ofstream
bc_file
(
"pinned_nodes.dat"
);
237
238
// Pin both positions at lower boundary (boundary 1)
239
unsigned
ibound
=1;
240
unsigned
num_nod
=
mesh_pt
()->nboundary_node(
ibound
);
241
for
(
unsigned
inod
=0;
inod
<
num_nod
;
inod
++)
242
{
243
244
// Get node
245
SolidNode
*
nod_pt
=Solid_mesh_pt->boundary_node_pt(
ibound
,
inod
);
246
247
// Pin both directions
248
for
(
unsigned
i
=0;
i
<2;
i
++)
249
{
250
nod_pt
->pin_position(
i
);
251
252
// ...and doc it as pinned
253
bc_file
<<
nod_pt
->x(
i
) <<
" "
;
254
}
255
256
bc_file
<< std::endl;
257
}
258
bc_file
.close();
259
260
261
// Complete the build of all elements so they are fully functional
262
n_element
= Solid_mesh_pt->nelement();
263
for
(
unsigned
i
=0;
i
<
n_element
;
i
++)
264
{
265
//Cast to a solid element
266
ELEMENT
*
el_pt
=
dynamic_cast<
ELEMENT
*
>
(Solid_mesh_pt->element_pt(
i
));
267
268
// Set the constitutive law
269
el_pt
->constitutive_law_pt() =
270
Global_Physical_Variables::Constitutive_law_pt
;
271
272
//Set the body force
273
el_pt
->body_force_fct_pt() =
Global_Physical_Variables::gravity
;
274
}
275
276
// Setup equation numbering scheme
277
cout
<<
"Number of equations: "
<<
assign_eqn_numbers
() << std::endl;
278
279
}
//end constructor
280
281
282
//========================================================================
283
/// Doc the solution
284
//========================================================================
285
template
<
class
ELEMENT>
286
void
UnstructuredSolidProblem<ELEMENT>::doc_solution
(
DocInfo
&
doc_info
)
287
{
288
289
ofstream
some_file
;
290
char
filename
[100];
291
292
// Number of plot points
293
unsigned
npts
;
294
npts
=5;
295
296
// Output solution
297
//----------------
298
snprintf
(
filename
,
sizeof
(
filename
),
"%s/soln%i.dat"
,
doc_info
.directory().c_str(),
299
doc_info
.number());
300
some_file
.open(
filename
);
301
Solid_mesh_pt->output(
some_file
,
npts
);
302
some_file
.close();
303
304
// Output traction
305
//----------------
306
snprintf
(
filename
,
sizeof
(
filename
),
"%s/traction%i.dat"
,
doc_info
.directory().c_str(),
307
doc_info
.number());
308
some_file
.open(
filename
);
309
Traction_mesh_pt->output(
some_file
,
npts
);
310
some_file
.close();
311
312
// Output boundaries
313
//------------------
314
snprintf
(
filename
,
sizeof
(
filename
),
"%s/boundaries.dat"
,
doc_info
.directory().c_str());
315
some_file
.open(
filename
);
316
Solid_mesh_pt->output_boundaries(
some_file
);
317
some_file
.close();
318
319
}
320
321
322
323
324
325
//===========start_main===================================================
326
/// Demonstrate how to solve an unstructured solid problem
327
//========================================================================
328
int
main
()
329
{
330
// Label for output
331
DocInfo
doc_info
;
332
333
// Output directory
334
doc_info
.set_directory(
"RESLT"
);
335
336
// Create generalised Hookean constitutive equations
337
Global_Physical_Variables::Constitutive_law_pt
=
338
new
GeneralisedHookean
(&
Global_Physical_Variables::Nu
);
339
340
{
341
std::cout <<
"Running with pure displacement formulation\n"
;
342
343
//Set up the problem
344
UnstructuredSolidProblem<TPVDElement<2,3>
>
problem
;
345
346
//Output initial configuration
347
problem
.doc_solution(
doc_info
);
348
doc_info
.number()++;
349
350
// Parameter study
351
Global_Physical_Variables::Gravity
=2.0e-4;
352
Global_Physical_Variables::P
=0.0;
353
double
pressure_increment
=-1.0e-4;
354
355
unsigned
nstep
=2;
// 10;
356
for
(
unsigned
istep
=0;
istep
<
nstep
;
istep
++)
357
{
358
// Solve the problem
359
problem
.newton_solve();
360
361
//Output solution
362
problem
.doc_solution(
doc_info
);
363
doc_info
.number()++;
364
365
// Bump up suction
366
Global_Physical_Variables::P
+=
pressure_increment
;
367
}
368
}
//end_displacement_formulation
369
370
//Repeat for displacement/pressure formulation
371
{
372
std::cout <<
"Running with pressure/displacement formulation\n"
;
373
374
// Change output directory
375
doc_info
.set_directory(
"RESLT_pres_disp"
);
376
//Reset doc_info number
377
doc_info
.number() = 0;
378
379
//Set up the problem
380
UnstructuredSolidProblem<TPVDElementWithContinuousPressure<2>
>
problem
;
381
382
//Output initial configuration
383
problem
.doc_solution(
doc_info
);
384
doc_info
.number()++;
385
386
// Parameter study
387
Global_Physical_Variables::Gravity
=2.0e-4;
388
Global_Physical_Variables::P
=0.0;
389
double
pressure_increment
=-1.0e-4;
390
391
unsigned
nstep
=2;
392
for
(
unsigned
istep
=0;
istep
<
nstep
;
istep
++)
393
{
394
// Solve the problem
395
problem
.newton_solve();
396
397
//Output solution
398
problem
.doc_solution(
doc_info
);
399
doc_info
.number()++;
400
401
// Bump up suction
402
Global_Physical_Variables::P
+=
pressure_increment
;
403
}
404
}
405
406
407
//Repeat for displacement/pressure formulation
408
//enforcing incompressibility
409
{
410
std::cout <<
411
"Running with pressure/displacement formulation (incompressible) \n"
;
412
413
// Change output directory
414
doc_info
.set_directory(
"RESLT_pres_disp_incomp"
);
415
//Reset doc_info number
416
doc_info
.number() = 0;
417
418
//Set up the problem
419
UnstructuredSolidProblem<TPVDElementWithContinuousPressure<2>
>
problem
;
420
421
//Loop over all elements and set incompressibility flag
422
{
423
const
unsigned
n_element
=
problem
.mesh_pt()->nelement();
424
for
(
unsigned
e
=0;
e
<
n_element
;
e
++)
425
{
426
//Cast the element to the equation base of our 2D elastiticy elements
427
PVDEquationsWithPressure<2>
*
cast_el_pt
=
428
dynamic_cast<
PVDEquationsWithPressure<2>
*
>
(
429
problem
.mesh_pt()->element_pt(
e
));
430
431
//If the cast was successful, it's a bulk element,
432
//so set the incompressibilty flag
433
if
(
cast_el_pt
) {
cast_el_pt
->set_incompressible();}
434
}
435
}
436
437
438
//Output initial configuration
439
problem
.doc_solution(
doc_info
);
440
doc_info
.number()++;
441
442
// Parameter study
443
Global_Physical_Variables::Gravity
=2.0e-4;
444
Global_Physical_Variables::P
=0.0;
445
double
pressure_increment
=-1.0e-4;
446
447
unsigned
nstep
=2;
448
for
(
unsigned
istep
=0;
istep
<
nstep
;
istep
++)
449
{
450
// Solve the problem
451
problem
.newton_solve();
452
453
//Output solution
454
problem
.doc_solution(
doc_info
);
455
doc_info
.number()++;
456
457
// Bump up suction
458
Global_Physical_Variables::P
+=
pressure_increment
;
459
}
460
}
461
462
463
464
}
// end main
465
466
467
ElasticTetMesh
Triangle-based mesh upgraded to become a solid mesh.
Definition
unstructured_three_d_solid.cc:50
ElasticTetMesh::ElasticTetMesh
ElasticTetMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &poly_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor:
Definition
unstructured_three_d_solid.cc:55
ElasticTriangleMesh
Triangle-based mesh upgraded to become a solid mesh.
Definition
unstructured_two_d_solid.cc:49
ElasticTriangleMesh::ElasticTriangleMesh
ElasticTriangleMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &poly_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor:
Definition
unstructured_two_d_solid.cc:54
ElasticTriangleMesh::~ElasticTriangleMesh
virtual ~ElasticTriangleMesh()
Empty Destructor.
Definition
unstructured_two_d_solid.cc:95
UnstructuredSolidProblem
Unstructured solid problem.
Definition
unstructured_three_d_solid.cc:165
UnstructuredSolidProblem::UnstructuredSolidProblem
UnstructuredSolidProblem()
Constructor:
UnstructuredSolidProblem::~UnstructuredSolidProblem
~UnstructuredSolidProblem()
Destructor (empty)
Definition
unstructured_two_d_solid.cc:166
UnstructuredSolidProblem::Solid_mesh_pt
ElasticTriangleMesh< ELEMENT > * Solid_mesh_pt
Bulk mesh.
Definition
unstructured_two_d_solid.cc:174
UnstructuredSolidProblem::doc_solution
void doc_solution(DocInfo &doc_info)
Doc the solution.
UnstructuredSolidProblem::Traction_mesh_pt
SolidMesh * Traction_mesh_pt
Pointer to mesh of traction elements.
Definition
unstructured_three_d_solid.cc:190
Global_Physical_Variables
Global variables.
Definition
unstructured_three_d_solid.cc:113
Global_Physical_Variables::gravity
void gravity(const double &time, const Vector< double > &xi, Vector< double > &b)
Non-dimensional gravity as body force.
Definition
unstructured_three_d_solid.cc:125
Global_Physical_Variables::constant_pressure
void constant_pressure(const Vector< double > &xi, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
Constant pressure load. The arguments to this function are imposed on us by the SolidTractionElements...
Definition
unstructured_three_d_solid.cc:142
Global_Physical_Variables::P
double P
Uniform pressure.
Definition
unstructured_three_d_solid.cc:135
Global_Physical_Variables::Nu
double Nu
Poisson's ratio.
Definition
unstructured_three_d_solid.cc:119
Global_Physical_Variables::Constitutive_law_pt
ConstitutiveLaw * Constitutive_law_pt
Pointer to constitutive law.
Definition
unstructured_three_d_solid.cc:116
Global_Physical_Variables::Gravity
double Gravity
Non-dim gravity.
Definition
unstructured_three_d_solid.cc:122
main
int main()
Demonstrate how to solve an unstructured solid problem.
Definition
unstructured_two_d_solid.cc:328