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