oomph::IsotropicStrainEnergyFunctionConstitutiveLaw Class Reference

#include <constitutive_laws.h>

+ Inheritance diagram for oomph::IsotropicStrainEnergyFunctionConstitutiveLaw:

Public Member Functions

 IsotropicStrainEnergyFunctionConstitutiveLaw (StrainEnergyFunction *const &strain_energy_function_pt)
 Constructor takes a pointer to the strain energy function. More...
 
void calculate_second_piola_kirchhoff_stress (const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma)
 
void calculate_second_piola_kirchhoff_stress (const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma_dev, DenseMatrix< double > &G_contra, double &Gdet)
 
void calculate_second_piola_kirchhoff_stress (const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma_dev, DenseMatrix< double > &Gcontra, double &gen_dil, double &inv_kappa)
 
bool requires_incompressibility_constraint ()
 
- Public Member Functions inherited from oomph::ConstitutiveLaw
 ConstitutiveLaw ()
 Empty constructor. More...
 
virtual ~ConstitutiveLaw ()
 Empty virtual destructor. More...
 
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)
 
virtual void calculate_d_second_piola_kirchhoff_stress_dG (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, const bool &symmetrize_tensor=true)
 
virtual void calculate_d_second_piola_kirchhoff_stress_dG (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, const bool &symmetrize_tensor=true)
 

Private Attributes

StrainEnergyFunctionStrain_energy_function_pt
 Pointer to the strain energy function. More...
 

Additional Inherited Members

- Protected Member Functions inherited from oomph::ConstitutiveLaw
bool is_matrix_square (const DenseMatrix< double > &M)
 Test whether a matrix is square. More...
 
bool are_matrices_of_equal_dimensions (const DenseMatrix< double > &M1, const DenseMatrix< double > &M2)
 Test whether two matrices are of equal dimensions. More...
 
void error_checking_in_input (const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma)
 
double calculate_contravariant (const DenseMatrix< double > &Gcov, DenseMatrix< double > &Gcontra)
 The function to calculate the contravariant tensor from a covariant one. More...
 
void calculate_d_contravariant_dG (const DenseMatrix< double > &Gcov, RankFourTensor< double > &dGcontra_dG, DenseMatrix< double > &d_detG_dG)
 

Detailed Description

////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// A class for constitutive laws derived from strain-energy functions. Theory is in Green and Zerna.

Constructor & Destructor Documentation

◆ IsotropicStrainEnergyFunctionConstitutiveLaw()

oomph::IsotropicStrainEnergyFunctionConstitutiveLaw::IsotropicStrainEnergyFunctionConstitutiveLaw ( StrainEnergyFunction *const &  strain_energy_function_pt)
inline

Constructor takes a pointer to the strain energy function.

810  : ConstitutiveLaw(), Strain_energy_function_pt(strain_energy_function_pt)
811  {
812  }
ConstitutiveLaw()
Empty constructor.
Definition: constitutive_laws.h:501
StrainEnergyFunction * Strain_energy_function_pt
Pointer to the strain energy function.
Definition: constitutive_laws.h:804

Member Function Documentation

◆ calculate_second_piola_kirchhoff_stress() [1/3]

void oomph::IsotropicStrainEnergyFunctionConstitutiveLaw::calculate_second_piola_kirchhoff_stress ( const DenseMatrix< double > &  g,
const DenseMatrix< double > &  G,
DenseMatrix< double > &  sigma 
)
virtual

Calculate the contravariant 2nd Piola Kirchhoff stress tensor. Arguments are the covariant undeformed and deformed metric tensor and the matrix in which to return the stress tensor. Uses correct 3D invariants for 2D (plane strain) problems.

////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// Calculate the contravariant 2nd Piola Kirchhoff stress tensor. Arguments are the covariant undeformed and deformed metric tensor and the matrix in which to return the stress tensor. Uses correct 3D invariants for 2D (plane strain) problems.

Implements oomph::ConstitutiveLaw.

899  {
900 // Error checking
901 #ifdef PARANOID
903 #endif
904 
905  // Find the dimension of the problem
906  unsigned dim = g.nrow();
907 
908 #ifdef PARANOID
909  if (dim == 1)
910  {
911  std::string function_name =
912  "IsotropicStrainEnergyFunctionConstitutiveLaw::";
913  function_name += "calculate_second_piola_kirchhoff_stress()";
914 
915  throw OomphLibError("Check constitutive equations carefully when dim=1",
918  }
919 #endif
920 
921  // Calculate the contravariant undeformed and deformed metric tensors
922  // and get the determinants of the metric tensors
923  DenseMatrix<double> gup(dim), Gup(dim);
924  double detg = calculate_contravariant(g, gup);
925  double detG = calculate_contravariant(G, Gup);
926 
927  // Calculate the strain invariants
928  Vector<double> I(3, 0.0);
929  // The third strain invaraint is the volumetric change
930  I[2] = detG / detg;
931  // The first and second are a bit more complex --- see G&Z
932  for (unsigned i = 0; i < dim; i++)
933  {
934  for (unsigned j = 0; j < dim; j++)
935  {
936  I[0] += gup(i, j) * G(i, j);
937  I[1] += g(i, j) * Gup(i, j);
938  }
939  }
940 
941  // If 2D we assume plane strain: In this case the 3D tensors have
942  // a 1 on the diagonal and zeroes in the off-diagonals of their
943  // third rows and columns. Only effect: Increase the first two
944  // invariants by one; rest of the computation can just be performed
945  // over the 2d set of coordinates.
946  if (dim == 2)
947  {
948  I[0] += 1.0;
949  I[1] += 1.0;
950  }
951 
952  // Second strain invariant is multiplied by the third.
953  I[1] *= I[2];
954 
955  // Calculate the derivatives of the strain energy function wrt the
956  // strain invariants
957  Vector<double> dWdI(3, 0.0);
959 
960 
961  // Only bother to compute the tensor B^{ij} (Green & Zerna notation)
962  // if the derivative wrt the second strain invariant is non-zero
963  DenseMatrix<double> Bup(dim, dim, 0.0);
964  if (std::fabs(dWdI[1]) > 0.0)
965  {
966  for (unsigned i = 0; i < dim; i++)
967  {
968  for (unsigned j = 0; j < dim; j++)
969  {
970  Bup(i, j) = I[0] * gup(i, j);
971  for (unsigned r = 0; r < dim; r++)
972  {
973  for (unsigned s = 0; s < dim; s++)
974  {
975  Bup(i, j) -= gup(i, r) * gup(j, s) * G(r, s);
976  }
977  }
978  }
979  }
980  }
981 
982  // Now set the values of the functions phi, psi and p (Green & Zerna
983  // notation) Note that the Green & Zerna stress \tau^{ij} is
984  // s^{ij}/sqrt(I[2]), where s^{ij} is the desired second Piola-Kirchhoff
985  // stress tensor so we multiply their constants by sqrt(I[2])
986  double phi = 2.0 * dWdI[0];
987  double psi = 2.0 * dWdI[1];
988  double p = 2.0 * dWdI[2] * I[2];
989 
990  // Put it all together to get the stress
991  for (unsigned i = 0; i < dim; i++)
992  {
993  for (unsigned j = 0; j < dim; j++)
994  {
995  sigma(i, j) = phi * gup(i, j) + psi * Bup(i, j) + p * Gup(i, j);
996  }
997  }
998  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
JacobiRotation< float > G
Definition: Jacobi_makeGivens.cpp:2
float * p
Definition: Tutorial_Map_using.cpp:9
void error_checking_in_input(const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma)
Definition: constitutive_laws.cc:71
double calculate_contravariant(const DenseMatrix< double > &Gcov, DenseMatrix< double > &Gcontra)
The function to calculate the contravariant tensor from a covariant one.
Definition: constitutive_laws.cc:113
unsigned long nrow() const
Return the number of rows of the matrix.
Definition: matrices.h:485
virtual void derivatives(Vector< double > &I, Vector< double > &dWdI)
Definition: constitutive_laws.h:102
RealScalar s
Definition: level1_cplx_impl.h:130
#define I
Definition: main.h:127
r
Definition: UniformPSDSelfTest.py:20
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117
int sigma
Definition: calibrate.py:179
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
#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

References oomph::ConstitutiveLaw::calculate_contravariant(), oomph::StrainEnergyFunction::derivatives(), oomph::ConstitutiveLaw::error_checking_in_input(), boost::multiprecision::fabs(), G, i, I, j, oomph::DenseMatrix< T >::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, p, UniformPSDSelfTest::r, s, calibrate::sigma, Strain_energy_function_pt, and oomph::Global_string_for_annotation::string().

◆ calculate_second_piola_kirchhoff_stress() [2/3]

void oomph::IsotropicStrainEnergyFunctionConstitutiveLaw::calculate_second_piola_kirchhoff_stress ( const DenseMatrix< double > &  g,
const DenseMatrix< double > &  G,
DenseMatrix< double > &  sigma_dev,
DenseMatrix< double > &  Gup,
double detG 
)
virtual

Calculate the deviatoric part \( \overline{ \sigma^{ij}}\) of the contravariant 2nd Piola Kirchhoff stress tensor \( \sigma^{ij}\). Also return the contravariant deformed metric tensor and the determinant of the deformed metric tensor. This form is appropriate for truly-incompressible materials for which \( \sigma^{ij} = - p G^{ij} +\overline{ \sigma^{ij}} \) where the "pressure" \( p \) is determined by \( \det G_{ij} - \det g_{ij} = 0 \).

Calculate the deviatoric part \( \overline{ \sigma^{ij}}\) of the contravariant 2nd Piola Kirchhoff stress tensor \( \sigma^{ij}\). Also return the contravariant deformed metric tensor and the determinant of the deformed metric tensor. Uses correct 3D invariants for 2D (plane strain) problems. This is the version for the pure incompressible formulation.

Reimplemented from oomph::ConstitutiveLaw.

1015  {
1016 // Error checking
1017 #ifdef PARANOID
1018  error_checking_in_input(g, G, sigma_dev);
1019 #endif
1020 
1021  // Find the dimension of the problem
1022  unsigned dim = g.nrow();
1023 
1024 
1025 #ifdef PARANOID
1026  if (dim == 1)
1027  {
1028  std::string function_name =
1029  "IsotropicStrainEnergyFunctionConstitutiveLaw::";
1030  function_name += "calculate_second_piola_kirchhoff_stress()";
1031 
1032  throw OomphLibError("Check constitutive equations carefully when dim=1",
1035  }
1036 #endif
1037 
1038  // Calculate the contravariant undeformed and deformed metric tensors
1039  DenseMatrix<double> gup(dim);
1040  // Don't need this determinant
1041  (void)calculate_contravariant(g, gup);
1042  // These are passed back
1043  detG = calculate_contravariant(G, Gup);
1044 
1045  // Calculate the strain invariants
1046  Vector<double> I(3, 0.0);
1047  // The third strain invaraint must be one (incompressibility)
1048  I[2] = 1.0;
1049  // The first and second are a bit more complex
1050  for (unsigned i = 0; i < dim; i++)
1051  {
1052  for (unsigned j = 0; j < dim; j++)
1053  {
1054  I[0] += gup(i, j) * G(i, j);
1055  I[1] += g(i, j) * Gup(i, j);
1056  }
1057  }
1058 
1059  // If 2D we assume plane strain: In this case the 3D tensors have
1060  // a 1 on the diagonal and zeroes in the off-diagonals of their
1061  // third rows and columns. Only effect: Increase the first two
1062  // invariants by one; rest of the computation can just be performed
1063  // over the 2d set of coordinates.
1064  if (dim == 2)
1065  {
1066  I[0] += 1.0;
1067  I[1] += 1.0;
1068  }
1069 
1070  // Calculate the derivatives of the strain energy function wrt the
1071  // strain invariants
1072  Vector<double> dWdI(3, 0.0);
1074 
1075  // Only bother to compute the tensor B^{ij} (Green & Zerna notation)
1076  // if the derivative wrt the second strain invariant is non-zero
1077  DenseMatrix<double> Bup(dim, dim, 0.0);
1078  if (std::fabs(dWdI[1]) > 0.0)
1079  {
1080  for (unsigned i = 0; i < dim; i++)
1081  {
1082  for (unsigned j = 0; j < dim; j++)
1083  {
1084  Bup(i, j) = I[0] * gup(i, j);
1085  for (unsigned r = 0; r < dim; r++)
1086  {
1087  for (unsigned s = 0; s < dim; s++)
1088  {
1089  Bup(i, j) -= gup(i, r) * gup(j, s) * G(r, s);
1090  }
1091  }
1092  }
1093  }
1094  }
1095 
1096  // Now set the values of the functions phi and psi (Green & Zerna notation)
1097  double phi = 2.0 * dWdI[0];
1098  double psi = 2.0 * dWdI[1];
1099  // Calculate the trace/dim of the first two terms of the stress tensor
1100  // phi g^{ij} + psi B^{ij} (see Green & Zerna)
1101  double K;
1102  // In two-d, we cannot use the strain invariants directly
1103  // but can use symmetry of the tensors involved
1104  if (dim == 2)
1105  {
1106  K = 0.5 * ((I[0] - 1.0) * phi +
1107  psi * (Bup(0, 0) * G(0, 0) + Bup(1, 1) * G(1, 1) +
1108  2.0 * Bup(0, 1) * G(0, 1)));
1109  }
1110  // In three-d we can make use of the strain invariants, see Green & Zerna
1111  else
1112  {
1113  K = (I[0] * phi + 2.0 * I[1] * psi) / 3.0;
1114  }
1115 
1116  // Put it all together to get the stress, subtracting the trace of the
1117  // first two terms to ensure that the stress is deviatoric, which means
1118  // that the computed pressure is the mechanical pressure
1119  for (unsigned i = 0; i < dim; i++)
1120  {
1121  for (unsigned j = 0; j < dim; j++)
1122  {
1123  sigma_dev(i, j) = phi * gup(i, j) + psi * Bup(i, j) - K * Gup(i, j);
1124  }
1125  }
1126  }
double K
Wave number.
Definition: sphere_scattering.cc:115

References oomph::ConstitutiveLaw::calculate_contravariant(), oomph::StrainEnergyFunction::derivatives(), oomph::ConstitutiveLaw::error_checking_in_input(), boost::multiprecision::fabs(), G, i, I, j, PlanarWave::K, oomph::DenseMatrix< T >::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, UniformPSDSelfTest::r, s, Strain_energy_function_pt, and oomph::Global_string_for_annotation::string().

◆ calculate_second_piola_kirchhoff_stress() [3/3]

void oomph::IsotropicStrainEnergyFunctionConstitutiveLaw::calculate_second_piola_kirchhoff_stress ( const DenseMatrix< double > &  g,
const DenseMatrix< double > &  G,
DenseMatrix< double > &  sigma_dev,
DenseMatrix< double > &  Gup,
double gen_dil,
double inv_kappa 
)
virtual

Calculate the deviatoric part of the contravariant 2nd Piola Kirchoff stress tensor. Also return the contravariant deformed metric tensor, the generalised dilatation, \( d, \) and the inverse of the bulk modulus \( \kappa\). This form is appropriate for near-incompressible materials for which \( \sigma^{ij} = -p G^{ij} + \overline{ \sigma^{ij}} \) where the "pressure" \( p \) is determined from \( p / \kappa - d =0 \).

Calculate the deviatoric part of the contravariant 2nd Piola Kirchoff stress tensor. Also return the contravariant deformed metric tensor, the generalised dilatation, \( d, \) and the inverse of the bulk modulus \( \kappa\). Uses correct 3D invariants for 2D (plane strain) problems. This is the version for the near-incompressible formulation.

Reimplemented from oomph::ConstitutiveLaw.

1143  {
1144 // Error checking
1145 #ifdef PARANOID
1146  error_checking_in_input(g, G, sigma_dev);
1147 #endif
1148 
1149  // Find the dimension of the problem
1150  unsigned dim = g.nrow();
1151 
1152 #ifdef PARANOID
1153  if (dim == 1)
1154  {
1155  std::string function_name =
1156  "IsotropicStrainEnergyFunctionConstitutiveLaw::";
1157  function_name += "calculate_second_piola_kirchhoff_stress()";
1158 
1159  throw OomphLibError("Check constitutive equations carefully when dim=1",
1162  }
1163 #endif
1164 
1165  // Calculate the contravariant undeformed and deformed metric tensors
1166  // and get the determinants of the metric tensors
1167  DenseMatrix<double> gup(dim);
1168  double detg = calculate_contravariant(g, gup);
1169  double detG = calculate_contravariant(G, Gup);
1170 
1171  // Calculate the strain invariants
1172  Vector<double> I(3, 0.0);
1173  // The third strain invaraint is the volumetric change
1174  I[2] = detG / detg;
1175  // The first and second are a bit more complex --- see G&Z
1176  for (unsigned i = 0; i < dim; i++)
1177  {
1178  for (unsigned j = 0; j < dim; j++)
1179  {
1180  I[0] += gup(i, j) * G(i, j);
1181  I[1] += g(i, j) * Gup(i, j);
1182  }
1183  }
1184 
1185  // If 2D we assume plane strain: In this case the 3D tensors have
1186  // a 1 on the diagonal and zeroes in the off-diagonals of their
1187  // third rows and columns. Only effect: Increase the first two
1188  // invariants by one; rest of the computation can just be performed
1189  // over the 2d set of coordinates.
1190  if (dim == 2)
1191  {
1192  I[0] += 1.0;
1193  I[1] += 1.0;
1194  }
1195 
1196  // Second strain invariant is multiplied by the third.
1197  I[1] *= I[2];
1198 
1199  // Calculate the derivatives of the strain energy function wrt the
1200  // strain invariants
1201  Vector<double> dWdI(3, 0.0);
1203 
1204  // Only bother to calculate the tensor B^{ij} (Green & Zerna notation)
1205  // if the derivative wrt the second strain invariant is non-zero
1206  DenseMatrix<double> Bup(dim, dim, 0.0);
1207  if (std::fabs(dWdI[1]) > 0.0)
1208  {
1209  for (unsigned i = 0; i < dim; i++)
1210  {
1211  for (unsigned j = 0; j < dim; j++)
1212  {
1213  Bup(i, j) = I[0] * gup(i, j);
1214  for (unsigned r = 0; r < dim; r++)
1215  {
1216  for (unsigned s = 0; s < dim; s++)
1217  {
1218  Bup(i, j) -= gup(i, r) * gup(j, s) * G(r, s);
1219  }
1220  }
1221  }
1222  }
1223  }
1224 
1225  // Now set the values of the functions phi and psi (Green & Zerna notation)
1226  // but multiplied by sqrt(I[2]) to recover the second Piola-Kirchhoff stress
1227  double phi = 2.0 * dWdI[0];
1228  double psi = 2.0 * dWdI[1];
1229 
1230  // Calculate the trace/dim of the first two terms of the stress tensor
1231  // phi g^{ij} + psi B^{ij} (see Green & Zerna)
1232  double K;
1233  // In two-d, we cannot use the strain invariants directly,
1234  // but we can use symmetry of the tensors involved
1235  if (dim == 2)
1236  {
1237  K = 0.5 * ((I[0] - 1.0) * phi +
1238  psi * (Bup(0, 0) * G(0, 0) + Bup(1, 1) * G(1, 1) +
1239  2.0 * Bup(0, 1) * G(0, 1)));
1240  }
1241  // In three-d we can make use of the strain invariants
1242  else
1243  {
1244  K = (I[0] * phi + 2.0 * I[1] * psi) / 3.0;
1245  }
1246 
1247  // Choose inverse kappa to be one...
1248  inv_kappa = 1.0;
1249 
1250  //...then the generalised dilation is the same as p in Green & Zerna's
1251  // notation, but multiplied by sqrt(I[2]) with the addition of the
1252  // terms that are subtracted to make the other part of the stress
1253  // deviatoric
1254  gen_dil = 2.0 * dWdI[2] * I[2] + K;
1255 
1256  // Calculate the deviatoric part of the stress by subtracting
1257  // the computed trace/dim
1258  for (unsigned i = 0; i < dim; i++)
1259  {
1260  for (unsigned j = 0; j < dim; j++)
1261  {
1262  sigma_dev(i, j) = phi * gup(i, j) + psi * Bup(i, j) - K * Gup(i, j);
1263  }
1264  }
1265  }

References oomph::ConstitutiveLaw::calculate_contravariant(), oomph::StrainEnergyFunction::derivatives(), oomph::ConstitutiveLaw::error_checking_in_input(), boost::multiprecision::fabs(), G, i, I, j, PlanarWave::K, oomph::DenseMatrix< T >::nrow(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, UniformPSDSelfTest::r, s, Strain_energy_function_pt, and oomph::Global_string_for_annotation::string().

◆ requires_incompressibility_constraint()

bool oomph::IsotropicStrainEnergyFunctionConstitutiveLaw::requires_incompressibility_constraint ( )
inlinevirtual

State if the constitutive equation requires an incompressible formulation in which the volume constraint is enforced explicitly. Used as a sanity check in PARANOID mode. This is determined by interrogating the associated strain energy function.

Implements oomph::ConstitutiveLaw.

862  {
864  }
virtual bool requires_incompressibility_constraint()=0

References oomph::StrainEnergyFunction::requires_incompressibility_constraint(), and Strain_energy_function_pt.

Member Data Documentation

◆ Strain_energy_function_pt

StrainEnergyFunction* oomph::IsotropicStrainEnergyFunctionConstitutiveLaw::Strain_energy_function_pt
private

Pointer to the strain energy function.

Referenced by calculate_second_piola_kirchhoff_stress(), and requires_incompressibility_constraint().


The documentation for this class was generated from the following files: