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