solid_elements.h
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-2022 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 // Header file for general solid mechanics elements
27 
28 // Include guards to prevent multiple inclusion of the header
29 #ifndef OOMPH_ELASTICITY_ELEMENTS_HEADER
30 #define OOMPH_ELASTICITY_ELEMENTS_HEADER
31 
32 // Config header generated by autoconfig
33 #ifdef HAVE_CONFIG_H
34 #include <oomph-lib-config.h>
35 #endif
36 
37 
38 // OOMPH-LIB headers
39 #include "../generic/Qelements.h"
40 #include "../generic/Telements.h"
41 #include "../generic/mesh.h"
42 #include "../generic/hermite_elements.h"
43 #include "../constitutive/constitutive_laws.h"
44 #include "../generic/error_estimator.h"
45 #include "../generic/projection.h"
46 
47 
48 namespace oomph
49 {
50  //=======================================================================
55  //=======================================================================
56  template<unsigned DIM>
57  class PVDEquationsBase : public virtual SolidFiniteElement
58  {
59  private:
63 
64  public:
68  typedef void (*IsotropicGrowthFctPt)(const Vector<double>& xi,
69  double& gamma);
70 
74  typedef double (*PrestressFctPt)(const unsigned& i,
75  const unsigned& j,
76  const Vector<double>& xi);
77 
81  typedef void (*BodyForceFctPt)(const double& t,
82  const Vector<double>& xi,
83  Vector<double>& b);
84 
94  Unsteady(true),
97  {
98  }
99 
102  {
103  return Constitutive_law_pt;
104  }
105 
106 
108  const double& lambda_sq() const
109  {
110  return *Lambda_sq_pt;
111  }
112 
113 
115  double*& lambda_sq_pt()
116  {
117  return Lambda_sq_pt;
118  }
119 
120 
123  {
125  }
126 
129  {
130  return Prestress_fct_pt;
131  }
132 
135  {
137  }
138 
141  {
142  return Body_force_fct_pt;
143  }
144 
147  {
148  return Body_force_fct_pt;
149  }
150 
153  {
154  Unsteady = true;
155  }
156 
159  {
160  Unsteady = false;
161  }
162 
164  bool is_inertia_enabled() const
165  {
166  return Unsteady;
167  }
168 
171  virtual unsigned npres_solid() const
172  {
173  return 0;
174  }
175 
178  virtual int solid_p_local_eqn(const unsigned& i) const
179  {
180  return -1;
181  }
182 
186  virtual int solid_p_nodal_index() const
187  {
189  }
190 
191 
194 
197 
209  const Vector<GeneralisedElement*>& element_pt)
210  {
211  // Loop over all elements
212  unsigned n_element = element_pt.size();
213  for (unsigned e = 0; e < n_element; e++)
214  {
215  dynamic_cast<PVDEquationsBase<DIM>*>(element_pt[e])
217  }
218  }
219 
222  const Vector<GeneralisedElement*>& element_pt)
223  {
224  // Loop over all elements
225  unsigned n_element = element_pt.size();
226  for (unsigned e = 0; e < n_element; e++)
227  {
228  dynamic_cast<PVDEquationsBase<DIM>*>(element_pt[e])
230  }
231  }
232 
237  virtual void get_stress(const Vector<double>& s,
239 
241  void get_strain(const Vector<double>& s, DenseMatrix<double>& strain) const;
242 
244  void get_energy(double& pot_en, double& kin_en);
245 
250  const Vector<double>& s, DenseMatrix<double>& def_covariant_basis);
251 
252 
257  DenseMatrix<double>& principal_stress_vector,
258  Vector<double>& principal_stress);
259 
260 
267  virtual inline void get_isotropic_growth(const unsigned& ipt,
268  const Vector<double>& s,
269  const Vector<double>& xi,
270  double& gamma) const
271  {
272  // If no function has been set, return 1
273  if (Isotropic_growth_fct_pt == 0)
274  {
275  gamma = 1.0;
276  }
277  else
278  {
279  // Get isotropic growth
280  (*Isotropic_growth_fct_pt)(xi, gamma);
281  }
282  }
283 
284 
287  inline void body_force(const Vector<double>& xi, Vector<double>& b) const
288  {
289  // If no function has been set, return zero vector
290  if (Body_force_fct_pt == 0)
291  {
292  // Get spatial dimension of element
293  unsigned n = dim();
294  for (unsigned i = 0; i < n; i++)
295  {
296  b[i] = 0.0;
297  }
298  }
299  else
300  {
301  // Get time from timestepper of first node (note that this must
302  // work -- body force only makes sense for elements that can be
303  // deformed and given that the deformation of solid finite elements
304  // is controlled by their nodes, nodes must exist!)
305  double time = node_pt(0)->time_stepper_pt()->time_pt()->time();
306 
307  // Now evaluate the body force
308  (*Body_force_fct_pt)(time, xi, b);
309  }
310  }
311 
312 
314  unsigned ndof_types() const
315  {
316  return DIM;
317  }
318 
330  std::list<std::pair<unsigned long, unsigned>>& dof_lookup_list) const
331  {
332  // temporary pair (used to store dof lookup prior to being added to list
333  std::pair<unsigned, unsigned> dof_lookup;
334 
335  // number of nodes
336  const unsigned n_node = this->nnode();
337 
338  // Get the number of position dofs and dimensions at the node
339  const unsigned n_position_type = nnodal_position_type();
340  const unsigned nodal_dim = nodal_dimension();
341 
342  // Integer storage for local unknown
343  int local_unknown = 0;
344 
345  // Loop over the nodes
346  for (unsigned n = 0; n < n_node; n++)
347  {
348  // Loop over position dofs
349  for (unsigned k = 0; k < n_position_type; k++)
350  {
351  // Loop over dimension
352  for (unsigned i = 0; i < nodal_dim; i++)
353  {
354  // If the variable is free
355  local_unknown = position_local_eqn(n, k, i);
356 
357  // ignore pinned values
358  if (local_unknown >= 0)
359  {
360  // store dof lookup in temporary pair: First entry in pair
361  // is global equation number; second entry is dof type
362  dof_lookup.first = this->eqn_number(local_unknown);
363  dof_lookup.second = i;
364 
365  // add to list
366  dof_lookup_list.push_front(dof_lookup);
367  }
368  }
369  }
370  }
371  }
372 
375  {
377  }
378 
381  {
382  Evaluate_jacobian_by_fd = false;
383  }
384 
387  {
389  }
390 
393  double prestress(const unsigned& i,
394  const unsigned& j,
395  const Vector<double> xi)
396  {
397  if (Prestress_fct_pt == 0)
398  {
399  return 0.0;
400  }
401  else
402  {
403  return (*Prestress_fct_pt)(i, j, xi);
404  }
405  }
406 
407  protected:
410 
413 
416 
418  double* Lambda_sq_pt;
419 
421  bool Unsteady;
422 
425 
427  static double Default_lambda_sq_value;
428 
431  };
432 
433 
434  //=======================================================================
437  //=======================================================================
438  template<unsigned DIM>
439  class PVDEquations : public virtual PVDEquationsBase<DIM>
440  {
441  public:
444 
448 
452  {
454  residuals, GeneralisedElement::Dummy_matrix, 0);
455  }
456 
460  DenseMatrix<double>& jacobian)
461  {
462  // Solve for the consistent acceleration in Newmark scheme?
464  {
465  // Add the contribution to the residuals -- these are the
466  // full residuals of whatever solid equations we're solving
467  this->fill_in_contribution_to_residuals(residuals);
468 
469  // Jacobian is not the Jacobian associated with these
470  // residuals (treating the postions as unknowns)
471  // but the derivatives w.r.t. to the discrete generalised
472  // accelerations in the Newmark scheme -- the Jacobian
473  // is therefore the associated mass matrix, multiplier
474  // by suitable scaling factors
475  this->fill_in_jacobian_for_newmark_accel(jacobian);
476  return;
477  }
478 
479  // Are we assigning a solid initial condition?
480  if (this->Solid_ic_pt != 0)
481  {
482  this->fill_in_jacobian_for_solid_ic(residuals, jacobian);
483  return;
484  }
485 
486 
487  // Use FD
488  if ((this->Evaluate_jacobian_by_fd))
489  {
490  // Add the contribution to the residuals from this element
492  residuals, GeneralisedElement::Dummy_matrix, 0);
493 
494  // Get the solid entries in the jacobian using finite differences
496  }
497  // Do it analytically
498  else
499  {
500  fill_in_generic_contribution_to_residuals_pvd(residuals, jacobian, 1);
501  }
502  }
503 
504 
506  void output(std::ostream& outfile)
507  {
508  unsigned n_plot = 5;
509  output(outfile, n_plot);
510  }
511 
513  void output(std::ostream& outfile, const unsigned& n_plot);
514 
515 
517  void output(FILE* file_pt)
518  {
519  unsigned n_plot = 5;
520  output(file_pt, n_plot);
521  }
522 
524  void output(FILE* file_pt, const unsigned& n_plot);
525 
526 
529  void extended_output(std::ostream& outfile, const unsigned& n_plot);
530 
531 
532  protected:
536  Vector<double>& residuals,
537  DenseMatrix<double>& jacobian,
538  const unsigned& flag);
539 
543  inline void get_stress(const DenseMatrix<double>& g,
544  const DenseMatrix<double>& G,
546  {
547 #ifdef PARANOID
548  // If the pointer to the constitutive law hasn't been set, issue an error
549  if (this->Constitutive_law_pt == 0)
550  {
551  // Write an error message
552  std::string error_message =
553  "Elements derived from PVDEquations must have a constitutive law:\n";
554  error_message +=
555  "set one using the constitutive_law_pt() member function";
556  // Throw the error
557  throw OomphLibError(
559  }
560 #endif
562  g, G, sigma);
563  }
564 
570  const DenseMatrix<double>& G,
571  const DenseMatrix<double>& sigma,
572  RankFourTensor<double>& d_sigma_dG)
573  {
574 #ifdef PARANOID
575  // If the pointer to the constitutive law hasn't been set, issue an error
576  if (this->Constitutive_law_pt == 0)
577  {
578  // Write an error message
579  std::string error_message =
580  "Elements derived from PVDEquations must have a constitutive law:\n";
581  error_message +=
582  "set one using the constitutive_law_pt() member function";
583  // Throw the error
584  throw OomphLibError(
586  }
587 #endif
588  // Only bother with the symmetric part by passing false as last entry
590  g, G, sigma, d_sigma_dG, false);
591  }
592 
593 
594  private:
597  };
598 
599 
600  //===========================================================================
604  //============================================================================
605  template<unsigned DIM, unsigned NNODE_1D>
606  class QPVDElement : public virtual SolidQElement<DIM, NNODE_1D>,
607  public virtual PVDEquations<DIM>
608  {
609  public:
611  QPVDElement() : SolidQElement<DIM, NNODE_1D>(), PVDEquations<DIM>() {}
612 
614  void output(std::ostream& outfile)
615  {
616  PVDEquations<DIM>::output(outfile);
617  }
618 
620  void output(std::ostream& outfile, const unsigned& n_plot)
621  {
622  PVDEquations<DIM>::output(outfile, n_plot);
623  }
624 
625 
627  void output(FILE* file_pt)
628  {
629  PVDEquations<DIM>::output(file_pt);
630  }
631 
633  void output(FILE* file_pt, const unsigned& n_plot)
634  {
635  PVDEquations<DIM>::output(file_pt, n_plot);
636  }
637  };
638 
639 
640  //============================================================================
642  //============================================================================
643  template<unsigned NNODE_1D>
644  class FaceGeometry<QPVDElement<2, NNODE_1D>>
645  : public virtual SolidQElement<1, NNODE_1D>
646  {
647  public:
649  FaceGeometry() : SolidQElement<1, NNODE_1D>() {}
650  };
651 
652 
653  //==============================================================
655  //==============================================================
656  template<unsigned NNODE_1D>
657  class FaceGeometry<FaceGeometry<QPVDElement<2, NNODE_1D>>>
658  : public virtual PointElement
659  {
660  public:
661  // Make sure that we call the constructor of the SolidQElement
662  // Only the Intel compiler seems to need this!
664  };
665 
666 
667  //============================================================================
669  //============================================================================
670  template<unsigned NNODE_1D>
671  class FaceGeometry<QPVDElement<3, NNODE_1D>>
672  : public virtual SolidQElement<2, NNODE_1D>
673  {
674  public:
676  FaceGeometry() : SolidQElement<2, NNODE_1D>() {}
677  };
678 
679  //============================================================================
681  //============================================================================
682  template<unsigned NNODE_1D>
683  class FaceGeometry<FaceGeometry<QPVDElement<3, NNODE_1D>>>
684  : public virtual SolidQElement<1, NNODE_1D>
685  {
686  public:
688  FaceGeometry() : SolidQElement<1, NNODE_1D>() {}
689  };
690 
691  //===========================================================================
694  //============================================================================
695  template<unsigned DIM>
696  class HermitePVDElement : public virtual SolidQHermiteElement<DIM>,
697  public virtual PVDEquations<DIM>
698  {
699  public:
702 
704  void output(std::ostream& outfile)
705  {
707  }
708 
710  void output(std::ostream& outfile, const unsigned& n_plot)
711  {
712  SolidQHermiteElement<DIM>::output(outfile, n_plot);
713  }
714 
716  void output(FILE* file_pt)
717  {
719  }
720 
722  void output(FILE* file_pt, const unsigned& n_plot)
723  {
724  SolidQHermiteElement<DIM>::output(file_pt, n_plot);
725  }
726  };
727 
728 
729  //==========================================================
731  //==========================================================
732  template<class PVD_ELEMENT>
733  class ProjectablePVDElement : public virtual ProjectableElement<PVD_ELEMENT>
734  {
735  public:
739 
740 
746  {
747  // Create the vector
749 
750  // Loop over all vertex nodes
751  // const unsigned n_solid_pres=this->npres_solid();
752  // for(unsigned j=0;j<n_solid_pres;j++)
753  // {
754  // // Add the data value associated with the pressure components
755  // unsigned vertex_index=this->Pconv[j];
756  // data_values.push_back(std::make_pair(this->node_pt(vertex_index),0));
757  // }
758 
759  // Return the vector
760  return data_values;
761  }
762 
765  {
766  return 0;
767  }
768 
771  unsigned nhistory_values_for_projection(const unsigned& fld)
772  {
773  return 0;
774  }
775 
778  {
779  return this->node_pt(0)->position_time_stepper_pt()->ntstorage();
780  }
781 
784  double jacobian_and_shape_of_field(const unsigned& fld,
785  const Vector<double>& s,
786  Shape& psi)
787  {
788  // Return the Jacobian of the eulerian mapping
789  return this->J_eulerian(s);
790  }
791 
794  double get_field(const unsigned& t,
795  const unsigned& fld,
796  const Vector<double>& s)
797  {
798  // Dummy return
799  return 0.0;
800  }
801 
802 
804  unsigned nvalue_of_field(const unsigned& fld)
805  {
806  return 0;
807  }
808 
809 
811  int local_equation(const unsigned& fld, const unsigned& j)
812  {
813  return -1;
814  }
815  };
816 
817 
818  //=======================================================================
821  //=======================================================================
822  template<class ELEMENT>
824  : public virtual FaceGeometry<ELEMENT>
825  {
826  public:
827  FaceGeometry() : FaceGeometry<ELEMENT>() {}
828  };
829 
830 
831  //=======================================================================
834  //=======================================================================
835  template<class ELEMENT>
837  : public virtual FaceGeometry<FaceGeometry<ELEMENT>>
838  {
839  public:
841  };
842 
843 
847 
848 
849  //=========================================================================
858  //============================================================================
859  template<unsigned DIM>
861  : public virtual PVDEquationsBase<DIM>,
863  {
864  public:
867  {
868  }
869 
873 
875  bool is_incompressible() const
876  {
877  return Incompressible;
878  }
879 
882  {
883  Incompressible = true;
884  }
885 
888  {
889  Incompressible = false;
890  }
891 
893  virtual double solid_p(const unsigned& l) = 0;
894 
896  virtual void set_solid_p(const unsigned& l, const double& p_value) = 0;
897 
900  {
901  // Call the generic residuals function with flag set to 0
902  // using a dummy matrix argument
904  residuals,
907  0);
908  }
909 
915  DenseMatrix<double>& jacobian)
916  {
917  // Solve for the consistent acceleration in the Newmark scheme
918  // Note that this replaces solid entries only
920  (this->Solid_ic_pt != 0))
921  {
922  std::string error_message = "Can't assign consistent Newmark history\n";
923  error_message += " values for solid element with pressure dofs\n";
924 
925  throw OomphLibError(
927  }
928 
929  // FD
930  if (this->Evaluate_jacobian_by_fd)
931  {
932  // Call the generic routine with the flag set to 2: Computes residuals
933  // and derivatives w.r.t. to pressure variables
935  residuals, jacobian, GeneralisedElement::Dummy_matrix, 2);
936 
937  // Call the finite difference routine for the deriatives w.r.t.
938  // the positional variables
940  }
941  // Do it fully analytically
942  else
943  {
944  // Call the generic routine with the flag set to 1: Get residual
945  // and fully analytical Jacobian
947  residuals, jacobian, GeneralisedElement::Dummy_matrix, 1);
948  }
949  }
950 
959  Vector<double>& residuals,
960  DenseMatrix<double>& jacobian,
961  DenseMatrix<double>& mass_matrix)
962  {
963  // Solve for the consistent acceleration in the Newmark scheme
964  // Note that this replaces solid entries only
966  (this->Solid_ic_pt != 0))
967  {
968  std::string error_message = "Can't assign consistent Newmark history\n";
969  error_message += " values for solid element with pressure dofs\n";
970 
971  throw OomphLibError(
973  }
974 
975  // FD
976  if (this->Evaluate_jacobian_by_fd)
977  {
978  // Call the generic routine with the flag set to 4: Computes residuals
979  // and derivatives w.r.t. to pressure variables
980  // and the mass matrix
982  residuals, jacobian, mass_matrix, 4);
983 
984  // Call the finite difference routine for the deriatives w.r.t.
985  // the positional variables
987  }
988  // Do it fully analytically
989  else
990  {
991  // Call the generic routine with the flag set to 3: Get residual
992  // and fully analytical Jacobian
994  residuals, jacobian, mass_matrix, 3);
995  }
996 
997  // Multiply the residuals and jacobian by minus one
998  const unsigned n_dof = this->ndof();
999  for (unsigned i = 0; i < n_dof; i++)
1000  {
1001  residuals[i] *= -1.0;
1002  for (unsigned j = 0; j < n_dof; j++)
1003  {
1004  jacobian(i, j) *= -1.0;
1005  }
1006  }
1007  }
1008 
1009 
1012  {
1013  // Find number of nodes
1014  unsigned n_solid_pres = this->npres_solid();
1015  // Local shape function
1016  Shape psisp(n_solid_pres);
1017  // Find values of shape function
1018  solid_pshape(s, psisp);
1019 
1020  // Initialise value of solid_p
1021  double interpolated_solid_p = 0.0;
1022  // Loop over the local nodes and sum
1023  for (unsigned l = 0; l < n_solid_pres; l++)
1024  {
1025  interpolated_solid_p += solid_p(l) * psisp[l];
1026  }
1027 
1028  return (interpolated_solid_p);
1029  }
1030 
1031 
1033  void output(std::ostream& outfile)
1034  {
1035  unsigned n_plot = 5;
1036  output(outfile, n_plot);
1037  }
1038 
1040  void output(std::ostream& outfile, const unsigned& n_plot);
1041 
1042 
1044  void output(FILE* file_pt)
1045  {
1046  unsigned n_plot = 5;
1047  output(file_pt, n_plot);
1048  }
1049 
1051  void output(FILE* file_pt, const unsigned& n_plot);
1052 
1055  void extended_output(std::ostream& outfile, const unsigned& n_plot);
1056 
1057 
1060  void get_mass_matrix_diagonal(Vector<double>& mass_diag);
1061 
1064  unsigned ndof_types() const
1065  {
1066  return DIM + 1;
1067  }
1068 
1078  std::list<std::pair<unsigned long, unsigned>>& dof_lookup_list) const
1079  {
1080  // temporary pair (used to store dof lookup prior to being added to list
1081  std::pair<unsigned, unsigned> dof_lookup;
1082 
1083  // number of nodes
1084  const unsigned n_node = this->nnode();
1085 
1086  // Get the number of position dofs and dimensions at the node
1087  const unsigned n_position_type = this->nnodal_position_type();
1088  const unsigned nodal_dim = this->nodal_dimension();
1089 
1090  // Integer storage for local unknown
1091  int local_unknown = 0;
1092 
1093  // Loop over the nodes
1094  for (unsigned n = 0; n < n_node; n++)
1095  {
1096  // Loop over position dofs
1097  for (unsigned k = 0; k < n_position_type; k++)
1098  {
1099  // Loop over dimension
1100  for (unsigned i = 0; i < nodal_dim; i++)
1101  {
1102  // If the variable is free
1103  local_unknown = this->position_local_eqn(n, k, i);
1104 
1105  // ignore pinned values
1106  if (local_unknown >= 0)
1107  {
1108  // store dof lookup in temporary pair: First entry in pair
1109  // is global equation number; second entry is dof type
1110  dof_lookup.first = this->eqn_number(local_unknown);
1111  dof_lookup.second = i;
1112 
1113  // add to list
1114  dof_lookup_list.push_front(dof_lookup);
1115  }
1116  }
1117  }
1118  }
1119 
1120  // Do solid pressure degrees of freedom
1121  unsigned np = this->npres_solid();
1122  for (unsigned j = 0; j < np; j++)
1123  {
1124  int local_unknown = this->solid_p_local_eqn(j);
1125  // ignore pinned values
1126  if (local_unknown >= 0)
1127  {
1128  // store dof lookup in temporary pair: First entry in pair
1129  // is global equation number; second entry is dof type
1130  dof_lookup.first = this->eqn_number(local_unknown);
1131  dof_lookup.second = DIM;
1132 
1133  // add to list
1134  dof_lookup_list.push_front(dof_lookup);
1135  }
1136  }
1137  }
1138 
1139  protected:
1145  inline void get_stress(const DenseMatrix<double>& g,
1146  const DenseMatrix<double>& G,
1147  DenseMatrix<double>& sigma_dev,
1148  DenseMatrix<double>& Gcontra,
1149  double& gen_dil,
1150  double& inv_kappa)
1151  {
1152 #ifdef PARANOID
1153  // If the pointer to the constitutive law hasn't been set, issue an error
1154  if (this->Constitutive_law_pt == 0)
1155  {
1156  // Write an error message
1157  std::string error_message =
1158  "Elements derived from PVDEquationsWithPressure \n";
1159  error_message += "must have a constitutive law:\n";
1160  error_message +=
1161  "set one using the constitutive_law_pt() member function";
1162  // Throw the error
1163  throw OomphLibError(
1165  }
1166 #endif
1168  g, G, sigma_dev, Gcontra, gen_dil, inv_kappa);
1169  }
1170 
1171 
1178  const DenseMatrix<double>& G,
1179  const DenseMatrix<double>& sigma,
1180  const double& gen_dil,
1181  const double& inv_kappa,
1182  const double& interpolated_solid_p,
1183  RankFourTensor<double>& d_sigma_dG,
1184  DenseMatrix<double>& d_gen_dil_dG)
1185 
1186  {
1187 #ifdef PARANOID
1188  // If the pointer to the constitutive law hasn't been set, issue an error
1189  if (this->Constitutive_law_pt == 0)
1190  {
1191  // Write an error message
1192  std::string error_message =
1193  "Elements derived from PVDEquationsWithPressure \n";
1194  error_message += "must have a constitutive law:\n";
1195  error_message +=
1196  "set one using the constitutive_law_pt() member function";
1197  // Throw the error
1198  throw OomphLibError(
1200  }
1201 #endif
1202  // Only bother with the symmetric part by passing false as last entry
1204  g,
1205  G,
1206  sigma,
1207  gen_dil,
1208  inv_kappa,
1210  d_sigma_dG,
1211  d_gen_dil_dG,
1212  false);
1213  }
1214 
1215 
1217  virtual void solid_pshape(const Vector<double>& s, Shape& psi) const = 0;
1218 
1220  void solid_pshape_at_knot(const unsigned& ipt, Shape& psi) const
1221  {
1222  // Find the dimension of the element
1223  unsigned Dim = this->dim();
1224  // Storage for local coordinates of the integration point
1225  Vector<double> s(Dim);
1226  // Set the local coordinates
1227  for (unsigned i = 0; i < Dim; i++)
1228  {
1229  s[i] = this->integral_pt()->knot(ipt, i);
1230  }
1231  // Get the shape function
1232  solid_pshape(s, psi);
1233  }
1234 
1235  protected:
1238 
1247  Vector<double>& residuals,
1248  DenseMatrix<double>& jacobian,
1249  DenseMatrix<double>& mass_matrix,
1250  const unsigned& flag);
1251 
1258  inline void get_stress(const DenseMatrix<double>& g,
1259  const DenseMatrix<double>& G,
1260  DenseMatrix<double>& sigma_dev,
1261  DenseMatrix<double>& Gcontra,
1262  double& detG)
1263  {
1264 #ifdef PARANOID
1265  // If the pointer to the constitutive law hasn't been set, issue an error
1266  if (this->Constitutive_law_pt == 0)
1267  {
1268  // Write an error message
1269  std::string error_message =
1270  "Elements derived from PVDEquationsWithPressure \n";
1271  error_message += "must have a constitutive law:\n";
1272  error_message +=
1273  "set one using the constitutive_law_pt() member function";
1274  // Throw the error
1275  throw OomphLibError(
1277  }
1278 #endif
1280  g, G, sigma_dev, Gcontra, detG);
1281  }
1282 
1289  const DenseMatrix<double>& G,
1290  const DenseMatrix<double>& sigma,
1291  const double& detG,
1292  const double& interpolated_solid_p,
1293  RankFourTensor<double>& d_sigma_dG,
1294  DenseMatrix<double>& d_detG_dG)
1295  {
1296 #ifdef PARANOID
1297  // If the pointer to the constitutive law hasn't been set, issue an error
1298  if (this->Constitutive_law_pt == 0)
1299  {
1300  // Write an error message
1301  std::string error_message =
1302  "Elements derived from PVDEquationsWithPressure \n";
1303  error_message += "must have a constitutive law:\n";
1304  error_message +=
1305  "set one using the constitutive_law_pt() member function";
1306  // Throw the error
1307  throw OomphLibError(
1309  }
1310 #endif
1311  // Only bother with the symmetric part by passing false as last entry
1313  g, G, sigma, detG, interpolated_solid_p, d_sigma_dG, d_detG_dG, false);
1314  }
1315  };
1316 
1317 
1321 
1322 
1323  //===========================================================================
1328  //============================================================================
1329  template<unsigned DIM>
1330  class QPVDElementWithPressure : public virtual SolidQElement<DIM, 3>,
1331  public virtual PVDEquationsWithPressure<DIM>
1332  {
1335  {
1336  unsigned n_pres = this->npres_solid();
1337  // loop over pressure dofs and unpin them
1338  for (unsigned l = 0; l < n_pres; l++)
1339  {
1341  }
1342  }
1343 
1344  protected:
1348 
1352  inline int solid_p_local_eqn(const unsigned& i) const
1353  {
1354  return this->internal_local_eqn(P_solid_internal_index, i);
1355  }
1356 
1358  inline void solid_pshape(const Vector<double>& s, Shape& psi) const;
1359 
1360  public:
1364  {
1365  return true;
1366  }
1367 
1371  {
1372  // Allocate and add one Internal data object that stores DIM+1 pressure
1373  // values
1375  }
1376 
1378  double solid_p(const unsigned& l)
1379  {
1380  return this->internal_data_pt(P_solid_internal_index)->value(l);
1381  }
1382 
1384  void set_solid_p(const unsigned& l, const double& p_value)
1385  {
1386  this->internal_data_pt(P_solid_internal_index)->set_value(l, p_value);
1387  }
1388 
1390  unsigned npres_solid() const
1391  {
1392  return DIM + 1;
1393  }
1394 
1396  void fix_solid_pressure(const unsigned& l, const double& pvalue)
1397  {
1398  this->internal_data_pt(P_solid_internal_index)->pin(l);
1399  this->internal_data_pt(P_solid_internal_index)->set_value(l, pvalue);
1400  }
1401 
1403  void output(std::ostream& outfile)
1404  {
1405  FiniteElement::output(outfile);
1406  }
1407 
1409  void output(std::ostream& outfile, const unsigned& n_plot)
1410  {
1411  PVDEquationsWithPressure<DIM>::output(outfile, n_plot);
1412  }
1413 
1414 
1416  void output(FILE* file_pt)
1417  {
1418  FiniteElement::output(file_pt);
1419  }
1420 
1422  void output(FILE* file_pt, const unsigned& n_plot)
1423  {
1424  PVDEquationsWithPressure<DIM>::output(file_pt, n_plot);
1425  }
1426  };
1427 
1428 
1429  //=====================================================================
1431  //=====================================================================
1432  template<>
1434  Shape& psi) const
1435  {
1436  psi[0] = 1.0;
1437  psi[1] = s[0];
1438  psi[2] = s[1];
1439  }
1440 
1441 
1442  //=====================================================================
1444  //=====================================================================
1445  template<>
1447  Shape& psi) const
1448  {
1449  psi[0] = 1.0;
1450  psi[1] = s[0];
1451  psi[2] = s[1];
1452  psi[3] = s[2];
1453  }
1454 
1455 
1456  //======================================================================
1458  //======================================================================
1459  template<>
1461  : public virtual SolidQElement<1, 3>
1462  {
1463  public:
1466  };
1467 
1468 
1469  //======================================================================
1471  //======================================================================
1472  template<>
1474  : public virtual PointElement
1475  {
1476  public:
1479  };
1480 
1481  //======================================================================
1483  //======================================================================
1484  template<>
1486  : public virtual SolidQElement<2, 3>
1487  {
1488  public:
1491  };
1492 
1493 
1494  //======================================================================
1496  //======================================================================
1497  template<>
1499  : public virtual SolidQElement<1, 3>
1500  {
1501  public:
1504  };
1505 
1506 
1510 
1511 
1512  //===========================================================================
1518  //============================================================================
1519  template<unsigned DIM>
1521  : public virtual SolidQElement<DIM, 3>,
1522  public virtual PVDEquationsWithPressure<DIM>
1523  {
1524  private:
1527  static const unsigned Initial_Nvalue[];
1528 
1531  {
1532  // find the index at which the pressure is stored
1533  int p_index = this->solid_p_nodal_index();
1534  unsigned n_node = this->nnode();
1535  // loop over nodes
1536  for (unsigned n = 0; n < n_node; n++)
1537  {
1538  this->node_pt(n)->unpin(p_index);
1539  }
1540  }
1541 
1542  protected:
1545  static const unsigned Pconv[];
1546 
1550  inline int solid_p_local_eqn(const unsigned& i) const
1551  {
1552  return this->nodal_local_eqn(Pconv[i], this->solid_p_nodal_index());
1553  }
1554 
1556  inline void solid_pshape(const Vector<double>& s, Shape& psi) const;
1557 
1558  public:
1562  {
1563  }
1564 
1566  inline int solid_p_nodal_index() const
1567  {
1568  return 0;
1569  }
1570 
1573  inline virtual unsigned required_nvalue(const unsigned& n) const
1574  {
1575  return Initial_Nvalue[n];
1576  }
1577 
1580  double solid_p(const unsigned& l)
1581  {
1582  return this->nodal_value(Pconv[l], this->solid_p_nodal_index());
1583  }
1584 
1586  void set_solid_p(const unsigned& l, const double& p_value)
1587  {
1588  this->node_pt(Pconv[l])->set_value(this->solid_p_nodal_index(), p_value);
1589  }
1590 
1592  unsigned npres_solid() const
1593  {
1594  return static_cast<unsigned>(pow(2.0, static_cast<int>(DIM)));
1595  }
1596 
1598  void fix_solid_pressure(const unsigned& l, const double& pvalue)
1599  {
1600  this->node_pt(Pconv[l])->pin(this->solid_p_nodal_index());
1601  this->node_pt(Pconv[l])->set_value(this->solid_p_nodal_index(), pvalue);
1602  }
1603 
1605  void output(std::ostream& outfile)
1606  {
1607  FiniteElement::output(outfile);
1608  }
1609 
1611  void output(std::ostream& outfile, const unsigned& n_plot)
1612  {
1613  PVDEquationsWithPressure<DIM>::output(outfile, n_plot);
1614  }
1615 
1616 
1618  void output(FILE* file_pt)
1619  {
1620  FiniteElement::output(file_pt);
1621  }
1622 
1624  void output(FILE* file_pt, const unsigned& n_plot)
1625  {
1626  PVDEquationsWithPressure<DIM>::output(file_pt, n_plot);
1627  }
1628  };
1629 
1630 
1631  //===============================================================
1634  //===============================================================
1635  template<>
1637  const Vector<double>& s, Shape& psi) const
1638  {
1639  // Local storage
1640  double psi1[2], psi2[2];
1641  // Call the OneDimensional Shape functions
1642  OneDimLagrange::shape<2>(s[0], psi1);
1643  OneDimLagrange::shape<2>(s[1], psi2);
1644 
1645  // Now let's loop over the nodal points in the element
1646  // s1 is the "x" coordinate, s2 the "y"
1647  for (unsigned i = 0; i < 2; i++)
1648  {
1649  for (unsigned j = 0; j < 2; j++)
1650  {
1651  /*Multiply the two 1D functions together to get the 2D function*/
1652  psi[2 * i + j] = psi2[i] * psi1[j];
1653  }
1654  }
1655  }
1656 
1657  //===============================================================
1660  //===============================================================
1661  template<>
1663  const Vector<double>& s, Shape& psi) const
1664  {
1665  // Local storage
1666  double psi1[2], psi2[2], psi3[2];
1667  // Call the OneDimensional Shape functions
1668  OneDimLagrange::shape<2>(s[0], psi1);
1669  OneDimLagrange::shape<2>(s[1], psi2);
1670  OneDimLagrange::shape<2>(s[2], psi3);
1671 
1672  // Now let's loop over the nodal points in the element
1673  // s1 is the "x" coordinate, s2 the "y"
1674  for (unsigned i = 0; i < 2; i++)
1675  {
1676  for (unsigned j = 0; j < 2; j++)
1677  {
1678  for (unsigned k = 0; k < 2; k++)
1679  {
1680  /*Multiply the two 1D functions together to get the 3D function*/
1681  psi[4 * i + 2 * j + k] = psi3[i] * psi2[j] * psi1[k];
1682  }
1683  }
1684  }
1685  }
1686 
1687 
1688  //===============================================================
1690  //===============================================================
1691  template<>
1693  : public virtual SolidQElement<1, 3>
1694  {
1695  public:
1698  };
1699 
1700 
1701  //===============================================================
1704  //===============================================================
1705  template<>
1707  : public virtual PointElement
1708  {
1709  public:
1712  };
1713 
1714 
1715  //===============================================================
1717  //===============================================================
1718  template<>
1720  : public virtual SolidQElement<2, 3>
1721  {
1722  public:
1725  };
1726 
1727 
1728  //===============================================================
1731  //===============================================================
1732  template<>
1734  : public virtual SolidQElement<1, 3>
1735  {
1736  public:
1739  };
1740 
1741 
1745 
1746 
1747  //===========================================================================
1751  //============================================================================
1752  template<unsigned DIM, unsigned NNODE_1D>
1753  class TPVDElement : public virtual SolidTElement<DIM, NNODE_1D>,
1754  public virtual PVDEquations<DIM>,
1755  public virtual ElementWithZ2ErrorEstimator
1756  {
1757  public:
1760 
1762  void output(std::ostream& outfile)
1763  {
1764  PVDEquations<DIM>::output(outfile);
1765  }
1766 
1768  void output(std::ostream& outfile, const unsigned& n_plot)
1769  {
1770  PVDEquations<DIM>::output(outfile, n_plot);
1771  }
1772 
1773 
1775  void output(FILE* file_pt)
1776  {
1777  PVDEquations<DIM>::output(file_pt);
1778  }
1779 
1781  void output(FILE* file_pt, const unsigned& n_plot)
1782  {
1783  PVDEquations<DIM>::output(file_pt, n_plot);
1784  }
1785 
1788  unsigned nrecovery_order()
1789  {
1790  return (NNODE_1D - 1);
1791  }
1792 
1794  unsigned nvertex_node() const
1795  {
1797  }
1798 
1800  Node* vertex_node_pt(const unsigned& j) const
1801  {
1803  }
1804 
1814 
1817  {
1818  // DIM Diagonal strain rates and DIM*(DIM-1)/2 off diagonal terms
1819  return DIM + DIM * (DIM - 1) / 2;
1820  }
1821 
1825  {
1826 #ifdef PARANOID
1827  unsigned num_entries = DIM + ((DIM * DIM) - DIM) / 2;
1828  if (flux.size() != num_entries)
1829  {
1830  std::ostringstream error_message;
1831  error_message << "The flux vector has the wrong number of entries, "
1832  << flux.size() << ", whereas it should be " << num_entries
1833  << std::endl;
1834  throw OomphLibError(error_message.str(),
1837  }
1838 #endif
1839 
1840  // Get strain matrix
1841  DenseMatrix<double> strain(DIM);
1842  this->get_strain(s, strain);
1843 
1844  // Pack into flux Vector
1845  unsigned icount = 0;
1846 
1847  // Start with diagonal terms
1848  for (unsigned i = 0; i < DIM; i++)
1849  {
1850  flux[icount] = strain(i, i);
1851  icount++;
1852  }
1853  // Off diagonals row by row
1854  for (unsigned i = 0; i < DIM; i++)
1855  {
1856  for (unsigned j = i + 1; j < DIM; j++)
1857  {
1858  flux[icount] = strain(i, j);
1859  icount++;
1860  }
1861  }
1862  }
1863  };
1864 
1865 
1866  //============================================================================
1868  //============================================================================
1869  template<unsigned NNODE_1D>
1870  class FaceGeometry<TPVDElement<2, NNODE_1D>>
1871  : public virtual SolidTElement<1, NNODE_1D>
1872  {
1873  public:
1875  FaceGeometry() : SolidTElement<1, NNODE_1D>() {}
1876  };
1877 
1878 
1879  //==============================================================
1881  //==============================================================
1882  template<unsigned NNODE_1D>
1884  : public virtual PointElement
1885  {
1886  public:
1887  // Make sure that we call the constructor of the SolidQElement
1888  // Only the Intel compiler seems to need this!
1890  };
1891 
1892 
1893  //============================================================================
1895  //============================================================================
1896  template<unsigned NNODE_1D>
1897  class FaceGeometry<TPVDElement<3, NNODE_1D>>
1898  : public virtual SolidTElement<2, NNODE_1D>
1899  {
1900  public:
1902  FaceGeometry() : SolidTElement<2, NNODE_1D>() {}
1903  };
1904 
1905  //============================================================================
1907  //============================================================================
1908  template<unsigned NNODE_1D>
1910  : public virtual SolidTElement<1, NNODE_1D>
1911  {
1912  public:
1914  FaceGeometry() : SolidTElement<1, NNODE_1D>() {}
1915  };
1916 
1917 
1921 
1922  //===========================================================================
1929  //============================================================================
1930  template<unsigned DIM, unsigned NNODE_1D>
1932  : public virtual SolidTBubbleEnrichedElement<DIM, NNODE_1D>,
1933  public virtual PVDEquations<DIM>,
1934  public virtual ElementWithZ2ErrorEstimator
1935  {
1936  public:
1939  : SolidTBubbleEnrichedElement<DIM, NNODE_1D>(), PVDEquations<DIM>()
1940  {
1941  }
1942 
1944  void output(std::ostream& outfile)
1945  {
1946  PVDEquations<DIM>::output(outfile);
1947  }
1948 
1950  void output(std::ostream& outfile, const unsigned& n_plot)
1951  {
1952  PVDEquations<DIM>::output(outfile, n_plot);
1953  }
1954 
1955 
1957  void output(FILE* file_pt)
1958  {
1959  PVDEquations<DIM>::output(file_pt);
1960  }
1961 
1963  void output(FILE* file_pt, const unsigned& n_plot)
1964  {
1965  PVDEquations<DIM>::output(file_pt, n_plot);
1966  }
1967 
1968 
1971  unsigned nrecovery_order()
1972  {
1973  return (NNODE_1D - 1);
1974  }
1975 
1977  unsigned nvertex_node() const
1978  {
1980  }
1981 
1983  Node* vertex_node_pt(const unsigned& j) const
1984  {
1986  }
1987 
1990  {
1991  // DIM Diagonal strain rates and DIM*(DIM-1)/2 off diagonal terms
1992  return DIM + DIM * (DIM - 1) / 2;
1993  }
1994 
1998  {
1999 #ifdef PARANOID
2000  unsigned num_entries = DIM + ((DIM * DIM) - DIM) / 2;
2001  if (flux.size() != num_entries)
2002  {
2003  std::ostringstream error_message;
2004  error_message << "The flux vector has the wrong number of entries, "
2005  << flux.size() << ", whereas it should be " << num_entries
2006  << std::endl;
2007  throw OomphLibError(error_message.str(),
2010  }
2011 #endif
2012 
2013  // Get strain matrix
2014  DenseMatrix<double> strain(DIM);
2015  this->get_strain(s, strain);
2016 
2017  // Pack into flux Vector
2018  unsigned icount = 0;
2019 
2020  // Start with diagonal terms
2021  for (unsigned i = 0; i < DIM; i++)
2022  {
2023  flux[icount] = strain(i, i);
2024  icount++;
2025  }
2026  // Off diagonals row by row
2027  for (unsigned i = 0; i < DIM; i++)
2028  {
2029  for (unsigned j = i + 1; j < DIM; j++)
2030  {
2031  flux[icount] = strain(i, j);
2032  icount++;
2033  }
2034  }
2035  }
2036  };
2037 
2038 
2039  //============================================================================
2041  //============================================================================
2042  template<unsigned NNODE_1D>
2044  : public virtual SolidTElement<1, NNODE_1D>
2045  {
2046  public:
2048  FaceGeometry() : SolidTElement<1, NNODE_1D>() {}
2049  };
2050 
2051 
2052  //==============================================================
2054  //==============================================================
2055  template<unsigned NNODE_1D>
2057  : public virtual PointElement
2058  {
2059  public:
2060  // Make sure that we call the constructor of the SolidQElement
2061  // Only the Intel compiler seems to need this!
2063  };
2064 
2065 
2066  //============================================================================
2068  //============================================================================
2069  template<unsigned NNODE_1D>
2071  : public virtual SolidTBubbleEnrichedElement<2, NNODE_1D>
2072  {
2073  public:
2076  };
2077 
2078  //============================================================================
2080  //============================================================================
2081  template<unsigned NNODE_1D>
2083  : public virtual SolidTElement<1, NNODE_1D>
2084  {
2085  public:
2087  FaceGeometry() : SolidTElement<1, NNODE_1D>() {}
2088  };
2089 
2090 
2091  //=======================================================================
2097  //=======================================================================
2098  template<unsigned DIM>
2100  : public virtual SolidTElement<DIM, 3>,
2101  public virtual PVDEquationsWithPressure<DIM>,
2102  public virtual ElementWithZ2ErrorEstimator
2103  {
2104  private:
2106  static const unsigned Initial_Nvalue[];
2107 
2110  {
2111  // find the index at which the pressure is stored
2112  int p_index = this->solid_p_nodal_index();
2113  unsigned n_node = this->nnode();
2114  // loop over nodes
2115  for (unsigned n = 0; n < n_node; n++)
2116  {
2117  this->node_pt(n)->unpin(p_index);
2118  }
2119  }
2120 
2121  protected:
2124  static const unsigned Pconv[];
2125 
2129  inline int solid_p_local_eqn(const unsigned& i) const
2130  {
2131  return this->nodal_local_eqn(Pconv[i], this->solid_p_nodal_index());
2132  }
2133 
2135  inline void solid_pshape(const Vector<double>& s, Shape& psi) const;
2136 
2137  public:
2141  {
2142  }
2143 
2144 
2147  const TPVDElementWithContinuousPressure<DIM>& dummy) = delete;
2148 
2150  // Commented out broken assignment operator because this can lead to a
2151  // conflict warning when used in the virtual inheritence hierarchy.
2152  // Essentially the compiler doesn't realise that two separate
2153  // implementations of the broken function are the same and so, quite
2154  // rightly, it shouts.
2155  /*void operator=(const TPVDElementWithContinuousPressure<DIM>&) = delete;*/
2156 
2158  inline int solid_p_nodal_index() const
2159  {
2160  return 0;
2161  }
2162 
2165  inline virtual unsigned required_nvalue(const unsigned& n) const
2166  {
2167  return Initial_Nvalue[n];
2168  }
2169 
2172  double solid_p(const unsigned& l)
2173  {
2174  return this->nodal_value(Pconv[l], this->solid_p_nodal_index());
2175  }
2176 
2178  void set_solid_p(const unsigned& l, const double& p_value)
2179  {
2180  this->node_pt(Pconv[l])->set_value(this->solid_p_nodal_index(), p_value);
2181  }
2182 
2184  unsigned npres_solid() const;
2185 
2187  void fix_solid_pressure(const unsigned& l, const double& pvalue)
2188  {
2189  this->node_pt(Pconv[l])->pin(this->solid_p_nodal_index());
2190  this->node_pt(Pconv[l])->set_value(this->solid_p_nodal_index(), pvalue);
2191  }
2192 
2194  void output(std::ostream& outfile)
2195  {
2196  FiniteElement::output(outfile);
2197  }
2198 
2200  void output(std::ostream& outfile, const unsigned& n_plot)
2201  {
2202  PVDEquationsWithPressure<DIM>::output(outfile, n_plot);
2203  }
2204 
2205 
2207  void output(FILE* file_pt)
2208  {
2209  FiniteElement::output(file_pt);
2210  }
2211 
2213  void output(FILE* file_pt, const unsigned& n_plot)
2214  {
2215  PVDEquationsWithPressure<DIM>::output(file_pt, n_plot);
2216  }
2217 
2220  unsigned nrecovery_order()
2221  {
2222  return 2;
2223  }
2224 
2226  unsigned nvertex_node() const
2227  {
2229  }
2230 
2232  Node* vertex_node_pt(const unsigned& j) const
2233  {
2235  }
2236 
2239  {
2240  // DIM Diagonal strain rates and DIM*(DIM-1)/2 off diagonal terms
2241  return DIM + DIM * (DIM - 1) / 2;
2242  }
2243 
2247  {
2248 #ifdef PARANOID
2249  unsigned num_entries = DIM + ((DIM * DIM) - DIM) / 2;
2250  if (flux.size() != num_entries)
2251  {
2252  std::ostringstream error_message;
2253  error_message << "The flux vector has the wrong number of entries, "
2254  << flux.size() << ", whereas it should be " << num_entries
2255  << std::endl;
2256  throw OomphLibError(error_message.str(),
2259  }
2260 #endif
2261 
2262  // Get strain matrix
2263  DenseMatrix<double> strain(DIM);
2264  this->get_strain(s, strain);
2265 
2266  // Pack into flux Vector
2267  unsigned icount = 0;
2268 
2269  // Start with diagonal terms
2270  for (unsigned i = 0; i < DIM; i++)
2271  {
2272  flux[icount] = strain(i, i);
2273  icount++;
2274  }
2275  // Off diagonals row by row
2276  for (unsigned i = 0; i < DIM; i++)
2277  {
2278  for (unsigned j = i + 1; j < DIM; j++)
2279  {
2280  flux[icount] = strain(i, j);
2281  icount++;
2282  }
2283  }
2284  }
2285  };
2286 
2287  // Inline functions
2288 
2289 
2290  //==========================================================================
2293  //==========================================================================
2294  template<>
2296  {
2297  return 3;
2298  }
2299 
2300  //==========================================================================
2303  //==========================================================================
2304  template<>
2306  {
2307  return 4;
2308  }
2309 
2310 
2311  //==========================================================================
2314  //==========================================================================
2315  template<>
2317  const Vector<double>& s, Shape& psi) const
2318  {
2319  psi[0] = s[0];
2320  psi[1] = s[1];
2321  psi[2] = 1.0 - s[0] - s[1];
2322  }
2323 
2324  //==========================================================================
2327  //==========================================================================
2328  template<>
2330  const Vector<double>& s, Shape& psi) const
2331  {
2332  psi[0] = s[0];
2333  psi[1] = s[1];
2334  psi[2] = s[2];
2335  psi[3] = 1.0 - s[0] - s[1] - s[2];
2336  }
2337 
2338 
2339  //=======================================================================
2341  //=======================================================================
2342  template<>
2344  : public virtual SolidTElement<1, 3>
2345  {
2346  public:
2349  };
2350 
2351  //=======================================================================
2353  //=======================================================================
2354  template<>
2356  : public virtual SolidTElement<2, 3>
2357  {
2358  public:
2361  };
2362 
2363 
2367 
2368 
2369  //====================================================================
2371  //====================================================================
2372  namespace SolidHelpers
2373  {
2378  template<class ELEMENT>
2379  void doc_2D_principal_stress(DocInfo& doc_info, SolidMesh* mesh_pt)
2380  {
2381  // Output principal stress vectors at the centre of all elements
2382  std::ofstream pos_file;
2383  std::ofstream neg_file;
2384  std::ostringstream filename;
2385  filename << doc_info.directory() << "/pos_principal_stress"
2386  << doc_info.number() << ".dat";
2387  pos_file.open(filename.str().c_str());
2388  filename.str("");
2389  filename << doc_info.directory() << "/neg_principal_stress"
2390  << doc_info.number() << ".dat";
2391  neg_file.open(filename.str().c_str());
2392 
2393  // Write dummy data in both so there's at lest one zone in each
2394  pos_file << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " "
2395  << std::endl;
2396  neg_file << 0.0 << " " << 0.0 << " " << 0.0 << " " << 0.0 << " "
2397  << std::endl;
2398 
2399 
2400  Vector<double> s(2);
2401  Vector<double> x(2);
2402  s[0] = 0.0;
2403  s[1] = 0.0;
2404  unsigned n_solid_element = mesh_pt->nelement();
2405  for (unsigned e = 0; e < n_solid_element; e++)
2406  {
2407  ELEMENT* el_pt = dynamic_cast<ELEMENT*>(mesh_pt->element_pt(e));
2408 
2409  // Get principal stress
2410  DenseMatrix<double> principal_stress_vector(2);
2411  Vector<double> principal_stress(2);
2412  el_pt->get_principal_stress(
2413  s, principal_stress_vector, principal_stress);
2414 
2415  // Get position of centre of element
2416  el_pt->interpolated_x(s, x);
2417 
2418  // compute vectors at 45 degree for nearly hydrostatic pressure state
2420 
2421  bool hydrostat = false;
2422 
2423  // Max. relative difference between principal stresses
2424  // required to classify stress state as non-hydrostatic: 1%
2425  double dev_max = 1.0e-2;
2426  if (principal_stress[0] != 0.0)
2427  {
2428  if (std::fabs((principal_stress[0] - principal_stress[1]) /
2429  principal_stress[0]) < dev_max)
2430  {
2431  hydrostat = true;
2432  double Cos = cos(0.25 * 3.14159);
2433  double Sin = sin(0.25 * 3.14159);
2434  rot(0, 0) = Cos * principal_stress_vector(0, 0) -
2435  Sin * principal_stress_vector(0, 1);
2436  rot(0, 1) = Sin * principal_stress_vector(0, 0) +
2437  Cos * principal_stress_vector(0, 1);
2438  rot(1, 0) = Cos * principal_stress_vector(1, 0) -
2439  Sin * principal_stress_vector(1, 1);
2440  rot(1, 1) = Sin * principal_stress_vector(1, 0) +
2441  Cos * principal_stress_vector(1, 1);
2442  }
2443  }
2444 
2445  // Loop over two principal stresses:
2446  for (unsigned i = 0; i < 2; i++)
2447  {
2448  if (principal_stress[i] > 0.0)
2449  {
2450  pos_file << x[0] << " " << x[1] << " "
2451  << principal_stress_vector(i, 0) << " "
2452  << principal_stress_vector(i, 1) << std::endl;
2453  pos_file << x[0] << " " << x[1] << " "
2454  << -principal_stress_vector(i, 0) << " "
2455  << -principal_stress_vector(i, 1) << std::endl;
2456  if (hydrostat)
2457  {
2458  pos_file << x[0] << " " << x[1] << " " << rot(i, 0) << " "
2459  << rot(i, 1) << std::endl;
2460  pos_file << x[0] << " " << x[1] << " " << -rot(i, 0) << " "
2461  << -rot(i, 1) << std::endl;
2462  }
2463  }
2464  else
2465  {
2466  neg_file << x[0] << " " << x[1] << " "
2467  << principal_stress_vector(i, 0) << " "
2468  << principal_stress_vector(i, 1) << std::endl;
2469  neg_file << x[0] << " " << x[1] << " "
2470  << -principal_stress_vector(i, 0) << " "
2471  << -principal_stress_vector(i, 1) << std::endl;
2472  if (hydrostat)
2473  {
2474  neg_file << x[0] << " " << x[1] << " " << rot(i, 0) << " "
2475  << rot(i, 1) << std::endl;
2476  neg_file << x[0] << " " << x[1] << " " << -rot(i, 0) << " "
2477  << -rot(i, 1) << std::endl;
2478  }
2479  }
2480  }
2481  }
2482 
2483  pos_file.close();
2484  neg_file.close();
2485  }
2486 
2487  }; // namespace SolidHelpers
2488 
2489 
2490  //==========================================================
2492  //==========================================================
2493  template<class PVD_ELEMENT>
2495  : public virtual ProjectableElement<PVD_ELEMENT>
2496  {
2497  public:
2501 
2502 
2509  {
2510  // Create the vector
2511  Vector<std::pair<Data*, unsigned>> data_values;
2512 
2513  // Loop over all vertex nodes
2514  const unsigned n_solid_pres = this->npres_solid();
2515  for (unsigned j = 0; j < n_solid_pres; j++)
2516  {
2517  // Add the data value associated with the pressure components
2518  unsigned vertex_index = this->Pconv[j];
2519  data_values.push_back(std::make_pair(this->node_pt(vertex_index), 0));
2520  }
2521 
2522  // Return the vector
2523  return data_values;
2524  }
2525 
2529  {
2530  return 1;
2531  }
2532 
2535  unsigned nhistory_values_for_projection(const unsigned& fld)
2536  {
2537  // pressure doesn't have history values as such so only one value
2538  // representing the current value
2539  return 1;
2540  }
2541 
2544  {
2545  return this->node_pt(0)->position_time_stepper_pt()->ntstorage();
2546  }
2547 
2550  double jacobian_and_shape_of_field(const unsigned& fld,
2551  const Vector<double>& s,
2552  Shape& psi)
2553  {
2554  // Get the solid pressure shape function
2555  this->solid_pshape(s, psi);
2556  // Return the Jacobian of the eulerian mapping
2557  return this->J_eulerian(s);
2558  }
2559 
2562  double get_field(const unsigned& t,
2563  const unsigned& fld,
2564  const Vector<double>& s)
2565  {
2566  return this->interpolated_solid_p(s);
2567  }
2568 
2569 
2571  unsigned nvalue_of_field(const unsigned& fld)
2572  {
2573  return this->npres_solid();
2574  }
2575 
2576 
2578  int local_equation(const unsigned& fld, const unsigned& j)
2579  {
2580  return this->solid_p_local_eqn(j);
2581  }
2582  };
2583 
2584 
2585  //=======================================================================
2588  //=======================================================================
2589  template<class ELEMENT>
2591  : public virtual FaceGeometry<ELEMENT>
2592  {
2593  public:
2594  FaceGeometry() : FaceGeometry<ELEMENT>() {}
2595  };
2596 
2597 
2598  //=======================================================================
2601  //=======================================================================
2602  template<class ELEMENT>
2605  : public virtual FaceGeometry<FaceGeometry<ELEMENT>>
2606  {
2607  public:
2609  };
2610 
2611 
2612 } // namespace oomph
2613 
2614 #endif
AnnoyingScalar cos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:136
AnnoyingScalar sin(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:137
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
JacobiRotation< float > G
Definition: Jacobi_makeGivens.cpp:2
Scalar * b
Definition: benchVecAdd.cpp:17
Definition: constitutive_laws.h:471
virtual void calculate_d_second_piola_kirchhoff_stress_dG(const DenseMatrix< double > &g, const DenseMatrix< double > &G, const DenseMatrix< double > &sigma, RankFourTensor< double > &d_sigma_dG, const bool &symmetrize_tensor=true)
Definition: constitutive_laws.cc:352
virtual void calculate_second_piola_kirchhoff_stress(const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma)=0
Definition: nodes.h:86
void pin(const unsigned &i)
Pin the i-th stored variable.
Definition: nodes.h:385
void unpin(const unsigned &i)
Unpin the i-th stored variable.
Definition: nodes.h:391
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
Definition: nodes.h:238
void set_value(const unsigned &i, const double &value_)
Definition: nodes.h:271
double value(const unsigned &i) const
Definition: nodes.h:293
Definition: oomph_utilities.h:499
std::string directory() const
Output directory.
Definition: oomph_utilities.h:524
unsigned & number()
Number used (e.g.) for labeling output files.
Definition: oomph_utilities.h:554
Definition: error_estimator.h:79
FaceGeometry()
Constructor must call constructor of the underlying Point element.
Definition: solid_elements.h:1711
FaceGeometry()
Constructor must call constructor of the underlying element.
Definition: solid_elements.h:1738
FaceGeometry()
Constructor must call constructor of underlying solid element.
Definition: solid_elements.h:1478
FaceGeometry()
Constructor must call constructor of underlying solid element.
Definition: solid_elements.h:1503
FaceGeometry()
Constructor must call the constructor of the underlying solid element.
Definition: solid_elements.h:688
FaceGeometry()
Constructor must call the constructor of the underlying solid element.
Definition: solid_elements.h:2087
FaceGeometry()
Constructor must call the constructor of the underlying solid element.
Definition: solid_elements.h:1914
FaceGeometry()
Definition: solid_elements.h:827
FaceGeometry()
Constructor must call constructor of the underlying Solid element.
Definition: solid_elements.h:1697
FaceGeometry()
Constructor must call constructor of the underlying Solid element.
Definition: solid_elements.h:1724
FaceGeometry()
Constructor must call constructor of underlying solid element.
Definition: solid_elements.h:1465
FaceGeometry()
Constructor must call constructor of underlying solid element.
Definition: solid_elements.h:1490
FaceGeometry()
Constructor must call the constructor of the underlying solid element.
Definition: solid_elements.h:649
FaceGeometry()
Constructor must call the constructor of the underlying solid element.
Definition: solid_elements.h:676
FaceGeometry()
Constructor must call the constructor of the underlying solid element.
Definition: solid_elements.h:2048
FaceGeometry()
Constructor must call the constructor of the underlying solid element.
Definition: solid_elements.h:2075
FaceGeometry()
Constructor: Call constructor of base.
Definition: solid_elements.h:2348
FaceGeometry()
Constructor: Call constructor of base.
Definition: solid_elements.h:2360
FaceGeometry()
Constructor must call the constructor of the underlying solid element.
Definition: solid_elements.h:1875
FaceGeometry()
Constructor must call the constructor of the underlying solid element.
Definition: solid_elements.h:1902
Definition: elements.h:4998
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
double nodal_value(const unsigned &n, const unsigned &i) const
Definition: elements.h:2593
virtual void output(std::ostream &outfile)
Definition: elements.h:3050
unsigned nnodal_position_type() const
Definition: elements.h:2463
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Definition: elements.h:1432
unsigned dim() const
Definition: elements.h:2611
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition: elements.h:1963
unsigned nodal_dimension() const
Return the required Eulerian dimension of the nodes in this element.
Definition: elements.h:2484
virtual double J_eulerian(const Vector< double > &s) const
Definition: elements.cc:4103
unsigned ndof() const
Return the number of equations/dofs in the element.
Definition: elements.h:835
unsigned long eqn_number(const unsigned &ieqn_local) const
Definition: elements.h:704
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
Definition: elements.h:622
int internal_local_eqn(const unsigned &i, const unsigned &j) const
Definition: elements.h:267
static DenseMatrix< double > Dummy_matrix
Definition: elements.h:227
unsigned add_internal_data(Data *const &data_pt, const bool &fd=true)
Definition: elements.cc:62
Definition: solid_elements.h:698
void output(FILE *file_pt, const unsigned &n_plot)
C-style SolidQHermiteElement output function.
Definition: solid_elements.h:722
void output(FILE *file_pt)
C-style SolidQHermiteElement output function.
Definition: solid_elements.h:716
void output(std::ostream &outfile, const unsigned &n_plot)
SolidQHermiteElement output function.
Definition: solid_elements.h:710
void output(std::ostream &outfile)
SolidQHermiteElement output function.
Definition: solid_elements.h:704
HermitePVDElement()
Constructor, there are no internal data points.
Definition: solid_elements.h:701
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
Definition: mesh.h:448
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
Definition: nodes.h:906
TimeStepper *& position_time_stepper_pt()
Return a pointer to the position timestepper.
Definition: nodes.h:1022
Definition: oomph_definitions.h:222
Definition: solid_elements.h:58
bool Unsteady
Flag that switches inertia on/off.
Definition: solid_elements.h:421
static void unpin_all_solid_pressure_dofs(const Vector< GeneralisedElement * > &element_pt)
Unpin all pressure dofs in elements listed in vector.
Definition: solid_elements.h:221
void get_energy(double &pot_en, double &kin_en)
Get potential (strain) and kinetic energy.
Definition: solid_elements.cc:829
virtual void pin_elemental_redundant_nodal_solid_pressures()
Pin the element's redundant solid pressures (needed for refinement)
Definition: solid_elements.h:196
PrestressFctPt & prestress_fct_pt()
Access function: Pointer to pre-stress function.
Definition: solid_elements.h:128
void disable_evaluate_jacobian_by_fd()
Set Jacobian to be evaluated analytically Else: by FD.
Definition: solid_elements.h:380
static double Default_lambda_sq_value
Static default value for timescale ratio (1.0 – for natural scaling)
Definition: solid_elements.h:427
BodyForceFctPt Body_force_fct_pt
Pointer to body force function.
Definition: solid_elements.h:424
virtual int solid_p_nodal_index() const
Definition: solid_elements.h:186
virtual int solid_p_local_eqn(const unsigned &i) const
Definition: solid_elements.h:178
void get_principal_stress(const Vector< double > &s, DenseMatrix< double > &principal_stress_vector, Vector< double > &principal_stress)
Definition: solid_elements.cc:1071
bool is_jacobian_evaluated_by_fd() const
Return the flag indicating whether the jacobian is evaluated by fd.
Definition: solid_elements.h:386
BodyForceFctPt & body_force_fct_pt()
Access function: Pointer to body force function.
Definition: solid_elements.h:140
ConstitutiveLaw *& constitutive_law_pt()
Return the constitutive law pointer.
Definition: solid_elements.h:101
double(* PrestressFctPt)(const unsigned &i, const unsigned &j, const Vector< double > &xi)
Definition: solid_elements.h:74
ConstitutiveLaw * Constitutive_law_pt
Pointer to the constitutive law.
Definition: solid_elements.h:415
double prestress(const unsigned &i, const unsigned &j, const Vector< double > xi)
Definition: solid_elements.h:393
void get_dof_numbers_for_unknowns(std::list< std::pair< unsigned long, unsigned >> &dof_lookup_list) const
Definition: solid_elements.h:329
void(* IsotropicGrowthFctPt)(const Vector< double > &xi, double &gamma)
Definition: solid_elements.h:68
virtual void get_isotropic_growth(const unsigned &ipt, const Vector< double > &s, const Vector< double > &xi, double &gamma) const
Definition: solid_elements.h:267
void disable_inertia()
Switch off solid inertia.
Definition: solid_elements.h:158
virtual unsigned npres_solid() const
Definition: solid_elements.h:171
unsigned ndof_types() const
returns the number of DOF types associated with this element.
Definition: solid_elements.h:314
bool is_inertia_enabled() const
Access function to flag that switches inertia on/off (const version)
Definition: solid_elements.h:164
double *& lambda_sq_pt()
Access function for pointer to timescale ratio (nondim density)
Definition: solid_elements.h:115
BodyForceFctPt body_force_fct_pt() const
Access function: Pointer to body force function (const version)
Definition: solid_elements.h:146
static int Solid_pressure_not_stored_at_node
Definition: solid_elements.h:62
void get_deformed_covariant_basis_vectors(const Vector< double > &s, DenseMatrix< double > &def_covariant_basis)
Definition: solid_elements.cc:1197
IsotropicGrowthFctPt isotropic_growth_fct_pt() const
Access function: Pointer to isotropic growth function (const version)
Definition: solid_elements.h:134
void get_strain(const Vector< double > &s, DenseMatrix< double > &strain) const
Return the strain tensor.
Definition: solid_elements.cc:47
IsotropicGrowthFctPt Isotropic_growth_fct_pt
Pointer to isotropic growth function.
Definition: solid_elements.h:409
void(* BodyForceFctPt)(const double &t, const Vector< double > &xi, Vector< double > &b)
Definition: solid_elements.h:81
PVDEquationsBase()
Definition: solid_elements.h:89
PrestressFctPt Prestress_fct_pt
Pointer to prestress function.
Definition: solid_elements.h:412
bool Evaluate_jacobian_by_fd
Use FD to evaluate Jacobian.
Definition: solid_elements.h:430
IsotropicGrowthFctPt & isotropic_growth_fct_pt()
Access function: Pointer to isotropic growth function.
Definition: solid_elements.h:122
virtual void unpin_elemental_solid_pressure_dofs()=0
Unpin all solid pressure dofs in the element.
virtual void get_stress(const Vector< double > &s, DenseMatrix< double > &sigma)=0
void body_force(const Vector< double > &xi, Vector< double > &b) const
Definition: solid_elements.h:287
void enable_evaluate_jacobian_by_fd()
Set Jacobian to be evaluated by FD? Else: Analytically.
Definition: solid_elements.h:374
static void pin_redundant_nodal_solid_pressures(const Vector< GeneralisedElement * > &element_pt)
Definition: solid_elements.h:208
double * Lambda_sq_pt
Timescale ratio (non-dim. density)
Definition: solid_elements.h:418
void enable_inertia()
Switch on solid inertia.
Definition: solid_elements.h:152
const double & lambda_sq() const
Access function for timescale ratio (nondim density)
Definition: solid_elements.h:108
Definition: solid_elements.h:863
void get_stress(const Vector< double > &s, DenseMatrix< double > &sigma)
Definition: solid_elements.cc:2267
void output(std::ostream &outfile)
Output: x,y,[z],xi0,xi1,[xi2],p,gamma.
Definition: solid_elements.h:1033
void set_compressible()
Set the material to be compressible.
Definition: solid_elements.h:887
virtual double solid_p(const unsigned &l)=0
Return the lth solid pressure.
void get_stress(const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma_dev, DenseMatrix< double > &Gcontra, double &detG)
Definition: solid_elements.h:1258
void get_d_stress_dG_upper(const DenseMatrix< double > &g, const DenseMatrix< double > &G, const DenseMatrix< double > &sigma, const double &gen_dil, const double &inv_kappa, const double &interpolated_solid_p, RankFourTensor< double > &d_sigma_dG, DenseMatrix< double > &d_gen_dil_dG)
Definition: solid_elements.h:1177
virtual void set_solid_p(const unsigned &l, const double &p_value)=0
Set the lth solid pressure to p_value.
void get_stress(const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma_dev, DenseMatrix< double > &Gcontra, double &gen_dil, double &inv_kappa)
Definition: solid_elements.h:1145
void get_dof_numbers_for_unknowns(std::list< std::pair< unsigned long, unsigned >> &dof_lookup_list) const
Definition: solid_elements.h:1077
virtual void fill_in_generic_residual_contribution_pvd_with_pressure(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, const unsigned &flag)
Definition: solid_elements.cc:1271
void get_d_stress_dG_upper(const DenseMatrix< double > &g, const DenseMatrix< double > &G, const DenseMatrix< double > &sigma, const double &detG, const double &interpolated_solid_p, RankFourTensor< double > &d_sigma_dG, DenseMatrix< double > &d_detG_dG)
Definition: solid_elements.h:1288
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Fill in the residuals.
Definition: solid_elements.h:899
void solid_pshape_at_knot(const unsigned &ipt, Shape &psi) const
Return the stored solid shape functions at the knots.
Definition: solid_elements.h:1220
void extended_output(std::ostream &outfile, const unsigned &n_plot)
Output: x,y,[z],xi0,xi1,[xi2],gamma strain and stress components.
Definition: solid_elements.cc:2116
double interpolated_solid_p(const Vector< double > &s)
Return the interpolated_solid_pressure.
Definition: solid_elements.h:1011
bool Incompressible
Boolean to determine whether the solid is incompressible or not.
Definition: solid_elements.h:1237
void fill_in_contribution_to_jacobian_and_mass_matrix(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix)
Definition: solid_elements.h:958
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: solid_elements.h:914
unsigned ndof_types() const
Definition: solid_elements.h:1064
bool is_incompressible() const
Return whether the material is incompressible.
Definition: solid_elements.h:875
void get_mass_matrix_diagonal(Vector< double > &mass_diag)
Definition: solid_elements.cc:2198
virtual void solid_pshape(const Vector< double > &s, Shape &psi) const =0
Return the solid pressure shape functions.
void set_incompressible()
Set the material to be incompressible.
Definition: solid_elements.h:881
void output(FILE *file_pt)
C-style output: x,y,[z],xi0,xi1,[xi2],p,gamma.
Definition: solid_elements.h:1044
PVDEquationsWithPressure()
Constructor, by default the element is NOT incompressible.
Definition: solid_elements.h:866
Definition: solid_elements.h:440
virtual void fill_in_generic_contribution_to_residuals_pvd(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Definition: solid_elements.cc:179
void unpin_elemental_solid_pressure_dofs()
Unpin all solid pressure dofs – empty as there are no pressures.
Definition: solid_elements.h:596
void get_d_stress_dG_upper(const DenseMatrix< double > &g, const DenseMatrix< double > &G, const DenseMatrix< double > &sigma, RankFourTensor< double > &d_sigma_dG)
Definition: solid_elements.h:569
void extended_output(std::ostream &outfile, const unsigned &n_plot)
Output: x,y,[z],xi0,xi1,[xi2],gamma strain and stress components.
Definition: solid_elements.cc:751
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: solid_elements.h:459
PVDEquations()
Constructor.
Definition: solid_elements.h:443
void output(std::ostream &outfile)
Output: x,y,[z],xi0,xi1,[xi2],gamma.
Definition: solid_elements.h:506
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Definition: solid_elements.h:451
void get_stress(const Vector< double > &s, DenseMatrix< double > &sigma)
Definition: solid_elements.cc:951
void output(FILE *file_pt)
C-style output: x,y,[z],xi0,xi1,[xi2],gamma.
Definition: solid_elements.h:517
void get_stress(const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma)
Definition: solid_elements.h:543
Definition: elements.h:3439
Definition: projection.h:183
PVDElementWithContinuousPressure upgraded to become projectable.
Definition: solid_elements.h:2496
unsigned nfields_for_projection()
Definition: solid_elements.h:2528
unsigned nvalue_of_field(const unsigned &fld)
Return number of values in field fld.
Definition: solid_elements.h:2571
double get_field(const unsigned &t, const unsigned &fld, const Vector< double > &s)
Definition: solid_elements.h:2562
unsigned nhistory_values_for_coordinate_projection()
Number of positional history values (Includes the current value!)
Definition: solid_elements.h:2543
int local_equation(const unsigned &fld, const unsigned &j)
Return local equation number of value j in field fld.
Definition: solid_elements.h:2578
ProjectablePVDElementWithContinuousPressure()
Definition: solid_elements.h:2500
double jacobian_and_shape_of_field(const unsigned &fld, const Vector< double > &s, Shape &psi)
Definition: solid_elements.h:2550
Vector< std::pair< Data *, unsigned > > data_values_of_field(const unsigned &fld)
Definition: solid_elements.h:2508
unsigned nhistory_values_for_projection(const unsigned &fld)
Definition: solid_elements.h:2535
PVDElementWithContinuousPressure upgraded to become projectable.
Definition: solid_elements.h:734
unsigned nvalue_of_field(const unsigned &fld)
Return number of values in field fld.
Definition: solid_elements.h:804
unsigned nhistory_values_for_projection(const unsigned &fld)
Definition: solid_elements.h:771
unsigned nfields_for_projection()
Number of fields to be projected: 0.
Definition: solid_elements.h:764
double get_field(const unsigned &t, const unsigned &fld, const Vector< double > &s)
Definition: solid_elements.h:794
unsigned nhistory_values_for_coordinate_projection()
Number of positional history values (Includes the current value!)
Definition: solid_elements.h:777
Vector< std::pair< Data *, unsigned > > data_values_of_field(const unsigned &fld)
Definition: solid_elements.h:745
ProjectablePVDElement()
Definition: solid_elements.h:738
int local_equation(const unsigned &fld, const unsigned &j)
Return local equation number of value j in field fld.
Definition: solid_elements.h:811
double jacobian_and_shape_of_field(const unsigned &fld, const Vector< double > &s, Shape &psi)
Definition: solid_elements.h:784
Definition: solid_elements.h:1523
QPVDElementWithContinuousPressure()
Constructor.
Definition: solid_elements.h:1560
double solid_p(const unsigned &l)
Definition: solid_elements.h:1580
void output(std::ostream &outfile, const unsigned &n_plot)
PVDEquationsWithPressure output function.
Definition: solid_elements.h:1611
void unpin_elemental_solid_pressure_dofs()
Unpin all solid pressure dofs in the element.
Definition: solid_elements.h:1530
static const unsigned Initial_Nvalue[]
Definition: solid_elements.h:1527
virtual unsigned required_nvalue(const unsigned &n) const
Definition: solid_elements.h:1573
void set_solid_p(const unsigned &l, const double &p_value)
Set the l-th solid pressure value to p_value.
Definition: solid_elements.h:1586
unsigned npres_solid() const
Return number of pressure values.
Definition: solid_elements.h:1592
void solid_pshape(const Vector< double > &s, Shape &psi) const
Return the pressure shape functions.
int solid_p_local_eqn(const unsigned &i) const
Definition: solid_elements.h:1550
int solid_p_nodal_index() const
Set the value at which the solid pressure is stored in the nodes.
Definition: solid_elements.h:1566
static const unsigned Pconv[]
Definition: solid_elements.h:1545
void fix_solid_pressure(const unsigned &l, const double &pvalue)
Fix the pressure dof l to be the value pvalue.
Definition: solid_elements.h:1598
void output(std::ostream &outfile)
Generic FiniteElement output function.
Definition: solid_elements.h:1605
void output(FILE *file_pt)
C-style generic FiniteElement output function.
Definition: solid_elements.h:1618
void output(FILE *file_pt, const unsigned &n_plot)
C-style PVDEquationsWithPressure output function.
Definition: solid_elements.h:1624
Definition: solid_elements.h:1332
void output(FILE *file_pt, const unsigned &n_plot)
C-style PVDEquationsWithPressure output function.
Definition: solid_elements.h:1422
void solid_pshape(const Vector< double > &s, Shape &psi) const
Return the pressure shape functions.
unsigned npres_solid() const
Return number of pressure values.
Definition: solid_elements.h:1390
void output(std::ostream &outfile)
Generic FiniteElement output function.
Definition: solid_elements.h:1403
void set_solid_p(const unsigned &l, const double &p_value)
Set the l-th pressure value to p_value.
Definition: solid_elements.h:1384
void fix_solid_pressure(const unsigned &l, const double &pvalue)
Fix the pressure dof l to be the value pvalue.
Definition: solid_elements.h:1396
int solid_p_local_eqn(const unsigned &i) const
Definition: solid_elements.h:1352
void output(std::ostream &outfile, const unsigned &n_plot)
PVDEquationsWithPressure output function.
Definition: solid_elements.h:1409
bool has_internal_solid_data()
Definition: solid_elements.h:1363
void output(FILE *file_pt)
C-style Generic FiniteElement output function.
Definition: solid_elements.h:1416
void unpin_elemental_solid_pressure_dofs()
Unpin all solid pressure dofs in the element.
Definition: solid_elements.h:1334
double solid_p(const unsigned &l)
Return the lth pressure value.
Definition: solid_elements.h:1378
QPVDElementWithPressure()
Constructor, there are DIM+1 internal data points.
Definition: solid_elements.h:1369
unsigned P_solid_internal_index
Definition: solid_elements.h:1347
Definition: solid_elements.h:608
void output(std::ostream &outfile)
Output function.
Definition: solid_elements.h:614
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function.
Definition: solid_elements.h:633
void output(std::ostream &outfile, const unsigned &n_plot)
Output function.
Definition: solid_elements.h:620
void output(FILE *file_pt)
C-style output function.
Definition: solid_elements.h:627
QPVDElement()
Constructor, there are no internal data points.
Definition: solid_elements.h:611
A Rank 4 Tensor class.
Definition: matrices.h:1701
Definition: shape.h:76
Definition: elements.h:3561
bool Solve_for_consistent_newmark_accel_flag
Definition: elements.h:4302
SolidInitialCondition * Solid_ic_pt
Pointer to object that specifies the initial condition.
Definition: elements.h:4131
int position_local_eqn(const unsigned &n, const unsigned &k, const unsigned &j) const
Definition: elements.h:4137
virtual void fill_in_jacobian_from_solid_position_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: elements.cc:6985
void fill_in_jacobian_for_solid_ic(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: elements.h:4035
void describe_local_dofs(std::ostream &out, const std::string &current_string) const
Definition: elements.cc:6514
void fill_in_jacobian_for_newmark_accel(DenseMatrix< double > &jacobian)
Definition: elements.cc:7227
Definition: mesh.h:2562
Definition: Qelements.h:1742
Definition: hermite_elements.h:504
void output(std::ostream &outfile)
Overload the output function.
Definition: hermite_elements.cc:1072
Definition: Telements.h:3926
Definition: Telements.h:3728
Definition: Telements.h:1208
Definition: solid_elements.h:1935
void output(std::ostream &outfile)
Output function.
Definition: solid_elements.h:1944
unsigned num_Z2_flux_terms()
Number of 'flux' terms for Z2 error estimation.
Definition: solid_elements.h:1989
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function.
Definition: solid_elements.h:1963
TPVDBubbleEnrichedElement()
Constructor, there are no internal data points.
Definition: solid_elements.h:1938
void output(FILE *file_pt)
C-style output function.
Definition: solid_elements.h:1957
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
Definition: solid_elements.h:1997
unsigned nrecovery_order()
Definition: solid_elements.h:1971
void output(std::ostream &outfile, const unsigned &n_plot)
Output function.
Definition: solid_elements.h:1950
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
Definition: solid_elements.h:1983
unsigned nvertex_node() const
Number of vertex nodes in the element.
Definition: solid_elements.h:1977
Definition: solid_elements.h:2103
TPVDElementWithContinuousPressure(const TPVDElementWithContinuousPressure< DIM > &dummy)=delete
Broken copy constructor.
void output(FILE *file_pt)
C-style generic FiniteElement output function.
Definition: solid_elements.h:2207
int solid_p_local_eqn(const unsigned &i) const
Definition: solid_elements.h:2129
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
Definition: solid_elements.h:2232
TPVDElementWithContinuousPressure()
Constructor.
Definition: solid_elements.h:2139
void output(std::ostream &outfile)
Generic FiniteElement output function.
Definition: solid_elements.h:2194
unsigned nvertex_node() const
Number of vertex nodes in the element.
Definition: solid_elements.h:2226
void unpin_elemental_solid_pressure_dofs()
Unpin all solid pressure dofs in the element.
Definition: solid_elements.h:2109
unsigned npres_solid() const
Return number of pressure values.
void set_solid_p(const unsigned &l, const double &p_value)
Set the l-th solid pressure value to p_value.
Definition: solid_elements.h:2178
virtual unsigned required_nvalue(const unsigned &n) const
Definition: solid_elements.h:2165
unsigned num_Z2_flux_terms()
Number of 'flux' terms for Z2 error estimation.
Definition: solid_elements.h:2238
void solid_pshape(const Vector< double > &s, Shape &psi) const
Pressure shape functions at local coordinate s.
static const unsigned Initial_Nvalue[]
Static array of ints to hold number of variables at node.
Definition: solid_elements.h:2106
void fix_solid_pressure(const unsigned &l, const double &pvalue)
Fix the pressure dof l to be the value pvalue.
Definition: solid_elements.h:2187
void output(FILE *file_pt, const unsigned &n_plot)
C-style PVDEquationsWithPressure output function.
Definition: solid_elements.h:2213
double solid_p(const unsigned &l)
Definition: solid_elements.h:2172
int solid_p_nodal_index() const
Broken assignment operator.
Definition: solid_elements.h:2158
unsigned nrecovery_order()
Definition: solid_elements.h:2220
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
Definition: solid_elements.h:2246
static const unsigned Pconv[]
Definition: solid_elements.h:2124
void output(std::ostream &outfile, const unsigned &n_plot)
PVDEquationsWithPressure output function.
Definition: solid_elements.h:2200
Definition: solid_elements.h:1756
void output(std::ostream &outfile)
Output function.
Definition: solid_elements.h:1762
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
Definition: solid_elements.h:1824
void output(std::ostream &outfile, const unsigned &n_plot)
Output function.
Definition: solid_elements.h:1768
TPVDElement()
Constructor, there are no internal data points.
Definition: solid_elements.h:1759
void output(FILE *file_pt)
C-style output function.
Definition: solid_elements.h:1775
unsigned num_Z2_flux_terms()
Number of 'flux' terms for Z2 error estimation.
Definition: solid_elements.h:1816
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
Definition: solid_elements.h:1800
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function.
Definition: solid_elements.h:1781
unsigned nrecovery_order()
Definition: solid_elements.h:1788
unsigned nvertex_node() const
Number of vertex nodes in the element.
Definition: solid_elements.h:1794
unsigned ntstorage() const
Definition: timesteppers.h:601
Time *const & time_pt() const
Access function for the pointer to time (const version)
Definition: timesteppers.h:572
double & time()
Return the current value of the continuous time.
Definition: timesteppers.h:123
RealScalar s
Definition: level1_cplx_impl.h:130
EIGEN_BLAS_FUNC() rot(int *n, Scalar *px, int *incx, Scalar *py, int *incy, Scalar *pc, Scalar *ps)
Definition: level1_real_impl.h:88
char char char int int * k
Definition: level2_impl.h:374
#define DIM
Definition: linearised_navier_stokes_elements.h:44
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
static const unsigned Dim
Problem dimension.
Definition: two_d_tilted_square.cc:62
string filename
Definition: MergeRestartFiles.py:39
void flux(const double &time, const Vector< double > &x, double &flux)
Get flux applied along boundary x=0.
Definition: pretend_melt.cc:59
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117
int sigma
Definition: calibrate.py:179
Mdouble gamma(Mdouble gamma_in)
This is the gamma function returns the true value for the half integer value.
Definition: ExtendedMath.cc:116
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
void shape< 2 >(const double &s, double *Psi)
1D shape functions specialised to linear order (2 Nodes)
Definition: shape.h:608
void doc_2D_principal_stress(DocInfo &doc_info, SolidMesh *mesh_pt)
Definition: solid_elements.h:2379
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
list x
Definition: plotDoE.py:28
t
Definition: plotPSD.py:36
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2