simple_shear.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 for elastic deformation of a cuboidal domain
31 // The deformation is a simple shear in the x-z plane driven by
32 // motion of the top boundary, for exact solution see Green & Zerna
33 
34 // Generic oomph-lib headers
35 #include "generic.h"
36 
37 // Solid mechanics
38 #include "solid.h"
39 
40 // The mesh
41 #include "meshes/simple_cubic_mesh.template.h"
42 
43 using namespace std;
44 
45 using namespace oomph;
46 
47 
48 ///////////////////////////////////////////////////////////////////////
49 ///////////////////////////////////////////////////////////////////////
50 ///////////////////////////////////////////////////////////////////////
51 
52 //=========================================================================
53 /// Simple cubic mesh upgraded to become a solid mesh
54 //=========================================================================
55 template<class ELEMENT>
56 class ElasticCubicMesh : public virtual SimpleCubicMesh<ELEMENT>,
57  public virtual SolidMesh
58 {
59 
60 public:
61 
62  /// \short Constructor:
63  ElasticCubicMesh(const unsigned &nx, const unsigned &ny, const unsigned &nz,
64  const double &a, const double &b, const double &c,
65  TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper) :
66  SimpleCubicMesh<ELEMENT>(nx,ny,nz,-a,a,-b,b,-c,c,time_stepper_pt)
67  {
68  //Assign the initial lagrangian coordinates
69  set_lagrangian_nodal_coordinates();
70  }
71 
72  /// Empty Destructor
73  virtual ~ElasticCubicMesh() { }
74 
75 };
76 
77 
78 
79 
80 ///////////////////////////////////////////////////////////////////////
81 ///////////////////////////////////////////////////////////////////////
82 ///////////////////////////////////////////////////////////////////////
83 
84 
85 
86 
87 //================================================================
88 /// Global variables
89 //================================================================
91 {
92  /// Pointer to strain energy function
93  StrainEnergyFunction* Strain_energy_function_pt;
94 
95  /// Pointer to constitutive law
96  ConstitutiveLaw* Constitutive_law_pt;
97 
98  /// Elastic modulus
99  double E=1.0;
100 
101  /// Poisson's ratio
102  double Nu=0.3;
103 
104  /// "Mooney Rivlin" coefficient for generalised Mooney Rivlin law
105  double C1=1.3;
106 
107  /// Body force
108  double Gravity=0.0;
109 
110  /// Body force vector: Vertically downwards with magnitude Gravity
111  void body_force(const Vector<double>& xi,
112  const double& t,
113  Vector<double>& b)
114  {
115  b[0]=0.0;
116  b[1]=-Gravity;
117  }
118 
119 }
120 
121 
122 ///////////////////////////////////////////////////////////////////////
123 ///////////////////////////////////////////////////////////////////////
124 ///////////////////////////////////////////////////////////////////////
125 
126 
127 
128 //======================================================================
129 /// Boundary-driven elastic deformation of fish-shaped domain.
130 //======================================================================
131 template<class ELEMENT>
132 class SimpleShearProblem : public Problem
133 {
134  double Shear;
135 
136  void set_incompressible(ELEMENT *el_pt,const bool &incompressible);
137 
138 public:
139 
140  /// Constructor:
141  SimpleShearProblem(const bool &incompressible);
142 
143  /// Run simulation.
144  void run(const std::string &dirname);
145 
146  /// Access function for the mesh
148  {return dynamic_cast<ElasticCubicMesh<ELEMENT>*>(Problem::mesh_pt());}
149 
150  /// Doc the solution
151  void doc_solution(DocInfo& doc_info);
152 
153  /// Update function (empty)
155 
156  /// \short Update before solve: We're dealing with a static problem so
157  /// the nodal positions before the next solve merely serve as
158  /// initial conditions. For meshes that are very strongly refined
159  /// near the boundary, the update of the displacement boundary
160  /// conditions (which only moves the SolidNodes *on* the boundary),
161  /// can lead to strongly distorted meshes. This can cause the
162  /// Newton method to fail --> the overall method is actually more robust
163  /// if we use the nodal positions as determined by the Domain/MacroElement-
164  /// based mesh update as initial guesses.
166  {
167  apply_boundary_conditions();
168  bool update_all_solid_nodes=true;
169  mesh_pt()->node_update(update_all_solid_nodes);
170  }
171 
172  ///Shear the top
174  {
175  unsigned ibound = 5;
176  unsigned num_nod=mesh_pt()->nboundary_node(ibound);
177  for (unsigned inod=0;inod<num_nod;inod++)
178  {
179  SolidNode *solid_nod_pt = static_cast<SolidNode*>(
180  mesh_pt()->boundary_node_pt(ibound,inod));
181 
182  solid_nod_pt->x(0) = solid_nod_pt->xi(0) + Shear*
183  solid_nod_pt->xi(2);
184  }
185  }
186 
187 };
188 
189 //======================================================================
190 /// Constructor:
191 //======================================================================
192 template<class ELEMENT>
193 SimpleShearProblem<ELEMENT>::SimpleShearProblem(const bool &incompressible)
194  : Shear(0.0)
195 {
196  double a = 1.0, b = 1.0, c = 1.0;
197  unsigned nx = 5, ny = 5, nz = 5;
198 
199  // Build mesh
200  Problem::mesh_pt()=new ElasticCubicMesh<ELEMENT>(nx,ny,nz,a,b,c);
201 
202  //Loop over all boundaries
203  for(unsigned b=0;b<6;b++)
204  {
205  //Loop over nodes in the boundary
206  unsigned n_node = mesh_pt()->nboundary_node(b);
207  for(unsigned n=0;n<n_node;n++)
208  {
209  //Pin all nodes in the y and z directions to keep the motion in plane
210  for(unsigned i=1;i<3;i++)
211  {
212  mesh_pt()->boundary_node_pt(b,n)->pin_position(i);
213  }
214  //On the top and bottom pin the positions in x
215  if((b==0) || (b==5))
216  {
217  mesh_pt()->boundary_node_pt(b,n)->pin_position(0);
218  }
219  }
220  }
221 
222  //Loop over the elements in the mesh to set parameters/function pointers
223  unsigned n_element =mesh_pt()->nelement();
224  for(unsigned i=0;i<n_element;i++)
225  {
226  //Cast to a solid element
227  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(i));
228 
229  // Set the constitutive law
230  el_pt->constitutive_law_pt() =
232 
233  set_incompressible(el_pt,incompressible);
234 
235  // Set the body force
236  //el_pt->body_force_fct_pt()=Global_Physical_Variables::body_force;
237  }
238 
239  // Pin the redundant solid pressures (if any)
240  //PVDEquationsBase<2>::pin_redundant_nodal_solid_pressures(
241  // mesh_pt()->element_pt());
242 
243  //Attach the boundary conditions to the mesh
244  cout << assign_eqn_numbers() << std::endl;
245 }
246 
247 
248 //==================================================================
249 /// Doc the solution
250 //==================================================================
251 template<class ELEMENT>
252 void SimpleShearProblem<ELEMENT>::doc_solution(DocInfo& doc_info)
253 {
254 
255  ofstream some_file;
256  char filename[100];
257 
258  // Number of plot points
259  unsigned npts = 5;
260 
261  // Output shape of deformed body
262  sprintf(filename,"%s/soln%i.dat",doc_info.directory().c_str(),
263  doc_info.number());
264  some_file.open(filename);
265  mesh_pt()->output(some_file,npts);
266  some_file.close();
267 
268  sprintf(filename,"%s/stress%i.dat", doc_info.directory().c_str(),
269  doc_info.number());
270  some_file.open(filename);
271  //Output the appropriate stress at the centre of each element
272  Vector<double> s(3,0.0);
273  Vector<double> x(3);
274  DenseMatrix<double> sigma(3,3);
275 
276  unsigned n_element = mesh_pt()->nelement();
277  for(unsigned e=0;e<n_element;e++)
278  {
279  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e));
280  el_pt->interpolated_x(s,x);
281  el_pt->get_stress(s,sigma);
282 
283  //Output
284  for(unsigned i=0;i<3;i++)
285  {
286  some_file << x[i] << " ";
287  }
288  for(unsigned i=0;i<3;i++)
289  {
290  for(unsigned j=0;j<3;j++)
291  {
292  some_file << sigma(i,j) << " ";
293  }
294  }
295  some_file << std::endl;
296  }
297  some_file.close();
298 
299 }
300 
301 
302 //==================================================================
303 /// Run the problem
304 //==================================================================
305 template<class ELEMENT>
306 void SimpleShearProblem<ELEMENT>::run(const std::string &dirname)
307 {
308 
309  // Output
310  DocInfo doc_info;
311 
312  // Set output directory
313  doc_info.set_directory(dirname);
314 
315  // Step number
316  doc_info.number()=0;
317 
318  // Initial parameter values
319 
320  // Gravity:
322 
323  //Parameter incrementation
324  unsigned nstep=2;
325  for(unsigned i=0;i<nstep;i++)
326  {
327  //Solve the problem with Newton's method, allowing for up to 5
328  //rounds of adaptation
329  newton_solve();
330 
331  // Doc solution
332  doc_solution(doc_info);
333  doc_info.number()++;
334  //Increase the shear
335  Shear += 0.5;
336  }
337 
338 }
339 
340 template<>
341 void SimpleShearProblem<QPVDElement<3,3> >::set_incompressible(
342  QPVDElement<3,3> *el_pt, const bool &incompressible)
343 {
344  //Does nothing
345 }
346 
347 
348 template<>
350  QPVDElementWithPressure<3> *el_pt, const bool &incompressible)
351 {
352  if(incompressible) {el_pt->set_incompressible();}
353  else {el_pt->set_compressible();}
354 }
355 
356 template<>
358 set_incompressible(
359  QPVDElementWithContinuousPressure<3> *el_pt, const bool &incompressible)
360 {
361  if(incompressible) {el_pt->set_incompressible();}
362  else {el_pt->set_compressible();}
363 }
364 
365 
366 //======================================================================
367 /// Driver for simple elastic problem
368 //======================================================================
369 int main()
370 {
371  //Initialise physical parameters
375 
376  for (unsigned i=0;i<2;i++)
377  {
378 
379  // Define a strain energy function: Generalised Mooney Rivlin
381  new GeneralisedMooneyRivlin(&Global_Physical_Variables::Nu,
384 
385  // Define a constitutive law (based on strain energy function)
387  new IsotropicStrainEnergyFunctionConstitutiveLaw(
389 
390  {
391  //Set up the problem with pure displacement formulation
392  SimpleShearProblem<QPVDElement<3,3> > problem(false);
393  problem.run("RESLT");
394  }
395 
396  //Discontinuous pressure
397  {
398  //Set up the problem with pure displacement formulation
400  problem.run("RESLT_pres");
401  }
402 
403  /*{
404  //Set up the problem with pure displacement formulation
405  SimpleShearProblem<QPVDElementWithPressure<3> > problem(true);
406  problem.run("RESLT_pres_incomp");
407  }*/
408 
409 
410  {
411  //Set up the problem with pure displacement formulation
413  problem.run("RESLT_cont_pres");
414  }
415 
416  /*{
417  //Set up the problem with pure displacement formulation
418  SimpleShearProblem<QPVDElementWithContinuousPressure<3> > problem(true);
419  problem.run("RESLT_cont_pres_incomp");
420  }*/
421 
422 
423  }
424 
425 
426 }
427 
428 
429 
430 
431 
void actions_before_newton_solve()
Update before solve: We&#39;re dealing with a static problem so the nodal positions before the next solve...
SimpleShearProblem(const bool &incompressible)
Constructor:
void apply_boundary_conditions()
Shear the top.
void body_force(const Vector< double > &xi, const double &t, Vector< double > &b)
Body force vector: Vertically downwards with magnitude Gravity.
ElasticCubicMesh(const unsigned &nx, const unsigned &ny, const unsigned &nz, const double &a, const double &b, const double &c, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor:
Definition: simple_shear.cc:63
ConstitutiveLaw * Constitutive_law_pt
Pointer to constitutive law.
virtual ~ElasticCubicMesh()
Empty Destructor.
Definition: simple_shear.cc:73
ElasticCubicMesh< ELEMENT > * mesh_pt()
Access function for the mesh.
void doc_solution(DocInfo &doc_info)
Doc the solution.
StrainEnergyFunction * Strain_energy_function_pt
Pointer to strain energy function.
void set_incompressible(ELEMENT *el_pt, const bool &incompressible)
void actions_after_newton_solve()
Update function (empty)
int main()
Driver for simple elastic problem.
Boundary-driven elastic deformation of fish-shaped domain.
Simple cubic mesh upgraded to become a solid mesh.
Definition: simple_shear.cc:56
double C1
"Mooney Rivlin" coefficient for generalised Mooney Rivlin law
void run(const std::string &dirname)
Run simulation.
double Nu
Poisson&#39;s ratio.