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