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;
39
40using namespace oomph;
41
42
43
44//=========================================================================
45/// Triangle-based mesh upgraded to become a solid mesh
46//=========================================================================
47template<class ELEMENT>
48class ElasticTetMesh : public virtual TetgenMesh<ELEMENT>,
49 public virtual SolidMesh
50{
51
52public:
53
54 /// Constructor:
55 ElasticTetMesh(const std::string& node_file_name,
56 const std::string& element_file_name,
57 const std::string& poly_file_name,
58 TimeStepper* time_stepper_pt=
59 &Mesh::Default_TimeStepper) :
60 TetgenMesh<ELEMENT>(node_file_name, element_file_name,
61 poly_file_name, time_stepper_pt)
62 {
63 //Assign the Lagrangian coordinates
64 set_lagrangian_nodal_coordinates();
65
66 // Identify special boundaries but remember that
67 // outer boundary is already set to boundary 0; inner
68 // (hole) boundary is already boundary 1.
69 set_nboundary(4);
70
71 unsigned n_node=this->nnode();
72 for (unsigned j=0;j<n_node;j++)
73 {
74 Node* nod_pt=this->node_pt(j);
75
76 // Boundary 2 is right boundary
77 if (nod_pt->x(1)>2.99)
78 {
79 this->convert_to_boundary_node(nod_pt);
80 this->remove_boundary_node(0,nod_pt);
81 this->add_boundary_node(2,nod_pt);
82 }
83
84 // Boundary 3 is upper boundary
85 if (nod_pt->x(2)>2.99)
86 {
87 this->convert_to_boundary_node(nod_pt);
88 this->remove_boundary_node(0,nod_pt);
89 this->add_boundary_node(3,nod_pt);
90 }
91
92 }
93 TetgenMesh<ELEMENT>::setup_boundary_element_info();
94
95 }
96
97 /// Empty Destructor
98 virtual ~ElasticTetMesh() { }
99
100
101};
102
103///////////////////////////////////////////////////////////////////////
104///////////////////////////////////////////////////////////////////////
105///////////////////////////////////////////////////////////////////////
106
107
108
109//=======start_namespace==========================================
110/// Global variables
111//================================================================
113{
114
115 /// Pointer to constitutive law
116 ConstitutiveLaw* Constitutive_law_pt=0;
117
118 /// Poisson's ratio
119 double Nu=0.3;
120
121 /// Non-dim gravity
122 double Gravity=0.0;
123
124 /// Non-dimensional gravity as body force
125 void gravity(const double& time,
126 const Vector<double> &xi,
127 Vector<double> &b)
128 {
129 b[0]=0.0;
130 b[1]=0.0;
131 b[2]=-Gravity;
132 }
133
134 /// Uniform pressure
135 double P = 0.0;
136
137 /// Constant pressure load. The arguments to this function are imposed
138 /// on us by the SolidTractionElements which allow the traction to
139 /// depend on the Lagrangian and Eulerian coordinates x and xi, and on the
140 /// outer unit normal to the surface. Here we only need the outer unit
141 /// normal.
142 void constant_pressure(const Vector<double> &xi, const Vector<double> &x,
143 const Vector<double> &n, Vector<double> &traction)
144 {
145 unsigned dim = traction.size();
146 for(unsigned i=0;i<dim;i++)
147 {
148 traction[i] = -P*n[i];
149 }
150 } // end traction
151
152
153} //end namespace
154
155
156
157
158
159
160//====================================================================
161/// Unstructured solid problem
162//====================================================================
163template<class ELEMENT>
164class UnstructuredSolidProblem : public Problem
165{
166
167public:
168
169 /// Constructor:
171
172 /// Destructor (empty)
174
175 /// Update the problem specs before solve: empty
177
178 /// Update the problem specs before solve: empty
180
181 /// Doc the solution
182 void doc_solution(DocInfo& doc_info);
183
184private:
185
186 /// Bulk mesh
188
189 /// Pointer to mesh of traction elements
191
192};
193
194
195
196//========================================================================
197/// Constructor for unstructured solid problem
198//========================================================================
199template<class ELEMENT>
202{
203
204 //Create bulk mesh
205 string node_file_name="cube_hole.1.node";
206 string element_file_name="cube_hole.1.ele";
207 string face_file_name="cube_hole.1.face";
208 Solid_mesh_pt = new ElasticTetMesh<ELEMENT>(node_file_name,
211
212 // Traction elements are located on boundary 3:
213 unsigned b=3;
214
215 // Make traction mesh
216 Traction_mesh_pt=new SolidMesh;
217
218 // How many bulk elements are adjacent to boundary b?
219 unsigned n_element = Solid_mesh_pt->nboundary_element(b);
220
221 // Loop over the bulk elements adjacent to boundary b
222 for(unsigned e=0;e<n_element;e++)
223 {
224 // Get pointer to the bulk element that is adjacent to boundary b
225 ELEMENT* bulk_elem_pt = dynamic_cast<ELEMENT*>(
226 Solid_mesh_pt->boundary_element_pt(b,e));
227
228 //Find the index of the face of element e along boundary b
229 int face_index = Solid_mesh_pt->face_index_at_boundary(b,e);
230
231 //Create solid traction element
234
235 // Add to mesh
236 Traction_mesh_pt->add_element_pt(el_pt);
237
238 //Set the traction function
240
241 }
242
243
244 // Add sub meshes
245 add_sub_mesh(Solid_mesh_pt);
246 add_sub_mesh(Traction_mesh_pt);
247
248 // Build global mesh
250
251
252 // Doc pinned solid nodes
253 std::ofstream bc_file("pinned_nodes.dat");
254
255 // Pin positions at right boundary (boundary 2)
256 unsigned ibound=2;
257 unsigned num_nod= Solid_mesh_pt->nboundary_node(ibound);
258 for (unsigned inod=0;inod<num_nod;inod++)
259 {
260 // Get node
261 SolidNode* nod_pt=Solid_mesh_pt->boundary_node_pt(ibound,inod);
262
263 // Pin all directions
264 for (unsigned i=0;i<3;i++)
265 {
266 nod_pt->pin_position(i);
267
268 // ...and doc it as pinned
269 bc_file << nod_pt->x(i) << " ";
270 }
271
272 bc_file << std::endl;
273 }
274
275 // Complete the build of all elements so they are fully functional
276 n_element = Solid_mesh_pt->nelement();
277 for(unsigned i=0;i<n_element;i++)
278 {
279 //Cast to a solid element
280 ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Solid_mesh_pt->element_pt(i));
281
282 // Set the constitutive law
283 el_pt->constitutive_law_pt() =
285
286 //Set the body force
287 el_pt->body_force_fct_pt() = Global_Physical_Variables::gravity;
288 }
289
290
291 // Setup equation numbering scheme
292 cout <<"Number of equations: " << assign_eqn_numbers() << std::endl;
293
294}
295
296
297
298//========================================================================
299/// Doc the solution
300//========================================================================
301template<class ELEMENT>
303{
304
306 char filename[100];
307
308 // Number of plot points
309 unsigned npts;
310 npts=5;
311
312 // Output boundaries
313 //------------------
314 snprintf(filename, sizeof(filename), "%s/boundaries%i.dat",doc_info.directory().c_str(),
315 doc_info.number());
316 some_file.open(filename);
317 Solid_mesh_pt->output_boundaries(some_file);
318 some_file.close();
319
320
321 // Output solution
322 //----------------
323 snprintf(filename, sizeof(filename), "%s/soln%i.dat",doc_info.directory().c_str(),
324 doc_info.number());
325 some_file.open(filename);
326 Solid_mesh_pt->output(some_file,npts);
327 some_file.close();
328
329
330 // Output traction
331 //----------------
332 snprintf(filename, sizeof(filename), "%s/traction%i.dat",doc_info.directory().c_str(),
333 doc_info.number());
334 some_file.open(filename);
335 Traction_mesh_pt->output(some_file,npts);
336 some_file.close();
337
338}
339
340
341
342
343
344//========================================================================
345/// Demonstrate how to solve an unstructured solid problem
346//========================================================================
347int main()
348{
349
350 // Label for output
352
353 // Output directory
354 doc_info.set_directory("RESLT");
355
356 // Create generalised Hookean constitutive equations
359
360 //Set up the problem
362
363 //Output initial configuration
364 problem.doc_solution(doc_info);
365 doc_info.number()++;
366
367 // Parameter study
370 double pressure_increment=-8.0e-3;
371
372 unsigned nstep=2; // 10;
373 for (unsigned istep=0;istep<nstep;istep++)
374 {
375 // Solve the problem
376 problem.newton_solve();
377
378 //Output solution
379 problem.doc_solution(doc_info);
380 doc_info.number()++;
381
382 // Bump up suction
384 }
385
386}
387
388
389
Triangle-based mesh upgraded to become a solid mesh.
virtual ~ElasticTetMesh()
Empty Destructor.
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:
Unstructured solid problem.
ElasticTetMesh< ELEMENT > * Solid_mesh_pt
Bulk mesh.
~UnstructuredSolidProblem()
Destructor (empty)
void actions_after_newton_solve()
Update the problem specs before solve: empty.
void doc_solution(DocInfo &doc_info)
Doc the solution.
SolidMesh * Traction_mesh_pt
Pointer to mesh of traction elements.
void actions_before_newton_solve()
Update the problem specs before solve: empty.
void gravity(const double &time, const Vector< double > &xi, Vector< double > &b)
Non-dimensional gravity as body force.
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
Pointer to constitutive law.
int main()
Demonstrate how to solve an unstructured solid problem.