unstructured_three_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 3d mesh generator
28// tetgen
29
30//Generic routines
31#include "generic.h"
32#include "solid.h"
33#include "constitutive.h"
34
35// Get the mesh
36#include "meshes/tetgen_mesh.h"
37
38using namespace std;
39using namespace oomph;
40
41
42
43//=======================start_mesh========================================
44/// Tetgen-based mesh upgraded to become a solid mesh
45//=========================================================================
46template<class ELEMENT>
47class MySolidTetgenMesh : public virtual TetgenMesh<ELEMENT>,
48 public virtual SolidMesh
49{
50
51public:
52
53 /// Constructor:
54 MySolidTetgenMesh(const std::string& node_file_name,
55 const std::string& element_file_name,
56 const std::string& face_file_name,
57 TimeStepper* time_stepper_pt=
58 &Mesh::Default_TimeStepper) :
59 TetgenMesh<ELEMENT>(node_file_name, element_file_name,
60 face_file_name, time_stepper_pt)
61 {
62 //Assign the Lagrangian coordinates
63 set_lagrangian_nodal_coordinates();
64
65 // Find elements next to boundaries
66 setup_boundary_element_info();
67 }
68
69 /// Empty Destructor
70 virtual ~MySolidTetgenMesh() { }
71
72
73};
74
75
76//////////////////////////////////////////////////////////////////
77//////////////////////////////////////////////////////////////////
78//////////////////////////////////////////////////////////////////
79
80
81//=======start_namespace==========================================
82/// Global variables
83//================================================================
85{
86
87 /// Poisson's ratio
88 double Nu=0.3;
89
90 /// Create constitutive law
91 ConstitutiveLaw* Constitutive_law_pt=new GeneralisedHookean(&Nu);
92
93 /// Non-dim gravity
94 double Gravity=0.0;
95
96 /// Non-dimensional gravity as body force
97 void gravity(const double& time,
98 const Vector<double> &xi,
99 Vector<double> &b)
100 {
101 b[0]=-Gravity;
102 b[1]=0.0;
103 b[2]=0.0;
104 } // end gravity
105
106 /// Uniform pressure
107 double P = 0.0;
108
109 /// Constant pressure load. The arguments to this function are imposed
110 /// on us by the SolidTractionElements which allow the traction to
111 /// depend on the Lagrangian and Eulerian coordinates x and xi, and on the
112 /// outer unit normal to the surface. Here we only need the outer unit
113 /// normal.
114 void constant_pressure(const Vector<double> &xi, const Vector<double> &x,
115 const Vector<double> &n, Vector<double> &traction)
116 {
117 unsigned dim = traction.size();
118 for(unsigned i=0;i<dim;i++)
119 {
120 traction[i] = -P*n[i];
121 }
122 } // end traction
123
124
125} //end namespace
126
127
128
129
130
131
132//=============start_problem===========================================
133/// Unstructured solid problem
134//=====================================================================
135template<class ELEMENT>
136class UnstructuredSolidProblem : public Problem
137{
138
139public:
140
141 /// Constructor:
143
144 /// Destructor (empty)
146
147 /// Doc the solution
148 void doc_solution(DocInfo& doc_info);
149
150private:
151
152 /// Create traction elements
154
155 /// Bulk solid mesh
157
158 /// Meshes of traction elements
159 Vector<SolidMesh*> Solid_traction_mesh_pt;
160
161 /// IDs of solid mesh boundaries where displacements are pinned
162 Vector<unsigned> Pinned_solid_boundary_id;
163
164 /// IDs of solid mesh boundaries which make up the traction interface
166
167};
168
169
170
171//=============start_constructor==========================================
172/// Constructor for unstructured solid problem
173//========================================================================
174template<class ELEMENT>
176{
177
178 //Create solid bulk mesh
179 string node_file_name="fsi_bifurcation_solid.1.node";
180 string element_file_name="fsi_bifurcation_solid.1.ele";
181 string face_file_name="fsi_bifurcation_solid.1.face";
182 Solid_mesh_pt = new MySolidTetgenMesh<ELEMENT>(node_file_name,
185
186 // The following IDs corresponds to the boundary IDs specified in
187 // the *.poly file from which tetgen generated the unstructured mesh.
188
189 /// IDs of solid mesh boundaries where displacements are pinned
190 Pinned_solid_boundary_id.resize(3);
191 Pinned_solid_boundary_id[0]=0;
192 Pinned_solid_boundary_id[1]=1;
193 Pinned_solid_boundary_id[2]=2;
194
195 // The solid mesh boundaries where an internal pressure is applied
196 Solid_traction_boundary_id.resize(12);
197 for (unsigned i=0;i<12;i++)
198 {
199 Solid_traction_boundary_id[i]=i+3;
200 }
201
202
203 // Apply BCs for solid
204 //--------------------
205
206 // Doc pinned solid nodes
207 std::ofstream bc_file("RESLT/pinned_solid_nodes.dat");
208
209 // Pin positions at inflow boundary (boundaries 0 and 1)
210 unsigned n=Pinned_solid_boundary_id.size();
211 for (unsigned i=0;i<n;i++)
212 {
213 // Get boundary ID
214 unsigned b=Pinned_solid_boundary_id[i];
215 unsigned num_nod= Solid_mesh_pt->nboundary_node(b);
216 for (unsigned inod=0;inod<num_nod;inod++)
217 {
218 // Get node
219 SolidNode* nod_pt=Solid_mesh_pt->boundary_node_pt(b,inod);
220
221 // Pin all directions
222 for (unsigned i=0;i<3;i++)
223 {
224 nod_pt->pin_position(i);
225
226 // ...and doc it as pinned
227 bc_file << nod_pt->x(i) << " ";
228 }
229
230 bc_file << std::endl;
231 }
232 }
233 bc_file.close();
234
235
236
237 // Complete the build of all elements so they are fully functional
238 //----------------------------------------------------------------
239 unsigned n_element = Solid_mesh_pt->nelement();
240 for(unsigned i=0;i<n_element;i++)
241 {
242 //Cast to a solid element
243 ELEMENT *el_pt = dynamic_cast<ELEMENT*>(
244 Solid_mesh_pt->element_pt(i));
245
246 // Set the constitutive law
247 el_pt->constitutive_law_pt() =
249
250 //Set the body force
251 el_pt->body_force_fct_pt() = Global_Parameters::gravity;
252 }
253
254
255 // Create traction elements
256 //-------------------------
257
258 // Create meshes of traction elements
259 n=Solid_traction_boundary_id.size();
260 Solid_traction_mesh_pt.resize(n);
261 for (unsigned i=0;i<n;i++)
262 {
263 Solid_traction_mesh_pt[i]=new SolidMesh;
264 }
265
266 // Build the traction elements
267 create_traction_elements();
268
269
270 // Combine the lot
271 //----------------
272
273 // The solid bulk mesh
274 add_sub_mesh(Solid_mesh_pt);
275
276 // The solid traction meshes
277 n=Solid_traction_boundary_id.size();
278 for (unsigned i=0;i<n;i++)
279 {
280 add_sub_mesh(Solid_traction_mesh_pt[i]);
281 }
282
283 // Build global mesh
285
286 // Setup equation numbering scheme
287 std::cout <<"Number of equations: " << assign_eqn_numbers() << std::endl;
288
289} // end constructor
290
291
292
293//============start_of_create_traction_elements==========================
294/// Create traction elements
295//=======================================================================
296template<class ELEMENT>
298{
299
300 // Loop over traction boundaries
301 unsigned n=Solid_traction_boundary_id.size();
302 for (unsigned i=0;i<n;i++)
303 {
304 // Get boundary ID
305 unsigned b=Solid_traction_boundary_id[i];
306
307 // How many bulk elements are adjacent to boundary b?
308 unsigned n_element = Solid_mesh_pt->nboundary_element(b);
309
310 // Loop over the bulk elements adjacent to boundary b
311 for(unsigned e=0;e<n_element;e++)
312 {
313 // Get pointer to the bulk element that is adjacent to boundary b
314 ELEMENT* bulk_elem_pt = dynamic_cast<ELEMENT*>(
315 Solid_mesh_pt->boundary_element_pt(b,e));
316
317 //What is the index of the face of the element e along boundary b
318 int face_index = Solid_mesh_pt->face_index_at_boundary(b,e);
319
320 // Create new element
323
324 // Add it to the mesh
325 Solid_traction_mesh_pt[i]->add_element_pt(el_pt);
326
327 //Set the traction function
328 el_pt->traction_fct_pt() = Global_Parameters::constant_pressure;
329 }
330 }
331
332} // end of create_traction_elements
333
334
335
336//========================================================================
337/// Doc the solution
338//========================================================================
339template<class ELEMENT>
341{
342
344 char filename[100];
345
346 // Number of plot points
347 unsigned npts;
348 npts=5;
349
350 // Output solid solution
351 //-----------------------
352 snprintf(filename, sizeof(filename), "%s/solid_soln%i.dat",doc_info.directory().c_str(),
353 doc_info.number());
354 some_file.open(filename);
355 Solid_mesh_pt->output(some_file,npts);
356 some_file.close();
357
358
359 // Output traction
360 //----------------
361 snprintf(filename, sizeof(filename), "%s/traction%i.dat",doc_info.directory().c_str(),
362 doc_info.number());
363 some_file.open(filename);
364 unsigned n=Solid_traction_boundary_id.size();
365 for (unsigned i=0;i<n;i++)
366 {
367 Solid_traction_mesh_pt[i]->output(some_file,npts);
368 }
369 some_file.close();
370
371} // end doc
372
373
374
375
376
377//============================start_main==================================
378/// Demonstrate how to solve an unstructured 3D solid problem
379//========================================================================
380int main(int argc, char **argv)
381{
382 // Store command line arguments
384
385 // Label for output
387
388 // Output directory
389 doc_info.set_directory("RESLT");
390
391 //Set up the problem
393
394 //Output initial configuration
395 problem.doc_solution(doc_info);
396 doc_info.number()++;
397
398 // Parameter study
400 double g_increment=1.0e-3;
401 double p_increment=1.0e-2;
402
403 unsigned nstep=6;
405 {
406 std::cout << "Validation -- only doing two steps" << std::endl;
407 nstep=2;
408 }
409
410 // Do the parameter study
411 for (unsigned istep=0;istep<nstep;istep++)
412 {
413 // Solve the problem
414 problem.newton_solve();
415
416 //Output solution
417 problem.doc_solution(doc_info);
418 doc_info.number()++;
419
420 // Bump up load
423
424 }
425
426} // end main
427
428
429
430
Tetgen-based mesh upgraded to become a solid mesh.
MySolidTetgenMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &face_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor:
virtual ~MySolidTetgenMesh()
Empty Destructor.
Unstructured solid problem.
~UnstructuredSolidProblem()
Destructor (empty)
Vector< SolidMesh * > Solid_traction_mesh_pt
Meshes of traction elements.
Vector< unsigned > Solid_traction_boundary_id
IDs of solid mesh boundaries which make up the traction interface.
Vector< unsigned > Pinned_solid_boundary_id
IDs of solid mesh boundaries where displacements are pinned.
void create_traction_elements()
Create traction elements.
void doc_solution(DocInfo &doc_info)
Doc the solution.
MySolidTetgenMesh< ELEMENT > * Solid_mesh_pt
Bulk solid mesh.
void gravity(const double &time, const Vector< double > &xi, Vector< double > &b)
Non-dimensional gravity as body force.
double Nu
Poisson's ratio.
double P
Uniform pressure.
double Gravity
Non-dim gravity.
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...
ConstitutiveLaw * Constitutive_law_pt
Create constitutive law.
int main(int argc, char **argv)
Demonstrate how to solve an unstructured 3D solid problem.