756 {
758
759 auto neohookean_ptr =
760 boost::dynamic_pointer_cast<HMHNeohookean>(
dataAtPts->physicsPtr);
761 if (!neohookean_ptr) {
763 "Pointer to HMHNeohookean is null");
764 }
765 auto [def_c10, def_K] =
767
768 const double c10 = def_c10;
769 const double alpha_u =
alphaU;
770 const double bulk_modulus = def_K;
771 const double alpha_grad_u = neohookean_ptr->alphaGradU;
772
774
776
779
780 int nb_integration_pts = row_data.
getN().size1();
781 int row_nb_dofs = row_data.
getIndices().size();
782 int col_nb_dofs = col_data.
getIndices().size();
783
787
788 &
m(r + 0,
c + 0), &
m(r + 0,
c + 1), &
m(r + 0,
c + 2), &
m(r + 0,
c + 3),
789 &
m(r + 0,
c + 4), &
m(r + 0,
c + 5),
790
791 &
m(r + 1,
c + 0), &
m(r + 1,
c + 1), &
m(r + 1,
c + 2), &
m(r + 1,
c + 3),
792 &
m(r + 1,
c + 4), &
m(r + 1,
c + 5),
793
794 &
m(r + 2,
c + 0), &
m(r + 2,
c + 1), &
m(r + 2,
c + 2), &
m(r + 2,
c + 3),
795 &
m(r + 2,
c + 4), &
m(r + 2,
c + 5),
796
797 &
m(r + 3,
c + 0), &
m(r + 3,
c + 1), &
m(r + 3,
c + 2), &
m(r + 3,
c + 3),
798 &
m(r + 3,
c + 4), &
m(r + 3,
c + 5),
799
800 &
m(r + 4,
c + 0), &
m(r + 4,
c + 1), &
m(r + 4,
c + 2), &
m(r + 4,
c + 3),
801 &
m(r + 4,
c + 4), &
m(r + 4,
c + 5),
802
803 &
m(r + 5,
c + 0), &
m(r + 5,
c + 1), &
m(r + 5,
c + 2), &
m(r + 5,
c + 3),
804 &
m(r + 5,
c + 4), &
m(r + 5,
c + 5)
805
806 );
807 };
808
810
814
815 int row_nb_base_functions = row_data.
getN().size2();
818
819 auto t_diff_u =
dataAtPts->getFTensorDiffStretch(nb_integration_pts);
820 auto t_log_u2_h1 =
dataAtPts->getFTensorLogStretch2H1(nb_integration_pts);
821 auto t_u =
dataAtPts->getFTensorStretch(nb_integration_pts);
822 auto t_approx_P_adjoint_dstretch =
823 dataAtPts->getFTensorAdjointPdstretch(nb_integration_pts);
824 auto t_eigen_vals =
dataAtPts->getFTensorEigenVals(nb_integration_pts);
825 auto t_eigen_vecs =
dataAtPts->getFTensorEigenVecs(nb_integration_pts);
827 auto t_nb_uniq =
829
830 auto no_h1 = [&]() {
832
833 for (int gg = 0; gg != nb_integration_pts; ++gg) {
835 ++t_w;
836
837 const auto principal_state =
840 auto coordinate_stress = [c10, principal_state](
const double v) {
842 };
843 auto coordinate_stress_derivative = [c10,
844 principal_state](
const double v) {
846 c10, principal_state,
v);
847 };
848 auto squared_stretch = [](
const double v) {
return std::exp(2. *
v); };
849 auto identity = [](
const double) {
return 1.; };
850 auto isochoric_coordinate_stress = [c10,
851 principal_state](
const double v) {
852 return getShearModulus(c10) * principal_state.jacobianToMinusTwoThirds *
853 (std::exp(2. *
v) - principal_state.firstInvariant / 3.);
854 };
855 auto t_diff_neohookean =
857 coordinate_stress_derivative, t_nb_uniq);
858 auto t_squared_stretch =
860 auto t_identity =
863 t_eigen_vals, t_eigen_vecs, isochoric_coordinate_stress);
864 const double scaled_shear_modulus =
867 t_material_tangent(
i,
j,
k,
l) =
868 t_diff_neohookean(
i,
j,
k,
l) -
869 (2. / 3.) * t_isochoric_coordinate_stress(
i,
j) * t_identity(
k,
l) -
870 (2. / 3.) * scaled_shear_modulus * t_identity(
i,
j) *
871 t_squared_stretch(
k,
l) +
872 principal_state.volumetricTangent * t_identity(
i,
j) *
874
877 t_L(
i,
j, L) * (t_material_tangent(
i,
j,
k,
l) * t_L(
k,
l,
J));
878 t_dP(L,
J) += (alpha_u * ts_a) *
879 (t_L(
i,
j, L) * (t_diff(
i,
j,
k,
l) * t_L(
k,
l,
J)));
880
882 t_deltaP(
i,
j) = (t_approx_P_adjoint_dstretch(
i,
j) ||
883 t_approx_P_adjoint_dstretch(
j,
i)) /
884 2.;
886 t_eigen_vals, t_eigen_vecs, static_cast<double (*)(double)>(std::exp),
887 static_cast<double (*)(double)>(std::exp),
888 static_cast<double (*)(double)>(std::exp), t_deltaP, t_nb_uniq);
889 t_dP(L,
J) -= t_L(
i,
j, L) * (t_diff2_uP(
i,
j,
k,
l) * t_L(
k,
l,
J));
890 ++t_approx_P_adjoint_dstretch;
891 ++t_eigen_vals;
892 ++t_eigen_vecs;
893 ++t_nb_uniq;
894
897
898
900 t_hessian_eig_vecs(L,
J) = 0.5 * (t_dP(L,
J) + t_dP(
J, L));
903 t_hessian_eig_vals);
905 bool project_hessian = false;
906 for (
int aa = 0; aa !=
size_symm; ++aa) {
907 project_hessian =
908 project_hessian || t_hessian_eig_vals(aa) < eigenvalue_floor;
909 }
910 if (project_hessian) {
911 auto min_eig_val = [eigenvalue_floor](
double v) {
912 return (
v + eigenvalue_floor + std::abs(
v - eigenvalue_floor)) / 2.;
913 };
915 t_hessian_eig_vals, t_hessian_eig_vecs, min_eig_val);
916 t_dP(L,
J) = t_dP_min_eig(L,
J);
917 }
918 }
919
920 int rr = 0;
921 for (; rr != row_nb_dofs /
size_symm; ++rr) {
924
925 auto t_m = get_ftensor2(
K, 6 * rr, 0);
926 for (
int cc = 0; cc != col_nb_dofs /
size_symm; ++cc) {
927 double b = t_row_base_fun * t_col_base_fun;
928 t_m(L,
J) += b * t_dP(L,
J);
929 double c = (
a * alpha_grad_u * ts_a) *
930 (t_row_grad_fun(
i) * t_col_grad_fun(
i));
931 t_m(L,
J) +=
c * t_kd_sym(L,
J);
932
933 ++t_m;
934 ++t_col_base_fun;
935 ++t_col_grad_fun;
936 }
937 ++t_row_base_fun;
938 ++t_row_grad_fun;
939 }
940
941 for (; rr != row_nb_base_functions; ++rr) {
942 ++t_row_base_fun;
943 ++t_row_grad_fun;
944 }
945 }
947 };
948
949 auto large = [&]() {
952 "Not implemented for Neo-Hookean (used ADOL-C)");
954 };
955
959 break;
963 break;
964 default:
966 "gradApproximator not handled");
967 };
968
970}
#define FTENSOR_INDEXES(DIM,...)
Fourth-order differential tensor symmetric in both index pairs.
Kronecker Delta class symmetric.
Mapping from symmetric tensor indices to packed storage index.
@ MOFEM_DATA_INCONSISTENCY
FTensor::Index< 'i', SPACE_DIM > i
const double c
speed of light (cm/ns)
const double v
phase velocity of light in medium (cm/ns)
const double n
refractive index of diffusive medium
FTensor::Index< 'J', DIM1 > J
FTensor::Index< 'l', 3 > l
FTensor::Index< 'j', 3 > j
FTensor::Index< 'k', 3 > k
auto getMat(A &&t_val, B &&t_vec, Fun< double > f)
Get the Mat object.
auto getDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, const int nb)
Get the Diff Mat object.
auto getDiffDiffMat(A &&t_val, B &&t_vec, Fun< double > f, Fun< double > d_f, Fun< double > dd_f, C &&t_S, const int nb)
Get the Diff Diff Mat object.
static constexpr auto size_symm
UBlasMatrix< double > MatrixDouble
MoFEMErrorCode computeEigenValuesSymmetric(const MatrixDouble &mat, VectorDouble &eig, MatrixDouble &eigen_vec)
compute eigenvalues of a symmetric matrix using lapack dsyev
FTensor::Index< 'm', 3 > m
static enum RotSelector gradApproximator
static double getShearModulus(const double c10)
static MoFEMErrorCode validatePrincipalState(const PrincipalState &state, const char *source)
static double getPrincipalCoordinateStressDerivativeAtFixedInvariants(const double c10, const PrincipalState &state, const double v)
static double getPrincipalCoordinateStress(const double c10, const PrincipalState &state, const double v)
static PrincipalState getPrincipalState(const double K, T &principal_coordinate_stretches)
FTensor::Tensor0< FTensor::PackPtr< double *, 1 > > getFTensor0N(const FieldApproximationBase base)
Get base function as Tensor0.
auto getFTensor1DiffN(const FieldApproximationBase base)
Get derivatives of base functions.
MatrixDouble & getN(const FieldApproximationBase base)
get base functions this return matrix (nb. of rows is equal to nb. of Gauss pts, nb....
const VectorInt & getIndices() const
Get global indices of degrees of freedom on entity.
EntityHandle getFEEntityHandle() const
Return finite element entity handle.
auto getFTensor0IntegrationWeight()
Get integration weights.
double getVolume() const
element volume (linear geometry)
MatrixDouble K
local tangent matrix
boost::shared_ptr< DataAtIntegrationPts > dataAtPts
data at integration pts