29 #include "../generic/elements.h"
79 OOMPH_CURRENT_FUNCTION,
80 OOMPH_EXCEPTION_LOCATION);
87 std::string error_message =
"Deformed metric tensor does \n";
89 "not have same dimensions as the undeformed metric tensor\n";
92 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
100 "Strain tensor passed to calculate_green_strain() does \n";
102 "not have same dimensions as the undeformed metric tensor\n";
105 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
121 throw OomphLibError(
"Matrices passed to calculate_contravariant() are "
122 "not of equal dimension",
123 OOMPH_CURRENT_FUNCTION,
124 OOMPH_EXCEPTION_LOCATION);
129 unsigned dim = Gdown.
ncol();
136 "Matrix passed to calculate_contravariant() is not square\n";
137 error_message +=
"non-square matrix inversion not implemented yet!\n";
140 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
153 OOMPH_CURRENT_FUNCTION,
154 OOMPH_EXCEPTION_LOCATION);
162 Gup(0, 0) = 1.0 / Gdown(0, 0);
169 det = Gdown(0, 0) * Gdown(1, 1) - Gdown(0, 1) * Gdown(1, 0);
171 Gup(0, 0) = Gdown(1, 1) / det;
172 Gup(0, 1) = -Gdown(0, 1) / det;
173 Gup(1, 0) = -Gdown(1, 0) / det;
174 Gup(1, 1) = Gdown(0, 0) / det;
180 det = Gdown(0, 0) * Gdown(1, 1) * Gdown(2, 2) +
181 Gdown(0, 1) * Gdown(1, 2) * Gdown(2, 0) +
182 Gdown(0, 2) * Gdown(1, 0) * Gdown(2, 1) -
183 Gdown(0, 0) * Gdown(1, 2) * Gdown(2, 1) -
184 Gdown(0, 1) * Gdown(1, 0) * Gdown(2, 2) -
185 Gdown(0, 2) * Gdown(1, 1) * Gdown(2, 0);
189 (Gdown(1, 1) * Gdown(2, 2) - Gdown(1, 2) * Gdown(2, 1)) / det;
191 -(Gdown(0, 1) * Gdown(2, 2) - Gdown(0, 2) * Gdown(2, 1)) / det;
193 (Gdown(0, 1) * Gdown(1, 2) - Gdown(0, 2) * Gdown(1, 1)) / det;
195 -(Gdown(1, 0) * Gdown(2, 2) - Gdown(1, 2) * Gdown(2, 0)) / det;
197 (Gdown(0, 0) * Gdown(2, 2) - Gdown(0, 2) * Gdown(2, 0)) / det;
199 -(Gdown(0, 0) * Gdown(1, 2) - Gdown(0, 2) * Gdown(1, 0)) / det;
201 (Gdown(1, 0) * Gdown(2, 1) - Gdown(1, 1) * Gdown(2, 0)) / det;
203 -(Gdown(0, 0) * Gdown(2, 1) - Gdown(0, 1) * Gdown(2, 0)) / det;
205 (Gdown(0, 0) * Gdown(1, 1) - Gdown(0, 1) * Gdown(1, 0)) / det;
209 throw OomphLibError(
"Dimension of matrix must be 0, 1, 2 or 3\n",
210 OOMPH_CURRENT_FUNCTION,
211 OOMPH_EXCEPTION_LOCATION);
231 const unsigned dim = Gdown.
ncol();
238 "Matrix passed to calculate_contravariant() is not square\n";
239 error_message +=
"non-square matrix inversion not implemented yet!\n";
242 error_message, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
255 OOMPH_CURRENT_FUNCTION,
256 OOMPH_EXCEPTION_LOCATION);
262 d_detG_dG(0, 0) = 1.0;
263 d_Gup_dG(0, 0, 0, 0) = -1.0 / (Gdown(0, 0) * Gdown(0, 0));
270 det = Gdown(0, 0) * Gdown(1, 1) - Gdown(0, 1) * Gdown(1, 0);
273 d_detG_dG(0, 0) = Gdown(1, 1);
275 d_detG_dG(0, 1) = d_detG_dG(1, 0) = -2.0 * Gdown(0, 1);
276 d_detG_dG(1, 1) = Gdown(0, 0);
281 const double det2 = det * det;
282 d_Gup_dG(0, 0, 0, 0) = -Gdown(1, 1) * d_detG_dG(0, 0) / det2;
283 d_Gup_dG(0, 0, 0, 1) = -Gdown(1, 1) * d_detG_dG(0, 1) / det2;
284 d_Gup_dG(0, 0, 1, 1) =
285 1.0 / det - Gdown(1, 1) * d_detG_dG(1, 1) / det2;
287 d_Gup_dG(0, 1, 0, 0) = Gdown(0, 1) * d_detG_dG(0, 0) / det2;
288 d_Gup_dG(0, 1, 0, 1) =
289 -1.0 / det + Gdown(0, 1) * d_detG_dG(0, 1) / det2;
290 d_Gup_dG(0, 1, 1, 1) = Gdown(0, 1) * d_detG_dG(1, 1) / det2;
292 d_Gup_dG(1, 1, 0, 0) =
293 1.0 / det - Gdown(0, 0) * d_detG_dG(0, 0) / det2;
294 d_Gup_dG(1, 1, 0, 1) = -Gdown(0, 0) * d_detG_dG(0, 1) / det2;
295 d_Gup_dG(1, 1, 1, 1) = -Gdown(0, 0) * d_detG_dG(1, 1) / det2;
309 "Analytic derivatives of metric tensors not yet implemented in 3D\n",
310 OOMPH_CURRENT_FUNCTION,
311 OOMPH_EXCEPTION_LOCATION);
314 det = Gdown(0, 0) * Gdown(1, 1) * Gdown(2, 2) +
315 Gdown(0, 1) * Gdown(1, 2) * Gdown(2, 0) +
316 Gdown(0, 2) * Gdown(1, 0) * Gdown(2, 1) -
317 Gdown(0, 0) * Gdown(1, 2) * Gdown(2, 1) -
318 Gdown(0, 1) * Gdown(1, 0) * Gdown(2, 2) -
319 Gdown(0, 2) * Gdown(1, 1) * Gdown(2, 0);
334 throw OomphLibError(
"Dimension of matrix must be 0, 1, 2 or 3\n",
335 OOMPH_CURRENT_FUNCTION,
336 OOMPH_EXCEPTION_LOCATION);
357 const bool& symmetrize_tensor)
364 throw OomphLibError(
"Matrices passed are not of equal dimension",
365 OOMPH_CURRENT_FUNCTION,
366 OOMPH_EXCEPTION_LOCATION);
371 const unsigned dim = G.
ncol();
382 for (
unsigned i = 0;
i < dim;
i++)
384 for (
unsigned j = 0; j < dim; j++)
386 G_pls(
i, j) = G(
i, j);
396 for (
unsigned i = 0;
i < dim;
i++)
398 for (
unsigned j =
i; j < dim; j++)
400 G_pls(
i, j) += eps_fd;
401 G_pls(j,
i) = G_pls(
i, j);
406 for (
unsigned ii = 0; ii < dim; ii++)
408 for (
unsigned jj = ii; jj < dim; jj++)
410 d_sigma_dG(ii, jj,
i, j) =
411 (sigma_pls(ii, jj) - sigma(ii, jj)) / eps_fd;
416 G_pls(
i, j) = G(
i, j);
417 G_pls(j,
i) = G(j,
i);
422 if (symmetrize_tensor)
424 for (
unsigned i = 0;
i < dim;
i++)
426 for (
unsigned j = 0; j <
i; j++)
428 for (
unsigned ii = 0; ii < dim; ii++)
430 for (
unsigned jj = 0; jj < ii; jj++)
432 d_sigma_dG(ii, jj,
i, j) = d_sigma_dG(jj, ii, j,
i);
458 const double& interpolated_solid_p,
461 const bool& symmetrize_tensor)
468 throw OomphLibError(
"Matrices passed are not of equal dimension",
469 OOMPH_CURRENT_FUNCTION,
470 OOMPH_EXCEPTION_LOCATION);
475 const unsigned dim = G.
ncol();
487 for (
unsigned i = 0;
i < dim;
i++)
489 for (
unsigned j = 0; j < dim; j++)
491 G_pls(
i, j) = G(
i, j);
501 for (
unsigned i = 0;
i < dim;
i++)
503 for (
unsigned j =
i; j < dim; j++)
505 G_pls(
i, j) += eps_fd;
506 G_pls(j,
i) = G_pls(
i, j);
510 g, G_pls, sigma_dev_pls, Gup_pls, detG_pls);
514 d_detG_dG(
i, j) = (detG_pls - detG) / eps_fd;
518 for (
unsigned ii = 0; ii < dim; ii++)
520 for (
unsigned jj = ii; jj < dim; jj++)
522 d_sigma_dG(ii, jj,
i, j) =
523 (sigma_dev_pls(ii, jj) - interpolated_solid_p * Gup_pls(ii, jj) -
530 G_pls(
i, j) = G(
i, j);
531 G_pls(j,
i) = G(j,
i);
536 if (symmetrize_tensor)
538 for (
unsigned i = 0;
i < dim;
i++)
540 for (
unsigned j = 0; j <
i; j++)
542 d_detG_dG(
i, j) = d_detG_dG(j,
i);
544 for (
unsigned ii = 0; ii < dim; ii++)
546 for (
unsigned jj = 0; jj < ii; jj++)
548 d_sigma_dG(ii, jj,
i, j) = d_sigma_dG(jj, ii, j,
i);
570 const double& gen_dil,
571 const double& inv_kappa,
572 const double& interpolated_solid_p,
575 const bool& symmetrize_tensor)
582 throw OomphLibError(
"Matrices passed are not of equal dimension",
583 OOMPH_CURRENT_FUNCTION,
584 OOMPH_EXCEPTION_LOCATION);
589 const unsigned dim = G.
ncol();
599 double inv_kappa_pls;
602 for (
unsigned i = 0;
i < dim;
i++)
604 for (
unsigned j = 0; j < dim; j++)
606 G_pls(
i, j) = G(
i, j);
616 for (
unsigned i = 0;
i < dim;
i++)
618 for (
unsigned j =
i; j < dim; j++)
620 G_pls(
i, j) += eps_fd;
621 G_pls(j,
i) = G_pls(
i, j);
625 g, G_pls, sigma_dev_pls, Gup_pls, gen_dil_pls, inv_kappa_pls);
628 d_gen_dil_dG(
i, j) = (gen_dil_pls - gen_dil) / eps_fd;
632 for (
unsigned ii = 0; ii < dim; ii++)
634 for (
unsigned jj = ii; jj < dim; jj++)
636 d_sigma_dG(ii, jj,
i, j) =
637 (sigma_dev_pls(ii, jj) - interpolated_solid_p * Gup_pls(ii, jj) -
644 G_pls(
i, j) = G(
i, j);
645 G_pls(j,
i) = G(j,
i);
650 if (symmetrize_tensor)
652 for (
unsigned i = 0;
i < dim;
i++)
654 for (
unsigned j = 0; j <
i; j++)
656 d_gen_dil_dG(
i, j) = d_gen_dil_dG(j,
i);
658 for (
unsigned ii = 0; ii < dim; ii++)
660 for (
unsigned jj = 0; jj < ii; jj++)
662 d_sigma_dG(ii, jj,
i, j) = d_sigma_dG(jj, ii, j,
i);
693 unsigned dim = G.
nrow();
701 double C1 = (*E_pt) / (2.0 * (1.0 + (*Nu_pt)));
702 double C2 = 2.0 * (*Nu_pt) / (1.0 - 2.0 * (*Nu_pt));
708 for (
unsigned i = 0;
i < dim;
i++)
710 for (
unsigned j =
i; j < dim; j++)
712 strain(
i, j) = 0.5 * (G(
i, j) - g(
i, j));
717 for (
unsigned i = 0;
i < dim;
i++)
719 for (
unsigned j = 0; j <
i; j++)
721 strain(
i, j) = strain(j,
i);
726 for (
unsigned i = 0;
i < dim;
i++)
728 for (
unsigned j =
i; j < dim; j++)
732 for (
unsigned k = 0; k < dim; k++)
734 for (
unsigned l = 0; l < dim; l++)
737 (Gup(
i, k) * Gup(j, l) + Gup(
i, l) * Gup(j, k) +
738 C2 * Gup(
i, j) * Gup(k, l)) *
746 for (
unsigned i = 0;
i < dim;
i++)
748 for (
unsigned j = 0; j <
i; j++)
750 sigma(
i, j) = sigma(j,
i);
774 unsigned dim = G.
nrow();
785 (1.0 - 2.0 * (*Nu_pt)) * (1.0 + (*
Nu_pt)) / ((*
E_pt) * (*Nu_pt));
790 for (
unsigned i = 0;
i < dim;
i++)
792 for (
unsigned j = 0; j < dim; j++)
794 gen_dil += Gup(
i, j) * 0.5 * (G(
i, j) - g(
i, j));
824 unsigned dim = G.
nrow();
830 double C1 = (*E_pt) / (2.0 * (1.0 + (*Nu_pt)));
836 for (
unsigned i = 0;
i < dim;
i++)
838 for (
unsigned j =
i; j < dim; j++)
840 strain(
i, j) = 0.5 * (G(
i, j) - g(
i, j));
845 for (
unsigned i = 0;
i < dim;
i++)
847 for (
unsigned j = 0; j <
i; j++)
849 strain(
i, j) = strain(j,
i);
854 for (
unsigned i = 0;
i < dim;
i++)
856 for (
unsigned j =
i; j < dim; j++)
859 sigma_dev(
i, j) = 0.0;
860 for (
unsigned k = 0; k < dim; k++)
862 for (
unsigned l = 0; l < dim; l++)
864 sigma_dev(
i, j) += C1 *
865 (Gup(
i, k) * Gup(j, l) + Gup(
i, l) * Gup(j, k)) *
873 for (
unsigned i = 0;
i < dim;
i++)
875 for (
unsigned j = 0; j <
i; j++)
877 sigma_dev(
i, j) = sigma_dev(j,
i);
906 unsigned dim = g.
nrow();
912 "IsotropicStrainEnergyFunctionConstitutiveLaw::";
913 function_name +=
"calculate_second_piola_kirchhoff_stress()";
915 throw OomphLibError(
"Check constitutive equations carefully when dim=1",
916 OOMPH_CURRENT_FUNCTION,
917 OOMPH_EXCEPTION_LOCATION);
932 for (
unsigned i = 0;
i < dim;
i++)
934 for (
unsigned j = 0; j < dim; j++)
936 I[0] += gup(
i, j) * G(
i, j);
937 I[1] += g(
i, j) * Gup(
i, j);
964 if (std::fabs(dWdI[1]) > 0.0)
966 for (
unsigned i = 0;
i < dim;
i++)
968 for (
unsigned j = 0; j < dim; j++)
970 Bup(
i, j) =
I[0] * gup(
i, j);
971 for (
unsigned r = 0; r < dim; r++)
973 for (
unsigned s = 0;
s < dim;
s++)
975 Bup(
i, j) -= gup(
i, r) * gup(j,
s) * G(r,
s);
986 double phi = 2.0 * dWdI[0];
987 double psi = 2.0 * dWdI[1];
988 double p = 2.0 * dWdI[2] *
I[2];
991 for (
unsigned i = 0;
i < dim;
i++)
993 for (
unsigned j = 0; j < dim; j++)
995 sigma(
i, j) = phi * gup(
i, j) + psi * Bup(
i, j) + p * Gup(
i, j);
1022 unsigned dim = g.
nrow();
1029 "IsotropicStrainEnergyFunctionConstitutiveLaw::";
1030 function_name +=
"calculate_second_piola_kirchhoff_stress()";
1032 throw OomphLibError(
"Check constitutive equations carefully when dim=1",
1033 OOMPH_CURRENT_FUNCTION,
1034 OOMPH_EXCEPTION_LOCATION);
1050 for (
unsigned i = 0;
i < dim;
i++)
1052 for (
unsigned j = 0; j < dim; j++)
1054 I[0] += gup(
i, j) * G(
i, j);
1055 I[1] += g(
i, j) * Gup(
i, j);
1078 if (std::fabs(dWdI[1]) > 0.0)
1080 for (
unsigned i = 0;
i < dim;
i++)
1082 for (
unsigned j = 0; j < dim; j++)
1084 Bup(
i, j) =
I[0] * gup(
i, j);
1085 for (
unsigned r = 0; r < dim; r++)
1087 for (
unsigned s = 0;
s < dim;
s++)
1089 Bup(
i, j) -= gup(
i, r) * gup(j,
s) * G(r,
s);
1097 double phi = 2.0 * dWdI[0];
1098 double psi = 2.0 * dWdI[1];
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)));
1113 K = (
I[0] * phi + 2.0 *
I[1] * psi) / 3.0;
1119 for (
unsigned i = 0;
i < dim;
i++)
1121 for (
unsigned j = 0; j < dim; j++)
1123 sigma_dev(
i, j) = phi * gup(
i, j) + psi * Bup(
i, j) - K * Gup(
i, j);
1150 unsigned dim = g.
nrow();
1156 "IsotropicStrainEnergyFunctionConstitutiveLaw::";
1157 function_name +=
"calculate_second_piola_kirchhoff_stress()";
1159 throw OomphLibError(
"Check constitutive equations carefully when dim=1",
1160 OOMPH_CURRENT_FUNCTION,
1161 OOMPH_EXCEPTION_LOCATION);
1176 for (
unsigned i = 0;
i < dim;
i++)
1178 for (
unsigned j = 0; j < dim; j++)
1180 I[0] += gup(
i, j) * G(
i, j);
1181 I[1] += g(
i, j) * Gup(
i, j);
1207 if (std::fabs(dWdI[1]) > 0.0)
1209 for (
unsigned i = 0;
i < dim;
i++)
1211 for (
unsigned j = 0; j < dim; j++)
1213 Bup(
i, j) =
I[0] * gup(
i, j);
1214 for (
unsigned r = 0; r < dim; r++)
1216 for (
unsigned s = 0;
s < dim;
s++)
1218 Bup(
i, j) -= gup(
i, r) * gup(j,
s) * G(r,
s);
1227 double phi = 2.0 * dWdI[0];
1228 double psi = 2.0 * dWdI[1];
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)));
1244 K = (
I[0] * phi + 2.0 *
I[1] * psi) / 3.0;
1254 gen_dil = 2.0 * dWdI[2] *
I[2] + K;
1258 for (
unsigned i = 0;
i < dim;
i++)
1260 for (
unsigned j = 0; j < dim; j++)
1262 sigma_dev(
i, j) = phi * gup(
i, j) + psi * Bup(
i, j) - K * Gup(
i, j);
void error_checking_in_input(const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma)
Check for errors in the input, i.e. check that the dimensions of the arrays are all consistent.
double calculate_contravariant(const DenseMatrix< double > &Gcov, DenseMatrix< double > &Gcontra)
Calculate a contravariant tensor from a covariant tensor, and return the determinant of the covariant...
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)
Calculate the derivatives of the contravariant 2nd Piola Kirchhoff stress tensor with respect to the ...
void calculate_d_contravariant_dG(const DenseMatrix< double > &Gcov, RankFourTensor< double > &dGcontra_dG, DenseMatrix< double > &d_detG_dG)
Calculate the derivatives of the contravariant tensor and the derivatives of the determinant of the c...
bool is_matrix_square(const DenseMatrix< double > &M)
Test whether a matrix is square.
bool are_matrices_of_equal_dimensions(const DenseMatrix< double > &M1, const DenseMatrix< double > &M2)
Test whether two matrices are of equal dimensions.
virtual void calculate_second_piola_kirchhoff_stress(const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma)=0
Calculate the contravariant 2nd Piola Kirchhoff stress tensor. Arguments are the covariant undeformed...
unsigned long nrow() const
Return the number of rows of the matrix.
unsigned long ncol() const
Return the number of columns of the matrix.
static double Default_fd_jacobian_step
Double used for the default finite difference step in elemental jacobian calculations.
void calculate_second_piola_kirchhoff_stress(const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma)
Calculate the contravariant 2nd Piola Kirchhoff stress tensor. Arguments are the covariant undeformed...
double * E_pt
Young's modulus.
double * Nu_pt
Poisson ratio.
StrainEnergyFunction * Strain_energy_function_pt
Pointer to the strain energy function.
void calculate_second_piola_kirchhoff_stress(const DenseMatrix< double > &g, const DenseMatrix< double > &G, DenseMatrix< double > &sigma)
Calculate the contravariant 2nd Piola Kirchhoff stress tensor. Arguments are the covariant undeformed...
An OomphLibError object which should be thrown when an run-time error is encountered....
////////////////////////////////////////////////////////////////// //////////////////////////////////...
virtual void derivatives(Vector< double > &I, Vector< double > &dWdI)
Return the derivatives of the strain energy function with respect to the strain invariants....
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
const std::complex< double > I(0.0, 1.0)
The imaginary unit.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...