DAMASK_EICMD/src/phase_mechanical_eigen.f90

178 lines
6.2 KiB
Fortran
Raw Normal View History

2021-02-13 23:27:41 +05:30
submodule(phase:mechanical) eigen
2021-01-27 05:02:44 +05:30
2021-02-13 23:11:30 +05:30
integer, dimension(:), allocatable :: &
Nmodels
2021-01-27 05:02:44 +05:30
interface
2021-02-13 23:11:30 +05:30
module function thermalexpansion_init(kinematics_length) result(myKinematics)
2021-01-27 05:02:44 +05:30
integer, intent(in) :: kinematics_length
logical, dimension(:,:), allocatable :: myKinematics
2021-02-13 23:11:30 +05:30
end function thermalexpansion_init
2021-01-27 11:40:53 +05:30
module subroutine thermalexpansion_LiAndItsTangent(Li, dLi_dTstar, ph,me)
integer, intent(in) :: ph, me
real(pREAL), intent(out), dimension(3,3) :: &
2021-01-27 11:40:53 +05:30
Li !< thermal velocity gradient
real(pREAL), intent(out), dimension(3,3,3,3) :: &
2021-01-27 11:40:53 +05:30
dLi_dTstar !< derivative of Li with respect to Tstar (4th-order tensor defined to be zero)
end subroutine thermalexpansion_LiAndItsTangent
2021-01-27 05:02:44 +05:30
end interface
contains
2021-07-17 15:20:21 +05:30
module subroutine eigen_init(phases)
2021-01-27 05:02:44 +05:30
type(tDict), pointer :: &
2021-01-27 05:02:44 +05:30
phases
integer :: &
ph
type(tDict), pointer :: &
2021-01-27 05:02:44 +05:30
phase, &
mechanics
type(tList), pointer :: &
kinematics
2021-01-27 05:02:44 +05:30
2023-01-18 23:20:01 +05:30
print'(/,1x,a)', '<<<+- phase:mechanical:eigen init -+>>>'
2021-01-27 05:02:44 +05:30
2023-01-18 23:20:01 +05:30
2021-01-27 05:02:44 +05:30
!--------------------------------------------------------------------------------------------------
2021-02-13 23:11:30 +05:30
! explicit eigen mechanisms
allocate(Nmodels(phases%length),source = 0)
2021-01-27 05:02:44 +05:30
do ph = 1,phases%length
phase => phases%get_dict(ph)
mechanics => phase%get_dict('mechanical')
kinematics => mechanics%get_list('eigen',defaultVal=emptyList)
2021-02-13 23:11:30 +05:30
Nmodels(ph) = kinematics%length
end do
2021-01-27 05:02:44 +05:30
2023-07-24 22:00:02 +05:30
allocate(mechanical_eigen_kinematics_type(maxval(Nmodels),phases%length), source = UNDEFINED)
2021-01-27 05:02:44 +05:30
if (maxval(Nmodels) /= 0) then
2023-07-24 22:00:02 +05:30
where(thermalexpansion_init(maxval(Nmodels))) mechanical_eigen_kinematics_type = MECHANICAL_EIGEN_THERMALEXPANSION
2022-06-09 02:36:01 +05:30
end if
2021-01-27 05:02:44 +05:30
2021-07-17 15:20:21 +05:30
end subroutine eigen_init
2021-01-27 05:02:44 +05:30
2021-01-27 11:40:53 +05:30
!--------------------------------------------------------------------------------------------------
!> @brief Check if an eigen kinematic mechanism is active.
2021-01-27 11:40:53 +05:30
!--------------------------------------------------------------------------------------------------
function kinematics_active(kinematics_label,kinematics_length) result(active_kinematics)
character(len=*), intent(in) :: kinematics_label !< name of kinematic mechanism
integer, intent(in) :: kinematics_length !< max. number of kinematics in system
logical, dimension(:,:), allocatable :: active_kinematics
type(tDict), pointer :: &
2021-01-27 11:40:53 +05:30
phases, &
phase, &
mechanics, &
kinematic
type(tList), pointer :: &
kinematics
2021-07-22 19:11:09 +05:30
integer :: ph,k
2021-01-27 11:40:53 +05:30
phases => config_material%get_dict('phase')
2021-01-27 11:40:53 +05:30
allocate(active_kinematics(kinematics_length,phases%length), source = .false. )
2021-07-22 19:11:09 +05:30
do ph = 1, phases%length
phase => phases%get_dict(ph)
mechanics => phase%get_dict('mechanical')
kinematics => mechanics%get_list('eigen',defaultVal=emptyList)
2021-01-27 11:40:53 +05:30
do k = 1, kinematics%length
kinematic => kinematics%get_dict(k)
2023-06-04 10:47:38 +05:30
active_kinematics(k,ph) = kinematic%get_asStr('type') == kinematics_label
end do
end do
2021-01-27 11:40:53 +05:30
end function kinematics_active
!--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient
! ToDo: MD: S is Mi?
!--------------------------------------------------------------------------------------------------
2021-02-09 03:51:53 +05:30
module subroutine phase_LiAndItsTangents(Li, dLi_dS, dLi_dFi, &
2021-04-13 00:51:15 +05:30
S, Fi, ph,en)
2021-01-27 11:40:53 +05:30
integer, intent(in) :: &
2021-04-13 00:51:15 +05:30
ph,en
real(pREAL), intent(in), dimension(3,3) :: &
2021-01-27 11:40:53 +05:30
S !< 2nd Piola-Kirchhoff stress
real(pREAL), intent(in), dimension(3,3) :: &
2021-01-27 11:40:53 +05:30
Fi !< intermediate deformation gradient
real(pREAL), intent(out), dimension(3,3) :: &
2021-01-27 11:40:53 +05:30
Li !< intermediate velocity gradient
real(pREAL), intent(out), dimension(3,3,3,3) :: &
2021-01-27 11:40:53 +05:30
dLi_dS, & !< derivative of Li with respect to S
dLi_dFi
real(pREAL), dimension(3,3) :: &
2021-01-27 11:40:53 +05:30
my_Li, & !< intermediate velocity gradient
FiInv, &
temp_33
real(pREAL), dimension(3,3,3,3) :: &
2021-01-27 11:40:53 +05:30
my_dLi_dS
real(pREAL) :: &
2021-01-27 11:40:53 +05:30
detFi
integer :: &
2021-02-13 11:45:57 +05:30
k, i, j
2021-02-13 23:11:30 +05:30
logical :: active
2021-01-27 11:40:53 +05:30
2021-02-13 23:11:30 +05:30
active = .false.
Li = 0.0_pREAL
dLi_dS = 0.0_pREAL
dLi_dFi = 0.0_pREAL
2021-01-27 11:40:53 +05:30
2021-02-13 11:45:57 +05:30
2021-02-13 23:11:30 +05:30
KinematicsLoop: do k = 1, Nmodels(ph)
2023-07-24 22:00:02 +05:30
kinematicsType: select case (mechanical_eigen_kinematics_type(k,ph))
case (MECHANICAL_EIGEN_THERMALEXPANSION) kinematicsType
2021-04-13 00:51:15 +05:30
call thermalexpansion_LiAndItsTangent(my_Li, my_dLi_dS, ph,en)
2021-02-13 23:11:30 +05:30
Li = Li + my_Li
dLi_dS = dLi_dS + my_dLi_dS
active = .true.
2021-01-27 11:40:53 +05:30
end select kinematicsType
end do KinematicsLoop
2021-01-27 11:40:53 +05:30
plasticType: select case (mechanical_plasticity_type(ph))
case (MECHANICAL_PLASTICITY_ISOTROPIC) plasticType
2023-07-18 08:21:16 +05:30
call plastic_isotropic_LiAndItsTangent(my_Li, my_dLi_dS, S ,ph,en)
Li = Li + my_Li
dLi_dS = dLi_dS + my_dLi_dS
active = .true.
end select plasticType
damageType: select case (damage_type(ph))
case (DAMAGE_ANISOBRITTLE)
2021-04-13 00:51:15 +05:30
call damage_anisobrittle_LiAndItsTangent(my_Li, my_dLi_dS, S, ph, en)
2021-02-13 23:11:30 +05:30
Li = Li + my_Li
dLi_dS = dLi_dS + my_dLi_dS
active = .true.
2023-07-18 08:12:14 +05:30
end select damageType
2021-02-13 23:11:30 +05:30
if (.not. active) return
2021-02-13 23:11:30 +05:30
2021-01-27 11:40:53 +05:30
FiInv = math_inv33(Fi)
detFi = math_det33(Fi)
Li = matmul(matmul(Fi,Li),FiInv)*detFi !< push forward to intermediate configuration
temp_33 = matmul(FiInv,Li)
do i = 1,3; do j = 1,3
dLi_dS(1:3,1:3,i,j) = matmul(matmul(Fi,dLi_dS(1:3,1:3,i,j)),FiInv)*detFi
dLi_dFi(1:3,1:3,i,j) = dLi_dFi(1:3,1:3,i,j) + Li*FiInv(j,i)
dLi_dFi(1:3,i,1:3,j) = dLi_dFi(1:3,i,1:3,j) + math_I3*temp_33(j,i) + Li*FiInv(j,i)
end do; end do
2021-01-27 11:40:53 +05:30
2021-02-09 03:51:53 +05:30
end subroutine phase_LiAndItsTangents
2021-01-27 11:40:53 +05:30
2021-02-13 23:27:41 +05:30
end submodule eigen