compressed_square.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 compressed square
31 
32 //Oomph-lib includes
33 #include "generic.h"
34 #include "solid.h"
35 
36 //The mesh
37 #include "meshes/rectangular_quadmesh.h"
38 
39 using namespace std;
40 
41 using namespace oomph;
42 
43 namespace oomph
44 {
45 
46 //=================start_wrapper==================================
47 /// Wrapper class for solid element to modify the output
48 //================================================================
49 template <class ELEMENT>
50 class MySolidElement : public virtual ELEMENT
51 {
52 
53 public:
54 
55  /// Constructor: Call constructor of underlying element
56  MySolidElement() : ELEMENT() {}
57 
58  /// Overload output function
59  void output(std::ostream &outfile, const unsigned &n_plot)
60  {
61  Vector<double> s(2);
62  Vector<double> x(2);
63  Vector<double> xi(2);
64  DenseMatrix<double> sigma(2,2);
65 
66  //Tecplot header info
67  outfile << "ZONE I=" << n_plot << ", J=" << n_plot << std::endl;
68 
69  //Loop over plot points
70  for(unsigned l2=0;l2<n_plot;l2++)
71  {
72  s[1] = -1.0 + l2*2.0/(n_plot-1);
73  for(unsigned l1=0;l1<n_plot;l1++)
74  {
75  s[0] = -1.0 + l1*2.0/(n_plot-1);
76 
77  // Get Eulerian and Lagrangian coordinates and the stress
78  this->interpolated_x(s,x);
79  this->interpolated_xi(s,xi);
80  this->get_stress(s,sigma);
81 
82  //Output the x,y coordinates
83  for(unsigned i=0;i<2;i++)
84  {outfile << x[i] << " ";}
85 
86  // Output displacements, the difference between Eulerian and Lagrangian
87  // coordinates
88  for(unsigned i=0;i<2;i++)
89  {outfile << x[i]-xi[i] << " ";}
90 
91  //Output stress
92  outfile << sigma(0,0) << " "
93  << sigma(1,0) << " "
94  << sigma(1,1) << " "
95  << std::endl;
96  }
97  }
98  }
99 };
100 
101 } //end namespace extension
102 
103 
104 
105 ///////////////////////////////////////////////////////////////////////
106 ///////////////////////////////////////////////////////////////////////
107 ///////////////////////////////////////////////////////////////////////
108 
109 
110 
111 //=======start_namespace==========================================
112 /// Global variables
113 //================================================================
115 {
116 
117  /// Pointer to constitutive law
118  ConstitutiveLaw* Constitutive_law_pt=0;
119 
120  /// Poisson's ratio for Hooke's law
121  double Nu=0.45;
122 
123  /// Pointer to strain energy function
124  StrainEnergyFunction* Strain_energy_function_pt=0;
125 
126  /// First "Mooney Rivlin" coefficient for generalised Mooney Rivlin law
127  double C1=1.3;
128 
129  /// Second "Mooney Rivlin" coefficient for generalised Mooney Rivlin law
130  double C2=1.3;
131 
132  /// Non-dim gravity
133  double Gravity=0.0;
134 
135  /// Non-dimensional gravity as body force
136  void gravity(const double& time,
137  const Vector<double> &xi,
138  Vector<double> &b)
139  {
140  b[0]=0.0;
141  b[1]=-Gravity;
142  }
143 
144 } //end namespace
145 
146 
147 
148 //=============begin_problem============================================
149 /// Problem class
150 //======================================================================
151 template<class ELEMENT>
152 class CompressedSquareProblem : public Problem
153 {
154 
155 public:
156 
157  /// \short Constructor: Pass flag that determines if we want to use
158  /// a true incompressible formulation
159  CompressedSquareProblem(const bool& incompress);
160 
161  /// Update function (empty)
163 
164  /// Update function (empty)
166 
167  /// \short Doc the solution & exact (linear) solution for compressible
168  /// or incompressible materials
169  void doc_solution(const bool& incompress);
170 
171  /// Run the job -- doc in RESLTi_case
172  void run_it(const int& i_case,const bool& incompress);
173 
174 private:
175 
176  /// Trace file
177  ofstream Trace_file;
178 
179  /// Pointers to node whose position we're tracing
181 
182  /// DocInfo object for output
183  DocInfo Doc_info;
184 
185 };
186 
187 
188 //===========start_of_constructor=======================================
189 /// Constructor: Pass flag that determines if we want to enforce
190 /// incompressibility
191 //======================================================================
192 template<class ELEMENT>
194  const bool& incompress)
195 {
196 
197  // Create the mesh
198 
199  // # of elements in x-direction
200  unsigned n_x=5;
201 
202  // # of elements in y-direction
203  unsigned n_y=5;
204 
205  // Domain length in x-direction
206  double l_x=1.0;
207 
208  // Domain length in y-direction
209  double l_y=1.0;
210 
211  //Now create the mesh
212  mesh_pt() = new ElasticRectangularQuadMesh<ELEMENT>(n_x,n_y,l_x,l_y);
213 
214 
215  //Assign the physical properties to the elements
216  unsigned n_element=mesh_pt()->nelement();
217  for(unsigned i=0;i<n_element;i++)
218  {
219  //Cast to a solid element
220  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(i));
221 
222  // Set the constitutive law
223  el_pt->constitutive_law_pt() =
225 
226  //Set the body force
227  el_pt->body_force_fct_pt() = Global_Physical_Variables::gravity;
228 
229 
230  // Is the element based on the pressure/displacement formulation?
231  PVDEquationsWithPressure<2>* test_pt =
232  dynamic_cast<PVDEquationsWithPressure<2>*>(mesh_pt()->element_pt(i));
233  if (test_pt!=0)
234  {
235  // Do we want true incompressibility (formulation III in the
236  // associated tutorial) or not (formulation II)
237  if (incompress)
238  {
239  test_pt->set_incompressible();
240  }
241  else
242  {
243  // Note that this assignment isn't strictly necessary as it's the
244  // default setting, but it doesn't do any harm to be explicit.
245  test_pt->set_compressible();
246  }
247  }
248  } // end compressibility
249 
250 
251  // Choose a control node: The last node in the solid mesh
252  unsigned nnod=mesh_pt()->nnode();
253  Trace_node_pt=mesh_pt()->node_pt(nnod-1);
254 
255 // Pin the left and right boundaries (1 and 2) in the horizontal directions
256  for (unsigned b=1;b<4;b+=2)
257  {
258  unsigned nnod = mesh_pt()->nboundary_node(b);
259  for(unsigned i=0;i<nnod;i++)
260  {
261  dynamic_cast<SolidNode*>(
262  mesh_pt()->boundary_node_pt(b,i))->pin_position(0);
263  }
264  }
265 
266 // Pin the bottom boundary (0) in the vertical direction
267  unsigned b=0;
268  {
269  unsigned nnod= mesh_pt()->nboundary_node(b);
270  for(unsigned i=0;i<nnod;i++)
271  {
272  dynamic_cast<SolidNode*>(
273  mesh_pt()->boundary_node_pt(b,i))->pin_position(1);
274  }
275  }
276 
277  //Assign equation numbers
278  assign_eqn_numbers();
279 
280 } //end of constructor
281 
282 
283 
284 //==============start_doc===========================================
285 /// Doc the solution
286 //==================================================================
287 template<class ELEMENT>
289 {
290  ofstream some_file;
291  char filename[100];
292 
293  // Number of plot points
294  unsigned n_plot = 5;
295 
296  // Output shape of and stress in deformed body
297  sprintf(filename,"%s/soln%i.dat",Doc_info.directory().c_str(),
298  Doc_info.number());
299  some_file.open(filename);
300  mesh_pt()->output(some_file,n_plot);
301  some_file.close();
302 
303  // Write trace file: Load/displacement characteristics
304  Trace_file << Global_Physical_Variables::Gravity << " "
305  << Trace_node_pt->x(0) << " "
306  << Trace_node_pt->x(1) << " "
307  << std::endl;
308 
309 
310  // Output exact solution for linear elasticity
311  // -------------------------------------------
312  sprintf(filename,"%s/exact_soln%i.dat",Doc_info.directory().c_str(),
313  Doc_info.number());
314  some_file.open(filename);
315  unsigned nelem=mesh_pt()->nelement();
316  Vector<double> s(2);
317  Vector<double> x(2);
318  DenseMatrix<double> sigma(2,2);
319 
320  // Poisson's ratio
322  if (incompress) nu=0.5;
323 
324  // Loop over all elements
325  for (unsigned e=0;e<nelem;e++)
326  {
327  //Cast to a solid element
328  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e));
329 
330  //Tecplot header info
331  some_file << "ZONE I=" << n_plot << ", J=" << n_plot << std::endl;
332 
333  //Loop over plot points
334  for(unsigned l2=0;l2<n_plot;l2++)
335  {
336  s[1] = -1.0 + l2*2.0/(n_plot-1);
337  for(unsigned l1=0;l1<n_plot;l1++)
338  {
339  s[0] = -1.0 + l1*2.0/(n_plot-1);
340 
341  // Get Lagrangian coordinates
342  el_pt->interpolated_x(s,x);
343 
344  // Output the x,y,..
345  for(unsigned i=0;i<2;i++)
346  {some_file << x[i] << " ";}
347 
348  // Exact vertical displacement
349  double v_exact=Global_Physical_Variables::Gravity*
350  (1.0+nu)*(1.0-2*nu)/(1.0-nu)*(0.5*x[1]*x[1]-x[1]);
351 
352  // x and y displacement
353  some_file << "0.0 " << v_exact << " ";
354 
355  // Stresses
356  sigma(0,0)=nu/(1.0-nu)*Global_Physical_Variables::Gravity*(x[1]-1.0);
357  sigma(1,0)=0.0;
358  sigma(1,1)=Global_Physical_Variables::Gravity*(x[1]-1.0);
359 
360  // Output linear stress tensor
361  some_file << sigma(0,0) << " "
362  << sigma(1,0) << " "
363  << sigma(1,1) << " "
364  << std::endl;
365  }
366  }
367  }
368  some_file.close();
369 
370  // Increment label for output files
371  Doc_info.number()++;
372 
373 } //end doc
374 
375 
376 
377 
378 
379 //==============start_run_it========================================
380 /// Run it
381 //==================================================================
382 template<class ELEMENT>
384  const bool& incompress)
385 {
386 
387  // Set output directory
388  char dirname[100];
389  sprintf(dirname,"RESLT%i",i_case);
390  Doc_info.set_directory(dirname);
391 
392  // Open trace file
393  char filename[100];
394  sprintf(filename,"%s/trace.dat",Doc_info.directory().c_str());
395  Trace_file.open(filename);
396 
397 
398  // Doc initial configuration
399  doc_solution(incompress);
400 
401  // Initial values for parameter values
403 
404  //Parameter incrementation
405  unsigned nstep=1;
406  double g_increment=1.0e-2;
407  for(unsigned i=0;i<nstep;i++)
408  {
409  // Bump up gravity
411 
412  // Solve
413  newton_solve();
414 
415  // Doc solution
416  doc_solution(incompress);
417  }
418 
419 }
420 
421 
422 //=======start_of_main==================================================
423 /// Driver for compressed square
424 //======================================================================
425 int main()
426 {
427 
428  //Flag to indicate if we want the material to be incompressible
429  bool incompress=false;
430 
431  // Label for different cases
432  int case_number=-1;
433 
434  // Generalised Hookean constitutive equations
435  //===========================================
436  {
437  // Nu values
438  Vector<double> nu_value(3);
439  nu_value[0]=0.45;
440  nu_value[1]=0.499999;
441  nu_value[2]=0.5;
442 
443  // Loop over nu values
444  for (unsigned i=0;i<3;i++)
445  {
446  // Set Poisson ratio
447  Global_Physical_Variables::Nu=nu_value[i];
448 
449  std::cout << "===========================================\n";
450  std::cout << "Doing Nu=" << Global_Physical_Variables::Nu
451  << std::endl;
452  std::cout << "===========================================\n";
453 
454  // Create constitutive equation
456  new GeneralisedHookean(&Global_Physical_Variables::Nu);
457 
458  // Displacement-based formulation
459  //--------------------------------
460  // (not for nu=1/2, obviously)
461  if (i!=2)
462  {
463  case_number++;
464  std::cout
465  << "Doing Generalised Hookean with displacement formulation: Case "
466  << case_number << std::endl;
467 
468  //Set up the problem with pure displacement based elements
469  incompress=false;
471  problem(incompress);
472 
473  // Run it
474  problem.run_it(case_number,incompress);
475  }
476 
477 
478  // Generalised Hookean with continuous pressure, compressible
479  //-----------------------------------------------------------
480  {
481  case_number++;
482  std::cout
483  << "Doing Generalised Hookean with displacement/cont pressure "
484  << "formulation: Case " << case_number << std::endl;
485 
486  //Set up the problem with continous pressure/displacement
487  incompress=false;
489  QPVDElementWithContinuousPressure<2> > >
490  problem(incompress);
491 
492  // Run it
493  problem.run_it(case_number,incompress);
494  }
495 
496 
497  // Generalised Hookean with discontinuous pressure, compressible
498  //--------------------------------------------------------------
499  {
500  case_number++;
501  std::cout
502  << "Doing Generalised Hookean with displacement/discont pressure "
503  << "formulation: Case " << case_number << std::endl;
504 
505  //Set up the problem with discontinous pressure/displacement
507  QPVDElementWithPressure<2> > > problem(incompress);
508 
509  // Run it
510  problem.run_it(case_number,incompress);
511  }
512 
513 
514 
515  // Generalised Hookean with continous pressure/displacement;
516  //----------------------------------------------------------
517  // incompressible
518  //---------------
519  {
520  case_number++;
521  std::cout
522  << "Doing Generalised Hookean with displacement/cont pressure, "
523  << "incompressible formulation: Case " << case_number << std::endl;
524 
525  //Set up the problem with continous pressure/displacement
526  incompress=true;
528  QPVDElementWithContinuousPressure<2> > >
529  problem(incompress);
530 
531  // Run it
532  problem.run_it(case_number,incompress);
533  }
534 
535 
536  // Generalised Hookean with discontinous pressure/displacement;
537  //-------------------------------------------------------------
538  // incompressible
539  //---------------
540  {
541  case_number++;
542  std::cout
543  << "Doing Generalised Hookean with displacement/discont pressure, "
544  << "incompressible formulation: Case " << case_number << std::endl;
545 
546  //Set up the problem with discontinous pressure/displacement
547  incompress=true;
549  QPVDElementWithPressure<2> > > problem(incompress);
550 
551  // Run it
552  problem.run_it(case_number,incompress);
553  }
554 
555  // Clean up
558 
559  }
560 
561  } // end generalised Hookean
562 
563 
564  // Incompressible Mooney Rivlin
565  //=============================
566  {
567 
568  // Create strain energy function
570  new MooneyRivlin(&Global_Physical_Variables::C1,
572 
573  // Define a constitutive law (based on strain energy function)
575  new IsotropicStrainEnergyFunctionConstitutiveLaw(
577 
578 
579  // Mooney-Rivlin with continous pressure/displacement;
580  //----------------------------------------------------
581  // incompressible
582  //---------------
583  {
584  case_number++;
585  std::cout
586  << "Doing Mooney Rivlin with cont pressure formulation: Case "
587  << case_number << std::endl;
588 
589  //Set up the problem with continous pressure/displacement
590  incompress=true;
592  QPVDElementWithContinuousPressure<2> > >
593  problem(incompress);
594 
595  // Run it
596  problem.run_it(case_number,incompress);
597  }
598 
599 
600  // Mooney-Rivlin with discontinous pressure/displacement;
601  //-------------------------------------------------------
602  // incompressible
603  //---------------
604  {
605  case_number++;
606  std::cout
607  << "Doing Mooney Rivlin with discont pressure formulation: Case "
608  << case_number << std::endl;
609 
610  //Set up the problem with discontinous pressure/displacement
611  incompress=true;
613  QPVDElementWithPressure<2> > >
614  problem(incompress);
615 
616  // Run it
617  problem.run_it(case_number,incompress);
618  }
619 
620 
621  // Clean up
624 
627 
628  }
629 
630 } //end of main
631 
632 
633 
634 
635 
636 
637 
638 
double Gravity
Non-dim gravity.
void actions_before_newton_solve()
Update function (empty)
Wrapper class for solid element to modify the output.
void doc_solution(const bool &incompress)
Doc the solution & exact (linear) solution for compressible or incompressible materials.
MySolidElement()
Constructor: Call constructor of underlying element.
ConstitutiveLaw * Constitutive_law_pt
Pointer to constitutive law.
Node * Trace_node_pt
Pointers to node whose position we&#39;re tracing.
void actions_after_newton_solve()
Update function (empty)
void gravity(const double &time, const Vector< double > &xi, Vector< double > &b)
Non-dimensional gravity as body force.
ofstream Trace_file
Trace file.
void output(std::ostream &outfile, const unsigned &n_plot)
Overload output function.
void run_it(const int &i_case, const bool &incompress)
Run the job – doc in RESLTi_case.
DocInfo Doc_info
DocInfo object for output.
int main()
Driver for compressed square.
CompressedSquareProblem(const bool &incompress)
Constructor: Pass flag that determines if we want to use a true incompressible formulation.
double C1
First "Mooney Rivlin" coefficient for generalised Mooney Rivlin law.
StrainEnergyFunction * Strain_energy_function_pt
Pointer to strain energy function.
double C2
Second "Mooney Rivlin" coefficient for generalised Mooney Rivlin law.
double Nu
Poisson&#39;s ratio for Hooke&#39;s law.