2020-07-15 18:05:21 +05:30
|
|
|
!----------------------------------------------------------------------------------------------------
|
2020-12-22 16:50:00 +05:30
|
|
|
!> @brief internal microstructure state for all damage sources and kinematics constitutive models
|
2020-07-15 18:05:21 +05:30
|
|
|
!----------------------------------------------------------------------------------------------------
|
2021-04-06 15:11:45 +05:30
|
|
|
submodule(phase) damage
|
2021-04-11 12:16:31 +05:30
|
|
|
|
|
|
|
type :: tDamageParameters
|
|
|
|
real(pReal) :: mu = 0.0_pReal !< viscosity
|
|
|
|
real(pReal), dimension(3,3) :: K = 0.0_pReal !< conductivity/diffusivity
|
|
|
|
end type tDamageParameters
|
|
|
|
|
2021-01-08 04:20:06 +05:30
|
|
|
enum, bind(c); enumerator :: &
|
|
|
|
DAMAGE_UNDEFINED_ID, &
|
|
|
|
DAMAGE_ISOBRITTLE_ID, &
|
|
|
|
DAMAGE_ISODUCTILE_ID, &
|
2021-04-14 23:28:58 +05:30
|
|
|
DAMAGE_ANISOBRITTLE_ID
|
2021-01-08 04:20:06 +05:30
|
|
|
end enum
|
|
|
|
|
2021-05-22 01:37:55 +05:30
|
|
|
integer :: phase_damage_maxSizeDotState
|
|
|
|
|
2021-01-21 01:24:31 +05:30
|
|
|
|
|
|
|
type :: tDataContainer
|
|
|
|
real(pReal), dimension(:), allocatable :: phi, d_phi_d_dot_phi
|
|
|
|
end type tDataContainer
|
|
|
|
|
2021-02-13 17:14:47 +05:30
|
|
|
integer(kind(DAMAGE_UNDEFINED_ID)), dimension(:), allocatable :: &
|
2021-05-22 01:10:46 +05:30
|
|
|
phase_damage !< active sources mechanisms of each phase
|
2020-07-09 04:31:08 +05:30
|
|
|
|
2021-01-21 01:24:31 +05:30
|
|
|
type(tDataContainer), dimension(:), allocatable :: current
|
|
|
|
|
2021-04-11 12:16:31 +05:30
|
|
|
type(tDamageParameters), dimension(:), allocatable :: param
|
|
|
|
|
2020-07-09 04:31:08 +05:30
|
|
|
interface
|
|
|
|
|
2021-02-13 17:14:47 +05:30
|
|
|
module function anisobrittle_init() result(mySources)
|
|
|
|
logical, dimension(:), allocatable :: mySources
|
2021-01-26 04:08:32 +05:30
|
|
|
end function anisobrittle_init
|
2020-07-09 04:31:08 +05:30
|
|
|
|
2021-02-13 17:14:47 +05:30
|
|
|
module function isobrittle_init() result(mySources)
|
|
|
|
logical, dimension(:), allocatable :: mySources
|
2021-01-26 04:08:32 +05:30
|
|
|
end function isobrittle_init
|
2020-07-09 04:31:08 +05:30
|
|
|
|
2021-02-13 17:14:47 +05:30
|
|
|
module function isoductile_init() result(mySources)
|
|
|
|
logical, dimension(:), allocatable :: mySources
|
2021-01-26 04:08:32 +05:30
|
|
|
end function isoductile_init
|
2020-07-09 04:31:08 +05:30
|
|
|
|
|
|
|
|
2021-02-13 15:31:08 +05:30
|
|
|
module subroutine isobrittle_deltaState(C, Fe, ph, me)
|
2021-01-19 14:55:52 +05:30
|
|
|
integer, intent(in) :: ph,me
|
|
|
|
real(pReal), intent(in), dimension(3,3) :: &
|
|
|
|
Fe
|
|
|
|
real(pReal), intent(in), dimension(6,6) :: &
|
|
|
|
C
|
2021-02-13 15:31:08 +05:30
|
|
|
end subroutine isobrittle_deltaState
|
2021-01-19 14:55:52 +05:30
|
|
|
|
2020-07-10 18:29:07 +05:30
|
|
|
|
2021-02-13 15:31:08 +05:30
|
|
|
module subroutine anisobrittle_dotState(S, ph, me)
|
|
|
|
integer, intent(in) :: ph,me
|
2021-01-19 15:00:10 +05:30
|
|
|
real(pReal), intent(in), dimension(3,3) :: &
|
|
|
|
S
|
2021-01-26 04:08:32 +05:30
|
|
|
end subroutine anisobrittle_dotState
|
2021-01-19 15:00:10 +05:30
|
|
|
|
2021-02-13 15:31:08 +05:30
|
|
|
module subroutine isoductile_dotState(ph,me)
|
|
|
|
integer, intent(in) :: ph,me
|
2021-01-26 04:08:32 +05:30
|
|
|
end subroutine isoductile_dotState
|
|
|
|
|
|
|
|
module subroutine anisobrittle_results(phase,group)
|
|
|
|
integer, intent(in) :: phase
|
|
|
|
character(len=*), intent(in) :: group
|
|
|
|
end subroutine anisobrittle_results
|
|
|
|
|
|
|
|
module subroutine isobrittle_results(phase,group)
|
|
|
|
integer, intent(in) :: phase
|
|
|
|
character(len=*), intent(in) :: group
|
|
|
|
end subroutine isobrittle_results
|
|
|
|
|
|
|
|
module subroutine isoductile_results(phase,group)
|
|
|
|
integer, intent(in) :: phase
|
|
|
|
character(len=*), intent(in) :: group
|
|
|
|
end subroutine isoductile_results
|
2020-07-12 18:52:40 +05:30
|
|
|
|
2020-07-09 04:31:08 +05:30
|
|
|
end interface
|
|
|
|
|
|
|
|
contains
|
|
|
|
|
2020-07-12 20:14:26 +05:30
|
|
|
!----------------------------------------------------------------------------------------------
|
|
|
|
!< @brief initialize damage sources and kinematics mechanism
|
|
|
|
!----------------------------------------------------------------------------------------------
|
2020-07-09 04:31:08 +05:30
|
|
|
module subroutine damage_init
|
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
integer :: &
|
2021-01-21 01:24:31 +05:30
|
|
|
ph, & !< counter in phase loop
|
2021-03-05 01:46:36 +05:30
|
|
|
Nmembers
|
2020-08-15 19:32:10 +05:30
|
|
|
class(tNode), pointer :: &
|
|
|
|
phases, &
|
|
|
|
phase, &
|
2021-04-11 16:12:57 +05:30
|
|
|
sources, &
|
|
|
|
source
|
2021-04-11 16:07:46 +05:30
|
|
|
logical:: damage_active
|
2021-01-27 15:14:03 +05:30
|
|
|
|
|
|
|
print'(/,a)', ' <<<+- phase:damage init -+>>>'
|
|
|
|
|
2020-09-13 14:09:17 +05:30
|
|
|
phases => config_material%get('phase')
|
2020-08-15 19:32:10 +05:30
|
|
|
|
2021-01-21 01:24:31 +05:30
|
|
|
allocate(current(phases%length))
|
2021-01-08 11:40:38 +05:30
|
|
|
allocate(damageState (phases%length))
|
2021-04-11 12:16:31 +05:30
|
|
|
allocate(param(phases%length))
|
2020-08-15 19:32:10 +05:30
|
|
|
|
2021-04-11 16:07:46 +05:30
|
|
|
damage_active = .false.
|
2020-08-15 19:32:10 +05:30
|
|
|
do ph = 1,phases%length
|
2021-01-21 01:24:31 +05:30
|
|
|
|
2021-04-06 15:08:44 +05:30
|
|
|
Nmembers = count(material_phaseID == ph)
|
2021-01-21 01:24:31 +05:30
|
|
|
|
2021-03-05 01:46:36 +05:30
|
|
|
allocate(current(ph)%phi(Nmembers),source=1.0_pReal)
|
|
|
|
allocate(current(ph)%d_phi_d_dot_phi(Nmembers),source=0.0_pReal)
|
2021-01-21 01:24:31 +05:30
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
phase => phases%get(ph)
|
2021-02-13 03:11:35 +05:30
|
|
|
sources => phase%get('damage',defaultVal=emptyList)
|
2021-02-13 13:02:43 +05:30
|
|
|
if (sources%length > 1) error stop
|
2021-04-11 16:12:57 +05:30
|
|
|
if (sources%length == 1) then
|
|
|
|
damage_active = .true.
|
|
|
|
source => sources%get(1)
|
2021-04-11 17:25:30 +05:30
|
|
|
param(ph)%mu = source%get_asFloat('M',defaultVal=0.0_pReal)
|
|
|
|
param(ph)%K(1,1) = source%get_asFloat('D_11',defaultVal=0.0_pReal)
|
|
|
|
param(ph)%K(3,3) = source%get_asFloat('D_33',defaultVal=0.0_pReal)
|
|
|
|
param(ph)%K = lattice_applyLatticeSymmetry33(param(ph)%K,phase%get_asString('lattice'))
|
2021-04-11 16:12:57 +05:30
|
|
|
endif
|
2021-02-13 13:02:43 +05:30
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
enddo
|
|
|
|
|
2021-05-22 01:10:46 +05:30
|
|
|
allocate(phase_damage(phases%length), source = DAMAGE_UNDEFINED_ID)
|
2020-08-15 19:32:10 +05:30
|
|
|
|
2021-04-11 16:07:46 +05:30
|
|
|
if (damage_active) then
|
2021-05-22 01:10:46 +05:30
|
|
|
where(isobrittle_init() ) phase_damage = DAMAGE_ISOBRITTLE_ID
|
|
|
|
where(isoductile_init() ) phase_damage = DAMAGE_ISODUCTILE_ID
|
|
|
|
where(anisobrittle_init()) phase_damage = DAMAGE_ANISOBRITTLE_ID
|
2020-08-15 19:32:10 +05:30
|
|
|
endif
|
2020-07-09 04:31:08 +05:30
|
|
|
|
2021-05-22 01:37:55 +05:30
|
|
|
phase_damage_maxSizeDotState = maxval(damageState%sizeDotState)
|
|
|
|
|
2020-07-09 04:31:08 +05:30
|
|
|
end subroutine damage_init
|
|
|
|
|
|
|
|
|
2021-05-10 18:01:21 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief returns the degraded/modified elasticity matrix
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
module function phase_damage_C(C_homogenized,ph,en) result(C)
|
|
|
|
|
|
|
|
real(pReal), dimension(3,3,3,3), intent(in) :: C_homogenized
|
2021-05-22 01:37:55 +05:30
|
|
|
integer, intent(in) :: ph,en
|
2021-05-10 18:01:21 +05:30
|
|
|
real(pReal), dimension(3,3,3,3) :: C
|
|
|
|
|
2021-05-22 01:10:46 +05:30
|
|
|
damageType: select case (phase_damage(ph))
|
2021-05-10 18:01:21 +05:30
|
|
|
case (DAMAGE_ISOBRITTLE_ID) damageType
|
|
|
|
C = C_homogenized * damage_phi(ph,en)**2
|
|
|
|
case default damageType
|
|
|
|
C = C_homogenized
|
|
|
|
end select damageType
|
|
|
|
|
|
|
|
end function phase_damage_C
|
|
|
|
|
|
|
|
|
2020-07-12 20:14:26 +05:30
|
|
|
!----------------------------------------------------------------------------------------------
|
|
|
|
!< @brief returns local part of nonlocal damage driving force
|
|
|
|
!----------------------------------------------------------------------------------------------
|
2021-04-09 03:10:20 +05:30
|
|
|
module function phase_f_phi(phi,co,ce) result(f)
|
2020-07-12 20:14:26 +05:30
|
|
|
|
2021-04-07 16:32:42 +05:30
|
|
|
integer, intent(in) :: ce,co
|
2020-07-12 20:14:26 +05:30
|
|
|
real(pReal), intent(in) :: &
|
2020-12-22 16:50:00 +05:30
|
|
|
phi !< damage parameter
|
2020-07-09 04:31:08 +05:30
|
|
|
real(pReal) :: &
|
2021-04-09 03:10:20 +05:30
|
|
|
f
|
2021-04-07 12:41:40 +05:30
|
|
|
|
2020-07-09 04:31:08 +05:30
|
|
|
integer :: &
|
2021-01-26 04:08:32 +05:30
|
|
|
ph, &
|
2021-04-08 00:22:25 +05:30
|
|
|
en
|
2020-07-09 04:31:08 +05:30
|
|
|
|
2021-04-07 16:32:42 +05:30
|
|
|
ph = material_phaseID(co,ce)
|
2021-04-08 00:22:25 +05:30
|
|
|
en = material_phaseEntry(co,ce)
|
|
|
|
|
2021-05-22 01:10:46 +05:30
|
|
|
select case(phase_damage(ph))
|
2021-04-14 23:28:58 +05:30
|
|
|
case(DAMAGE_ISOBRITTLE_ID,DAMAGE_ISODUCTILE_ID,DAMAGE_ANISOBRITTLE_ID)
|
2021-04-09 03:10:20 +05:30
|
|
|
f = 1.0_pReal &
|
|
|
|
- phi*damageState(ph)%state(1,en)
|
2021-04-08 00:22:25 +05:30
|
|
|
case default
|
2021-04-09 03:10:20 +05:30
|
|
|
f = 0.0_pReal
|
2021-04-08 00:22:25 +05:30
|
|
|
end select
|
2020-07-09 04:31:08 +05:30
|
|
|
|
2021-04-08 17:01:21 +05:30
|
|
|
end function phase_f_phi
|
2020-07-09 04:31:08 +05:30
|
|
|
|
2020-07-12 18:52:40 +05:30
|
|
|
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief integrate stress, state with adaptive 1st order explicit Euler method
|
|
|
|
!> using Fixed Point Iteration to adapt the stepsize
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2021-05-22 14:56:19 +05:30
|
|
|
module function integrateDamageState(dt,co,ce) result(broken)
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
real(pReal), intent(in) :: dt
|
|
|
|
integer, intent(in) :: &
|
2021-05-22 14:56:19 +05:30
|
|
|
ce, &
|
|
|
|
co
|
2021-01-08 04:02:54 +05:30
|
|
|
logical :: broken
|
|
|
|
|
|
|
|
integer :: &
|
|
|
|
NiterationState, & !< number of iterations in state loop
|
|
|
|
ph, &
|
|
|
|
me, &
|
|
|
|
size_so
|
|
|
|
real(pReal) :: &
|
|
|
|
zeta
|
2021-05-22 01:10:46 +05:30
|
|
|
real(pReal), dimension(phase_damage_maxSizeDotState) :: &
|
2021-01-08 04:02:54 +05:30
|
|
|
r ! state residuum
|
2021-05-22 01:10:46 +05:30
|
|
|
real(pReal), dimension(phase_damage_maxSizeDotState,2) :: source_dotState
|
2021-01-08 04:02:54 +05:30
|
|
|
logical :: &
|
|
|
|
converged_
|
|
|
|
|
2021-05-22 14:56:19 +05:30
|
|
|
ph = material_phaseID(co,ce)
|
|
|
|
me = material_phaseEntry(co,ce)
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-02-13 23:11:30 +05:30
|
|
|
if (damageState(ph)%sizeState == 0) then
|
2021-02-13 18:45:41 +05:30
|
|
|
broken = .false.
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
|
2021-01-08 04:02:54 +05:30
|
|
|
converged_ = .true.
|
2021-02-13 15:31:08 +05:30
|
|
|
broken = phase_damage_collectDotState(ph,me)
|
2021-01-08 04:02:54 +05:30
|
|
|
if(broken) return
|
|
|
|
|
2021-02-13 13:02:43 +05:30
|
|
|
size_so = damageState(ph)%sizeDotState
|
|
|
|
damageState(ph)%state(1:size_so,me) = damageState(ph)%subState0(1:size_so,me) &
|
2021-02-13 18:45:41 +05:30
|
|
|
+ damageState(ph)%dotState (1:size_so,me) * dt
|
2021-02-13 13:02:43 +05:30
|
|
|
source_dotState(1:size_so,2) = 0.0_pReal
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
iteration: do NiterationState = 1, num%nState
|
|
|
|
|
2021-02-13 13:02:43 +05:30
|
|
|
if(nIterationState > 1) source_dotState(1:size_so,2) = source_dotState(1:size_so,1)
|
|
|
|
source_dotState(1:size_so,1) = damageState(ph)%dotState(:,me)
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-02-13 15:31:08 +05:30
|
|
|
broken = phase_damage_collectDotState(ph,me)
|
2021-01-08 04:02:54 +05:30
|
|
|
if(broken) exit iteration
|
|
|
|
|
2021-02-13 13:02:43 +05:30
|
|
|
|
|
|
|
zeta = damper(damageState(ph)%dotState(:,me),source_dotState(1:size_so,1),source_dotState(1:size_so,2))
|
|
|
|
damageState(ph)%dotState(:,me) = damageState(ph)%dotState(:,me) * zeta &
|
2021-06-25 16:56:08 +05:30
|
|
|
+ source_dotState(1:size_so,1)* (1.0_pReal - zeta)
|
2021-02-13 13:02:43 +05:30
|
|
|
r(1:size_so) = damageState(ph)%state (1:size_so,me) &
|
|
|
|
- damageState(ph)%subState0(1:size_so,me) &
|
|
|
|
- damageState(ph)%dotState (1:size_so,me) * dt
|
|
|
|
damageState(ph)%state(1:size_so,me) = damageState(ph)%state(1:size_so,me) - r(1:size_so)
|
|
|
|
converged_ = converged_ .and. converged(r(1:size_so), &
|
|
|
|
damageState(ph)%state(1:size_so,me), &
|
|
|
|
damageState(ph)%atol(1:size_so))
|
|
|
|
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
if(converged_) then
|
2021-02-09 03:51:53 +05:30
|
|
|
broken = phase_damage_deltaState(mechanical_F_e(ph,me),ph,me)
|
2021-01-08 04:02:54 +05:30
|
|
|
exit iteration
|
|
|
|
endif
|
|
|
|
|
|
|
|
enddo iteration
|
|
|
|
|
|
|
|
broken = broken .or. .not. converged_
|
|
|
|
|
|
|
|
|
|
|
|
contains
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief calculate the damping for correction of state and dot state
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2021-04-14 01:00:56 +05:30
|
|
|
real(pReal) pure function damper(omega_0,omega_1,omega_2)
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-04-14 01:00:56 +05:30
|
|
|
real(pReal), dimension(:), intent(in) :: &
|
|
|
|
omega_0, omega_1, omega_2
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
real(pReal) :: dot_prod12, dot_prod22
|
|
|
|
|
2021-04-14 01:00:56 +05:30
|
|
|
dot_prod12 = dot_product(omega_0-omega_1, omega_1-omega_2)
|
|
|
|
dot_prod22 = dot_product(omega_1-omega_2, omega_1-omega_2)
|
|
|
|
|
|
|
|
if (min(dot_product(omega_0,omega_1),dot_prod12) < 0.0_pReal .and. dot_prod22 > 0.0_pReal) then
|
2021-01-08 04:02:54 +05:30
|
|
|
damper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22)
|
|
|
|
else
|
|
|
|
damper = 1.0_pReal
|
|
|
|
endif
|
|
|
|
|
|
|
|
end function damper
|
|
|
|
|
|
|
|
end function integrateDamageState
|
|
|
|
|
|
|
|
|
2020-07-12 20:14:26 +05:30
|
|
|
!----------------------------------------------------------------------------------------------
|
2020-08-15 19:32:10 +05:30
|
|
|
!< @brief writes damage sources results to HDF5 output file
|
2020-07-12 20:14:26 +05:30
|
|
|
!----------------------------------------------------------------------------------------------
|
2020-12-22 16:50:00 +05:30
|
|
|
module subroutine damage_results(group,ph)
|
2020-07-12 18:52:40 +05:30
|
|
|
|
2020-12-22 16:50:00 +05:30
|
|
|
character(len=*), intent(in) :: group
|
|
|
|
integer, intent(in) :: ph
|
2020-07-12 18:52:40 +05:30
|
|
|
|
|
|
|
|
2021-05-22 01:10:46 +05:30
|
|
|
if (phase_damage(ph) /= DAMAGE_UNDEFINED_ID) &
|
2021-03-25 23:52:59 +05:30
|
|
|
call results_closeGroup(results_addGroup(group//'damage'))
|
2020-07-12 18:52:40 +05:30
|
|
|
|
2021-05-22 01:10:46 +05:30
|
|
|
sourceType: select case (phase_damage(ph))
|
2020-12-22 16:50:00 +05:30
|
|
|
|
2021-04-11 16:07:46 +05:30
|
|
|
case (DAMAGE_ISOBRITTLE_ID) sourceType
|
|
|
|
call isobrittle_results(ph,group//'damage/')
|
2020-12-22 16:50:00 +05:30
|
|
|
|
2021-04-11 16:07:46 +05:30
|
|
|
case (DAMAGE_ISODUCTILE_ID) sourceType
|
|
|
|
call isoductile_results(ph,group//'damage/')
|
2020-12-22 16:50:00 +05:30
|
|
|
|
2021-04-11 16:07:46 +05:30
|
|
|
case (DAMAGE_ANISOBRITTLE_ID) sourceType
|
|
|
|
call anisobrittle_results(ph,group//'damage/')
|
2020-12-22 16:50:00 +05:30
|
|
|
|
2021-04-11 16:07:46 +05:30
|
|
|
end select sourceType
|
2020-07-12 18:52:40 +05:30
|
|
|
|
|
|
|
end subroutine damage_results
|
|
|
|
|
|
|
|
|
2021-01-08 04:02:54 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief contains the constitutive equation for calculating the rate of change of microstructure
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2021-02-13 15:31:08 +05:30
|
|
|
function phase_damage_collectDotState(ph,me) result(broken)
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
integer, intent(in) :: &
|
|
|
|
ph, &
|
2021-02-13 15:31:08 +05:30
|
|
|
me !< counter in source loop
|
2021-01-08 04:02:54 +05:30
|
|
|
logical :: broken
|
|
|
|
|
|
|
|
|
|
|
|
broken = .false.
|
|
|
|
|
2021-02-13 23:11:30 +05:30
|
|
|
if (damageState(ph)%sizeState > 0) then
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-05-22 01:10:46 +05:30
|
|
|
sourceType: select case (phase_damage(ph))
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-01-08 04:20:06 +05:30
|
|
|
case (DAMAGE_ISODUCTILE_ID) sourceType
|
2021-02-13 15:31:08 +05:30
|
|
|
call isoductile_dotState(ph,me)
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-01-08 05:14:16 +05:30
|
|
|
case (DAMAGE_ANISOBRITTLE_ID) sourceType
|
2021-02-13 15:31:08 +05:30
|
|
|
call anisobrittle_dotState(mechanical_S(ph,me), ph,me) ! correct stress?
|
2021-01-08 05:14:16 +05:30
|
|
|
|
2021-01-08 04:02:54 +05:30
|
|
|
end select sourceType
|
|
|
|
|
2021-02-13 13:02:43 +05:30
|
|
|
broken = broken .or. any(IEEE_is_NaN(damageState(ph)%dotState(:,me)))
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-02-13 15:31:08 +05:30
|
|
|
endif
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-02-09 03:51:53 +05:30
|
|
|
end function phase_damage_collectDotState
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
|
2021-04-11 16:51:27 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Damage viscosity.
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
module function phase_mu_phi(co,ce) result(mu)
|
|
|
|
|
|
|
|
integer, intent(in) :: co, ce
|
|
|
|
real(pReal) :: mu
|
|
|
|
|
|
|
|
|
2021-04-11 17:25:30 +05:30
|
|
|
mu = param(material_phaseID(co,ce))%mu
|
2021-04-11 16:51:27 +05:30
|
|
|
|
|
|
|
end function phase_mu_phi
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Damage conductivity/diffusivity in reference configuration.
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
module function phase_K_phi(co,ce) result(K)
|
|
|
|
|
|
|
|
integer, intent(in) :: co, ce
|
|
|
|
real(pReal), dimension(3,3) :: K
|
|
|
|
|
|
|
|
|
2021-04-11 17:25:30 +05:30
|
|
|
K = crystallite_push33ToRef(co,ce,param(material_phaseID(co,ce))%K)
|
2021-04-11 16:51:27 +05:30
|
|
|
|
|
|
|
end function phase_K_phi
|
|
|
|
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief for constitutive models having an instantaneous change of state
|
|
|
|
!> will return false if delta state is not needed/supported by the constitutive model
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2021-02-09 03:51:53 +05:30
|
|
|
function phase_damage_deltaState(Fe, ph, me) result(broken)
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
integer, intent(in) :: &
|
|
|
|
ph, &
|
2021-01-19 14:51:51 +05:30
|
|
|
me
|
2021-01-08 04:02:54 +05:30
|
|
|
real(pReal), intent(in), dimension(3,3) :: &
|
|
|
|
Fe !< elastic deformation gradient
|
|
|
|
integer :: &
|
|
|
|
myOffset, &
|
|
|
|
mySize
|
|
|
|
logical :: &
|
|
|
|
broken
|
|
|
|
|
|
|
|
|
|
|
|
broken = .false.
|
|
|
|
|
2021-02-13 23:11:30 +05:30
|
|
|
if (damageState(ph)%sizeState == 0) return
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-05-22 01:10:46 +05:30
|
|
|
sourceType: select case (phase_damage(ph))
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-04-11 16:07:46 +05:30
|
|
|
case (DAMAGE_ISOBRITTLE_ID) sourceType
|
|
|
|
call isobrittle_deltaState(phase_homogenizedC(ph,me), Fe, ph,me)
|
|
|
|
broken = any(IEEE_is_NaN(damageState(ph)%deltaState(:,me)))
|
|
|
|
if(.not. broken) then
|
|
|
|
myOffset = damageState(ph)%offsetDeltaState
|
|
|
|
mySize = damageState(ph)%sizeDeltaState
|
|
|
|
damageState(ph)%state(myOffset + 1: myOffset + mySize,me) = &
|
|
|
|
damageState(ph)%state(myOffset + 1: myOffset + mySize,me) + damageState(ph)%deltaState(1:mySize,me)
|
|
|
|
endif
|
2021-01-08 04:02:54 +05:30
|
|
|
|
2021-04-11 16:07:46 +05:30
|
|
|
end select sourceType
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
|
2021-02-09 03:51:53 +05:30
|
|
|
end function phase_damage_deltaState
|
2021-01-08 04:02:54 +05:30
|
|
|
|
|
|
|
|
2021-01-08 12:07:51 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief checks if a source mechanism is active or not
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2021-02-13 17:14:47 +05:30
|
|
|
function source_active(source_label) result(active_source)
|
2021-01-08 12:07:51 +05:30
|
|
|
|
|
|
|
character(len=*), intent(in) :: source_label !< name of source mechanism
|
2021-02-13 17:14:47 +05:30
|
|
|
logical, dimension(:), allocatable :: active_source
|
2021-01-08 12:07:51 +05:30
|
|
|
|
|
|
|
class(tNode), pointer :: &
|
|
|
|
phases, &
|
|
|
|
phase, &
|
|
|
|
sources, &
|
|
|
|
src
|
2021-02-13 17:14:47 +05:30
|
|
|
integer :: ph
|
2021-01-08 12:07:51 +05:30
|
|
|
|
|
|
|
phases => config_material%get('phase')
|
2021-02-13 17:14:47 +05:30
|
|
|
allocate(active_source(phases%length))
|
|
|
|
do ph = 1, phases%length
|
|
|
|
phase => phases%get(ph)
|
2021-02-13 03:11:35 +05:30
|
|
|
sources => phase%get('damage',defaultVal=emptyList)
|
2021-02-13 17:14:47 +05:30
|
|
|
src => sources%get(1)
|
2021-02-13 23:11:30 +05:30
|
|
|
active_source(ph) = src%get_asString('type',defaultVal = 'x') == source_label
|
2021-01-08 12:07:51 +05:30
|
|
|
enddo
|
|
|
|
|
|
|
|
|
|
|
|
end function source_active
|
|
|
|
|
|
|
|
|
2021-01-21 01:24:31 +05:30
|
|
|
!----------------------------------------------------------------------------------------------
|
|
|
|
!< @brief Set damage parameter
|
|
|
|
!----------------------------------------------------------------------------------------------
|
2021-04-08 17:01:21 +05:30
|
|
|
module subroutine phase_set_phi(phi,co,ce)
|
2021-01-21 01:24:31 +05:30
|
|
|
|
|
|
|
real(pReal), intent(in) :: phi
|
|
|
|
integer, intent(in) :: ce, co
|
|
|
|
|
|
|
|
|
2021-04-06 15:08:44 +05:30
|
|
|
current(material_phaseID(co,ce))%phi(material_phaseEntry(co,ce)) = phi
|
2021-01-21 01:24:31 +05:30
|
|
|
|
2021-04-08 17:01:21 +05:30
|
|
|
end subroutine phase_set_phi
|
2021-01-21 01:24:31 +05:30
|
|
|
|
|
|
|
|
2021-02-13 11:45:57 +05:30
|
|
|
module function damage_phi(ph,me) result(phi)
|
|
|
|
|
|
|
|
integer, intent(in) :: ph, me
|
|
|
|
real(pReal) :: phi
|
|
|
|
|
|
|
|
|
|
|
|
phi = current(ph)%phi(me)
|
|
|
|
|
|
|
|
end function damage_phi
|
|
|
|
|
|
|
|
|
2021-04-06 13:52:47 +05:30
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Forward data after successful increment.
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
module subroutine damage_forward()
|
|
|
|
|
|
|
|
integer :: ph
|
|
|
|
|
|
|
|
|
|
|
|
do ph = 1, size(damageState)
|
|
|
|
if (damageState(ph)%sizeState > 0) &
|
|
|
|
damageState(ph)%state0 = damageState(ph)%state
|
|
|
|
enddo
|
|
|
|
|
|
|
|
end subroutine damage_forward
|
|
|
|
|
|
|
|
|
2021-04-06 15:11:45 +05:30
|
|
|
end submodule damage
|