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