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
39using namespace std;
40using namespace oomph;
41
42
43//================start_mesh===============================================
44/// Triangle-based mesh upgraded to become a solid mesh
45//=========================================================================
46template<class ELEMENT>
47class ElasticTriangleMesh : public virtual TriangleMesh<ELEMENT>,
48 public virtual SolidMesh
49{
50
51public:
52
53 /// Constructor:
55 const std::string& element_file_name,
56 const std::string& poly_file_name,
61 {
62 //Assign the Lagrangian coordinates
64
65 // Identify special boundaries
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 {
78 }
79
80 // Boundary 2 is upper boundary
81 if (nod_pt->x(1)>2.69)
82 {
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
96
97};
98
99///////////////////////////////////////////////////////////////////////
100///////////////////////////////////////////////////////////////////////
101///////////////////////////////////////////////////////////////////////
102
103
104
105//=======start_namespace==========================================
106/// Global variables
107//================================================================
109{
110 /// Poisson's ratio
111 double Nu=0.3;
112
113 /// Pointer to constitutive law
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,
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.
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//====================================================================
156template<class ELEMENT>
157class UnstructuredSolidProblem : public Problem
158{
159
160public:
161
162 /// Constructor:
164
165 /// Destructor (empty)
167
168 /// Doc the solution
170
171private:
172
173 /// Bulk mesh
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//========================================================================
186template<class ELEMENT>
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";
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
220
221 // Add to mesh
222 Traction_mesh_pt->add_element_pt(el_pt);
223
224 //Set the traction function
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
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() =
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//========================================================================
285template<class ELEMENT>
287{
288
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//========================================================================
328int main()
329{
330 // Label for output
332
333 // Output directory
334 doc_info.set_directory("RESLT");
335
336 // Create generalised Hookean constitutive equations
339
340 {
341 std::cout << "Running with pure displacement formulation\n";
342
343 //Set up the problem
345
346 //Output initial configuration
347 problem.doc_solution(doc_info);
348 doc_info.number()++;
349
350 // Parameter study
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
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
381
382 //Output initial configuration
383 problem.doc_solution(doc_info);
384 doc_info.number()++;
385
386 // Parameter study
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
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
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
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
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
459 }
460 }
461
462
463
464} // end main
465
466
467
Triangle-based mesh upgraded to become a solid mesh.
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:
Triangle-based mesh upgraded to become a solid mesh.
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:
virtual ~ElasticTriangleMesh()
Empty Destructor.
Unstructured solid problem.
UnstructuredSolidProblem()
Constructor:
~UnstructuredSolidProblem()
Destructor (empty)
ElasticTriangleMesh< ELEMENT > * Solid_mesh_pt
Bulk mesh.
void doc_solution(DocInfo &doc_info)
Doc the solution.
SolidMesh * Traction_mesh_pt
Pointer to mesh of traction elements.
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.