module StrainClass use, intrinsic :: iso_fortran_env use MathClass use ShapeFunctionClass implicit none type :: Strain_ ! Finite strain theory real(real64), allocatable :: F(:, :) real(real64), allocatable :: F_n(:, :) real(real64), allocatable :: C(:, :) real(real64), allocatable :: C_n(:, :) real(real64), allocatable :: b(:, :) real(real64), allocatable :: Cp(:, :) real(real64), allocatable ::Cp_n(:, :) real(real64) :: detF ! Hypo-elasto-plasticity real(real64), allocatable :: d(:, :) real(real64), allocatable ::de(:, :) real(real64), allocatable ::dp(:, :) real(real64), allocatable :: l(:, :) real(real64), allocatable :: w(:, :) ! small-strain real(real64), allocatable :: eps(:, :) real(real64), allocatable :: eps_n(:, :) real(real64), allocatable :: eps_p(:, :) real(real64), allocatable :: eps_p_n(:, :) real(real64), allocatable :: eps_e(:, :) real(real64), allocatable :: eps_e_n(:, :) integer(int32) :: TheoryID character*40 :: StrainTheory ! Please input one of following keyphrases ! Finite_Elasticity ! Finite_ElastoPlasticity ! Infinitesimal_Elasticity ! Infinitesimal_ElastoPlasticity ! Small_strain contains procedure, public :: init => InitStrain procedure, public :: import => importStrain procedure, public :: get => getStrain procedure, public :: getAll => getAllStrain procedure, public :: delete => deleteStrain end type contains ! ############################### subroutine InitStrain(obj, StrainTheory) class(Strain_), intent(inout) :: obj character(*), intent(in) :: StrainTheory real(real64) :: delta(3, 3) delta(:, :) = 0.0d0 delta(1, 1) = 1.0d0 delta(2, 2) = 1.0d0 delta(3, 3) = 1.0d0 if (allocated(obj%F)) then ! delete old obj call obj%delete() end if obj%StrainTheory = StrainTheory if (obj%StrainTheory == "Finite_Elasticity") then obj%theoryID = 1 ! Finite strain theory allocate (obj%F(3, 3)) allocate (obj%F_n(3, 3)) allocate (obj%C(3, 3)) allocate (obj%b(3, 3)) allocate (obj%C_n(3, 3)) allocate (obj%Cp(3, 3)) allocate (obj%Cp_n(3, 3)) ! Hypo-elasto-plasticity allocate (obj%d(0, 0)) allocate (obj%de(0, 0)) allocate (obj%dp(0, 0)) allocate (obj%l(0, 0)) allocate (obj%w(0, 0)) ! small-strain allocate (obj%eps(0, 0)) allocate (obj%eps_n(0, 0)) allocate (obj%eps_e(0, 0)) allocate (obj%eps_e_n(0, 0)) allocate (obj%eps_p(0, 0)) allocate (obj%eps_p_n(0, 0)) ! Initialize obj%F(:, :) = delta(:, :) obj%F_n(:, :) = delta(:, :) obj%C(:, :) = delta(:, :) obj%C_n(:, :) = delta(:, :) obj%Cp(:, :) = delta(:, :) obj%Cp_n(:, :) = delta(:, :) elseif (obj%StrainTheory == "Finite_ElastoPlasticity") then obj%theoryID = 2 ! Finite strain theory allocate (obj%F(3, 3)) allocate (obj%F_n(3, 3)) allocate (obj%C(3, 3)) allocate (obj%C_n(3, 3)) allocate (obj%b(3, 3)) allocate (obj%Cp(3, 3)) allocate (obj%Cp_n(3, 3)) ! Hypo-elasto-plasticity allocate (obj%d(0, 0)) allocate (obj%de(0, 0)) allocate (obj%dp(0, 0)) allocate (obj%l(0, 0)) allocate (obj%w(0, 0)) ! small-strain allocate (obj%eps(0, 0)) allocate (obj%eps_n(0, 0)) allocate (obj%eps_e(0, 0)) allocate (obj%eps_e_n(0, 0)) allocate (obj%eps_p(0, 0)) allocate (obj%eps_p_n(0, 0)) obj%F(:, :) = delta(:, :) obj%F_n(:, :) = delta(:, :) obj%C(:, :) = delta(:, :) obj%C_n(:, :) = delta(:, :) obj%Cp(:, :) = delta(:, :) obj%Cp_n(:, :) = delta(:, :) elseif (obj%StrainTheory == "Infinitesimal_Elasticity") then obj%theoryID = 3 ! Finite strain theory allocate (obj%F(0, 0)) allocate (obj%F_n(0, 0)) allocate (obj%C(0, 0)) allocate (obj%C_n(0, 0)) allocate (obj%b(0, 0)) allocate (obj%Cp(0, 0)) allocate (obj%Cp_n(0, 0)) ! Hypo-elasto-plasticity allocate (obj%d(3, 3)) allocate (obj%de(0, 0)) allocate (obj%dp(0, 0)) allocate (obj%l(3, 3)) allocate (obj%w(3, 3)) ! small-strain allocate (obj%eps(3, 3)) allocate (obj%eps_n(3, 3)) allocate (obj%eps_e(3, 3)) allocate (obj%eps_e_n(3, 3)) allocate (obj%eps_p(3, 3)) allocate (obj%eps_p_n(3, 3)) ! initialize obj%d(:, :) = delta(:, :) obj%l(:, :) = delta(:, :) obj%w(:, :) = 0.0d0 obj%eps(:, :) = delta(:, :) obj%eps_n(:, :) = delta(:, :) obj%eps_e(:, :) = delta(:, :) obj%eps_e_n(:, :) = delta(:, :) obj%eps_p(:, :) = 0.0d0 obj%eps_p_n(:, :) = 0.0d0 elseif (obj%StrainTheory == "Infinitesimal_ElastoPlasticity") then obj%theoryID = 4 ! Finite strain theory allocate (obj%F(0, 0)) allocate (obj%F_n(0, 0)) allocate (obj%C(0, 0)) allocate (obj%C_n(0, 0)) allocate (obj%b(0, 0)) allocate (obj%Cp(0, 0)) allocate (obj%Cp_n(0, 0)) ! Hypo-elasto-plasticity allocate (obj%d(3, 3)) allocate (obj%de(3, 3)) allocate (obj%dp(3, 3)) allocate (obj%l(3, 3)) allocate (obj%w(3, 3)) ! small-strain allocate (obj%eps(3, 3)) allocate (obj%eps_n(3, 3)) allocate (obj%eps_e(3, 3)) allocate (obj%eps_e_n(3, 3)) allocate (obj%eps_p(3, 3)) allocate (obj%eps_p_n(3, 3)) ! initialize obj%d(:, :) = delta(:, :) obj%de(:, :) = delta(:, :) obj%dp(:, :) = delta(:, :) obj%l(:, :) = delta(:, :) obj%w(:, :) = 0.0d0 obj%eps(:, :) = delta(:, :) obj%eps_n(:, :) = delta(:, :) obj%eps_e(:, :) = delta(:, :) obj%eps_e_n(:, :) = delta(:, :) obj%eps_p(:, :) = 0.0d0 obj%eps_p_n(:, :) = 0.0d0 elseif (obj%StrainTheory == "Small_strain") then obj%theoryID = 5 ! Finite strain theory allocate (obj%F(0, 0)) allocate (obj%F_n(0, 0)) allocate (obj%C(0, 0)) allocate (obj%C_n(0, 0)) allocate (obj%b(0, 0)) allocate (obj%Cp(0, 0)) allocate (obj%Cp_n(0, 0)) ! Hypo-elasto-plasticity allocate (obj%d(0, 0)) allocate (obj%de(0, 0)) allocate (obj%dp(0, 0)) allocate (obj%l(0, 0)) allocate (obj%w(0, 0)) ! small-strain allocate (obj%eps(3, 3)) allocate (obj%eps_n(3, 3)) allocate (obj%eps_e(3, 3)) allocate (obj%eps_e_n(3, 3)) allocate (obj%eps_p(3, 3)) allocate (obj%eps_p_n(3, 3)) obj%eps(:, :) = delta(:, :) obj%eps_n(:, :) = delta(:, :) obj%eps_e(:, :) = delta(:, :) obj%eps_e_n(:, :) = delta(:, :) obj%eps_p(:, :) = 0.0d0 obj%eps_p_n(:, :) = 0.0d0 else print *, StrainTheory print *, "Please input one of following keyphrases" print *, " ---->" print *, "Finite_Elasticity" print *, "Finite_ElastoPlasticity" print *, "Infinitesimal_Elasticity" print *, "Infinitesimal_ElastoPlasticity" print *, "Small_strain" print *, " <----" end if end subroutine ! ############################### ! ############################### subroutine deleteStrain(obj) class(Strain_), intent(inout) :: obj ! Finite strain theory deallocate (obj%F) deallocate (obj%F_n) deallocate (obj%C) deallocate (obj%C_n) deallocate (obj%b) deallocate (obj%Cp) deallocate (obj%Cp_n) obj%detF = 0.0d0 ! Hypo-elasto-plasticity deallocate (obj%d) deallocate (obj%de) deallocate (obj%dp) deallocate (obj%l) deallocate (obj%w) ! small-strain deallocate (obj%eps) deallocate (obj%eps_n) deallocate (obj%eps_e) deallocate (obj%eps_e_n) deallocate (obj%eps_p) deallocate (obj%eps_p_n) obj%TheoryID = 0 obj%StrainTheory = " " end subroutine ! ############################### ! ############################### subroutine importStrain(obj, F, F_n, C, C_n, b, Cp, Cp_n, d, de, dp, l, w, eps, eps_n) class(Strain_), intent(inout) :: obj real(real64), optional, intent(in) :: F(:, :), F_n(:, :), C(:, :), C_n(:, :), b(:, :) real(real64), optional, intent(in) :: Cp(:, :), Cp_n(:, :), d(:, :), de(:, :) real(real64), optional, intent(in) :: dp(:, :), l(:, :), w(:, :), eps(:, :), eps_n(:, :) if (present(F)) then if (size(obj%F, 1) /= size(F, 1) .or. size(obj%F, 2) /= size(F, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%F(:, :) = F(:, :) end if end if if (present(F_n)) then if (size(obj%F_n, 1) /= size(F_n, 1) .or. size(obj%F_n, 2) /= size(F_n, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%F_n(:, :) = F_n(:, :) end if end if if (present(C)) then if (size(obj%C, 1) /= size(C, 1) .or. size(obj%C, 2) /= size(C, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%C(:, :) = C(:, :) end if end if if (present(C_n)) then if (size(obj%C_n, 1) /= size(C_n, 1) .or. size(obj%C_n, 2) /= size(C_n, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%C_n(:, :) = C_n(:, :) end if end if if (present(b)) then if (size(obj%b, 1) /= size(b, 1) .or. size(obj%b, 2) /= size(b, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%b(:, :) = b(:, :) end if end if if (present(Cp)) then if (size(obj%Cp, 1) /= size(Cp, 1) .or. size(obj%Cp, 2) /= size(Cp, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%Cp(:, :) = Cp(:, :) end if end if if (present(Cp_n)) then if (size(obj%Cp_n, 1) /= size(Cp_n, 1) .or. size(obj%Cp_n, 2) /= size(Cp_n, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%Cp_n(:, :) = Cp_n(:, :) end if end if if (present(d)) then if (size(obj%d, 1) /= size(d, 1) .or. size(obj%d, 2) /= size(d, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%d(:, :) = d(:, :) end if end if if (present(de)) then if (size(obj%de, 1) /= size(de, 1) .or. size(obj%de, 2) /= size(de, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%de(:, :) = de(:, :) end if end if if (present(dp)) then if (size(obj%dp, 1) /= size(dp, 1) .or. size(obj%dp, 2) /= size(dp, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%dp(:, :) = dp(:, :) end if end if if (present(l)) then if (size(obj%l, 1) /= size(l, 1) .or. size(obj%l, 2) /= size(l, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%l(:, :) = l(:, :) end if end if if (present(w)) then if (size(obj%w, 1) /= size(w, 1) .or. size(obj%w, 2) /= size(w, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%w(:, :) = w(:, :) end if end if if (present(eps)) then if (size(obj%eps, 1) /= size(eps, 1) .or. size(obj%eps, 2) /= size(eps, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%eps(:, :) = eps(:, :) end if end if if (present(eps_n)) then if (size(obj%eps_n, 1) /= size(eps_n, 1) .or. size(obj%eps_n, 2) /= size(eps_n, 2)) then print *, "ERROR :: importStrain :: invalid size " return else obj%eps_n(:, :) = eps_n(:, :) end if end if end subroutine ! ############################### ! ############################### subroutine getallStrain(obj, ShapeFunction) class(Strain_), intent(inout) :: obj class(ShapeFunction_), intent(in)::ShapeFunction real(real64), allocatable :: fmat(:, :), Jmat_n(:, :), ddudgzi(:, :), ddudx_n(:, :), ddudx(:, :), & dudx(:, :), JmatInv_n(:, :), dudgzi(:, :) ! for Finite strain theory if (size(obj%F, 1) == 3) then allocate (fmat(3, 3), Jmat_n(3, 3), ddudgzi(3, 3), ddudx_n(3, 3), JmatInv_n(3, 3)) fmat(:, :) = 0.0d0 fmat(1, 1) = 1.0d0 fmat(2, 2) = 1.0d0 fmat(3, 3) = 1.0d0 Jmat_n(:, :) = matmul(ShapeFunction%dNdgzi, ShapeFunction%ElemCoord_n) ddudgzi(:, :) = matmul(ShapeFunction%dNdgzi, ShapeFunction%du) call inverse_rank_2(Jmat_n, JmatInv_n) ddudx_n(:, :) = matmul(ddudgzi, JmatInv_n) fmat(:, :) = fmat(:, :) + ddudx_n(:, :) obj%F = matmul(fmat, obj%F_n) call obj%get(C=.true., b=.true., detF=.true.) end if ! for infinitesimal strain theory if (size(obj%d, 1) == 3) then allocate (ddudx(3, 3), ddudgzi(3, 3)) ddudgzi(:, :) = matmul(ShapeFunction%dNdgzi, ShapeFunction%du) ddudx(:, :) = matmul(ddudgzi, ShapeFunction%JmatInv) obj%l(:, :) = ddudx(:, :) ! from velocity gradient tensor l, spin tensor w and stretch tensor d is computed. call obj%get(d=.true.) call obj%get(w=.true.) if (size(obj%de, 1) == 3 .and. size(obj%dp, 1) == 3) then call obj%get(de=.true.) end if end if ! for small strain theory if (size(obj%eps, 1) == 3) then if (size(obj%d, 1) == 3) then ! forward Euler obj%eps(:, :) = obj%eps_n(:, :) + obj%d(:, :) ! other integral scheme will be implemented. else ! small strain ! Caution :: du here is seen as u allocate (dudgzi(3, 3), dudx(3, 3)) dudgzi(:, :) = matmul(ShapeFunction%dNdgzi, ShapeFunction%du) dudx(:, :) = matmul(dudgzi, ShapeFunction%JmatInv) ! Here is the small strain tensor. obj%eps(:, :) = 0.50d0*(dudx(:, :) + transpose(dudx)) end if end if end subroutine ! ############################### ! ############################### subroutine getStrain(obj, C, b, d, w, de, detF) class(Strain_), intent(inout)::obj logical, optional, intent(in) :: C, b, d, w, detF, de if (present(C)) then if (C .eqv. .true.) then obj%C(:, :) = matmul(transpose(obj%F), obj%F) end if end if if (present(b)) then if (b .eqv. .true.) then obj%b(:, :) = matmul(obj%F, transpose(obj%F)) end if end if if (present(d)) then if (d .eqv. .true.) then obj%d(:, :) = 0.50d0*(obj%l(:, :) + transpose(obj%l)) end if end if if (present(de)) then if (de .eqv. .true.) then obj%de(:, :) = obj%d(:, :) - obj%dp(:, :) end if end if if (present(w)) then if (w .eqv. .true.) then obj%w(:, :) = 0.50d0*(obj%l(:, :) - transpose(obj%l)) end if end if if (present(detF)) then if (detF .eqv. .true.) then obj%detF = det_mat(obj%F, size(obj%F, 1)) end if end if end subroutine ! ############################### end module