Merge remote-tracking branch 'remotes/origin/clean-and-polish-damage' into development

This commit is contained in:
Franz Roters 2020-03-13 07:19:52 +01:00
commit e8c16e7f98
28 changed files with 1349 additions and 1691 deletions

@ -1 +1 @@
Subproject commit 9573ce7bd2c1a7188c1aac5b83aa76d480c2bdb0 Subproject commit d0d5b5a22be9778187b100214c782747793bb956

View File

@ -7,7 +7,7 @@ plasticity isotropic
(output) flowstress (output) flowstress
(output) strainrate (output) strainrate
lattice_structure isotropic lattice_structure iso
c11 110.9e9 c11 110.9e9
c12 58.34e9 c12 58.34e9

View File

@ -12,7 +12,7 @@ plasticity isotropic
(output) flowstress (output) flowstress
(output) strainrate (output) strainrate
lattice_structure isotropic lattice_structure iso
c11 10e9 c11 10e9
c12 0.0 c12 0.0
gdot0 0.001 gdot0 0.001
@ -22,4 +22,4 @@ h0 1e6
n 5 n 5
m 3 m 3
a 2 a 2
atol_resistance 1 atol_resistance 1

View File

@ -1,9 +1,8 @@
[IsotropicVolumePreservation] [IsotropicVolumePreservation]
elasticity hooke elasticity hooke
plasticity none plasticity none
### Material parameters ### ### Material parameters ###
lattice_structure isotropic lattice_structure iso
C11 100.0e9 C11 100.0e9
C12 66.6666667e9 C12 66.6666667e9

View File

@ -16,7 +16,7 @@ t0 330.0
#................. #.................
[isotropic matrix] [isotropic matrix]
lattice_structure isotropic lattice_structure iso
plasticity none plasticity none
{config/elastic_isotropic.config} {config/elastic_isotropic.config}
{config/thermal.config} {config/thermal.config}
@ -45,7 +45,7 @@ plasticity none
#................. #.................
[isotropic inclusion] [isotropic inclusion]
lattice_structure isotropic lattice_structure iso
plasticity none plasticity none
{config/elastic_isotropic.config} {config/elastic_isotropic.config}
{config/thermal.config} {config/thermal.config}

View File

@ -27,9 +27,6 @@ module CPFEM
implicit none implicit none
private private
real(pReal), parameter, private :: &
CPFEM_odd_stress = 1e15_pReal, & !< return value for stress in case of ping pong dummy cycle
CPFEM_odd_jacobian = 1e50_pReal !< return value for jacobian in case of ping pong dummy cycle
real(pReal), dimension (:,:,:), allocatable, private :: & real(pReal), dimension (:,:,:), allocatable, private :: &
CPFEM_cs !< Cauchy stress CPFEM_cs !< Cauchy stress
real(pReal), dimension (:,:,:,:), allocatable, private :: & real(pReal), dimension (:,:,:,:), allocatable, private :: &
@ -150,7 +147,10 @@ subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt
integer(pInt) elCP, & ! crystal plasticity element number integer(pInt) elCP, & ! crystal plasticity element number
i, j, k, l, m, n, ph, homog, mySource i, j, k, l, m, n, ph, homog, mySource
logical updateJaco ! flag indicating if JAcobian has to be updated logical updateJaco ! flag indicating if Jacobian has to be updated
real(pReal), parameter :: ODD_STRESS = 1e15_pReal, & !< return value for stress in case of ping pong dummy cycle
ODD_JACOBIAN = 1e50_pReal !< return value for jacobian in case of ping pong dummy cycle
elCP = mesh_FEM2DAMASK_elem(elFE) elCP = mesh_FEM2DAMASK_elem(elFE)
@ -193,8 +193,8 @@ subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt
elseif (iand(mode, CPFEM_COLLECT) /= 0_pInt) then elseif (iand(mode, CPFEM_COLLECT) /= 0_pInt) then
call random_number(rnd) call random_number(rnd)
if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal
CPFEM_cs(1:6,ip,elCP) = rnd * CPFEM_odd_stress CPFEM_cs(1:6,ip,elCP) = rnd * ODD_STRESS
CPFEM_dcsde(1:6,1:6,ip,elCP) = CPFEM_odd_jacobian * math_identity2nd(6) CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_identity2nd(6)
chosenThermal2: select case (thermal_type(material_homogenizationAt(elCP))) chosenThermal2: select case (thermal_type(material_homogenizationAt(elCP)))
case (THERMAL_conduction_ID) chosenThermal2 case (THERMAL_conduction_ID) chosenThermal2
temperature(material_homogenizationAt(elCP))%p(thermalMapping(material_homogenizationAt(elCP))%p(ip,elCP)) = & temperature(material_homogenizationAt(elCP))%p(thermalMapping(material_homogenizationAt(elCP))%p(ip,elCP)) = &
@ -226,8 +226,8 @@ subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt
endif endif
call random_number(rnd) call random_number(rnd)
if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal
CPFEM_cs(1:6,ip,elCP) = rnd*CPFEM_odd_stress CPFEM_cs(1:6,ip,elCP) = ODD_STRESS * rnd
CPFEM_dcsde(1:6,1:6,ip,elCP) = CPFEM_odd_jacobian*math_identity2nd(6) CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_identity2nd(6)
!*** deformation gradient is not outdated !*** deformation gradient is not outdated
@ -257,8 +257,8 @@ subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt
call random_number(rnd) call random_number(rnd)
if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal if (rnd < 0.5_pReal) rnd = rnd - 1.0_pReal
CPFEM_cs(1:6,ip,elCP) = rnd * CPFEM_odd_stress CPFEM_cs(1:6,ip,elCP) = ODD_STRESS * rnd
CPFEM_dcsde(1:6,1:6,ip,elCP) = CPFEM_odd_jacobian * math_identity2nd(6) CPFEM_dcsde(1:6,1:6,ip,elCP) = ODD_JACOBIAN * math_identity2nd(6)
else terminalIllness else terminalIllness
@ -331,6 +331,7 @@ subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt
end subroutine CPFEM_general end subroutine CPFEM_general
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Forward data for new time increment. !> @brief Forward data for new time increment.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------

View File

@ -40,7 +40,7 @@ module DAMASK_interface
implicit none implicit none
private private
logical, public :: symmetricSolver logical, protected, public :: symmetricSolver
character(len=*), parameter, public :: INPUTFILEEXTENSION = '.dat' character(len=*), parameter, public :: INPUTFILEEXTENSION = '.dat'
public :: & public :: &

View File

@ -77,20 +77,6 @@ module HDF5_utilities
module procedure HDF5_addAttribute_real_array module procedure HDF5_addAttribute_real_array
end interface HDF5_addAttribute end interface HDF5_addAttribute
!--------------------------------------------------------------------------------------------------
public :: &
HDF5_utilities_init, &
HDF5_openFile, &
HDF5_closeFile, &
HDF5_addAttribute, &
HDF5_closeGroup ,&
HDF5_openGroup, &
HDF5_addGroup, &
HDF5_read, &
HDF5_write, &
HDF5_setLink, &
HDF5_objectExists
contains contains

View File

@ -198,10 +198,10 @@ module subroutine plastic_dislotwin_init
prm%n0_sl = lattice_slip_normal(prm%N_sl,config%getString('lattice_structure'),& prm%n0_sl = lattice_slip_normal(prm%N_sl,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal)) config%getFloat('c/a',defaultVal=0.0_pReal))
prm%fccTwinTransNucleation = merge(.true., .false., lattice_structure(p) == LATTICE_FCC_ID) & prm%fccTwinTransNucleation = merge(.true., .false., lattice_structure(p) == lattice_FCC_ID) &
.and. (prm%N_sl(1) == 12) .and. (prm%N_sl(1) == 12)
if(prm%fccTwinTransNucleation) & if(prm%fccTwinTransNucleation) &
prm%fcc_twinNucleationSlipPair = lattice_fcc_twinNucleationSlipPair prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR
prm%rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(prm%N_sl)) prm%rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(prm%N_sl))
prm%rho_dip_0 = config%getFloats('rhoedgedip0',requiredSize=size(prm%N_sl)) prm%rho_dip_0 = config%getFloats('rhoedgedip0',requiredSize=size(prm%N_sl))
@ -230,7 +230,7 @@ module subroutine plastic_dislotwin_init
prm%omega = config%getFloat('omega', defaultVal = 1000.0_pReal) & prm%omega = config%getFloat('omega', defaultVal = 1000.0_pReal) &
* merge(12.0_pReal, & * merge(12.0_pReal, &
8.0_pReal, & 8.0_pReal, &
lattice_structure(p) == LATTICE_FCC_ID .or. lattice_structure(p) == LATTICE_HEX_ID) lattice_structure(p) == lattice_FCC_ID .or. lattice_structure(p) == lattice_HEX_ID)
! expand: family => system ! expand: family => system
@ -335,7 +335,7 @@ module subroutine plastic_dislotwin_init
config%getFloat('a_bcc', defaultVal=0.0_pReal), & config%getFloat('a_bcc', defaultVal=0.0_pReal), &
config%getFloat('a_fcc', defaultVal=0.0_pReal)) config%getFloat('a_fcc', defaultVal=0.0_pReal))
if (lattice_structure(p) /= LATTICE_fcc_ID) then if (lattice_structure(p) /= lattice_FCC_ID) then
prm%dot_N_0_tr = config%getFloats('ndot0_trans') prm%dot_N_0_tr = config%getFloats('ndot0_trans')
prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,prm%N_tr) prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,prm%N_tr)
endif endif

View File

@ -16,24 +16,18 @@ module damage_local
implicit none implicit none
private private
enum, bind(c)
enumerator :: &
undefined_ID, &
damage_ID
end enum
type :: tParameters type :: tParameters
integer(kind(undefined_ID)), dimension(:), allocatable :: & character(len=pStringLen), allocatable, dimension(:) :: &
outputID output
end type tParameters end type tParameters
type(tparameters), dimension(:), allocatable :: & type(tparameters), dimension(:), allocatable :: &
param param
public :: & public :: &
damage_local_init, & damage_local_init, &
damage_local_updateState, & damage_local_updateState, &
damage_local_Results damage_local_results
contains contains
@ -43,41 +37,30 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine damage_local_init subroutine damage_local_init
integer :: maxNinstance,o,NofMyHomog,h integer :: Ninstance,NofMyHomog,h
character(len=pStringLen), dimension(:), allocatable :: outputs
write(6,'(/,a)') ' <<<+- damage_'//DAMAGE_local_label//' init -+>>>'; flush(6)
maxNinstance = count(damage_type == DAMAGE_local_ID) write(6,'(/,a)') ' <<<+- damage_'//DAMAGE_local_label//' init -+>>>'; flush(6)
if (maxNinstance == 0) return
Ninstance = count(damage_type == DAMAGE_local_ID)
allocate(param(maxNinstance)) allocate(param(Ninstance))
do h = 1, size(damage_type) do h = 1, size(config_homogenization)
if (damage_type(h) /= DAMAGE_LOCAL_ID) cycle if (damage_type(h) /= DAMAGE_LOCAL_ID) cycle
associate(prm => param(damage_typeInstance(h)),config => config_homogenization(h)) associate(prm => param(damage_typeInstance(h)),config => config_homogenization(h))
outputs = config%getStrings('(output)',defaultVal=emptyStringArray) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
allocate(prm%outputID(0))
do o=1, size(outputs)
select case(outputs(o))
case ('damage')
prm%outputID = [prm%outputID , damage_ID]
end select
enddo
NofMyHomog = count(material_homogenizationAt == h) NofMyHomog = count(material_homogenizationAt == h)
damageState(h)%sizeState = 1 damageState(h)%sizeState = 1
allocate(damageState(h)%state0 (1,NofMyHomog), source=damage_initialPhi(h)) allocate(damageState(h)%state0 (1,NofMyHomog), source=damage_initialPhi(h))
allocate(damageState(h)%subState0(1,NofMyHomog), source=damage_initialPhi(h)) allocate(damageState(h)%subState0(1,NofMyHomog), source=damage_initialPhi(h))
allocate(damageState(h)%state (1,NofMyHomog), source=damage_initialPhi(h)) allocate(damageState(h)%state (1,NofMyHomog), source=damage_initialPhi(h))
nullify(damageMapping(h)%p) nullify(damageMapping(h)%p)
damageMapping(h)%p => material_homogenizationMemberAt damageMapping(h)%p => material_homogenizationMemberAt
deallocate(damage(h)%p) deallocate(damage(h)%p)
damage(h)%p => damageState(h)%state(1,:) damage(h)%p => damageState(h)%state(1,:)
end associate end associate
enddo enddo
@ -85,10 +68,10 @@ end subroutine damage_local_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates local change in damage field !> @brief calculates local change in damage field
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function damage_local_updateState(subdt, ip, el) function damage_local_updateState(subdt, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
el !< element number el !< element number
@ -100,30 +83,30 @@ function damage_local_updateState(subdt, ip, el)
homog, & homog, &
offset offset
real(pReal) :: & real(pReal) :: &
phi, phiDot, dPhiDot_dPhi phi, phiDot, dPhiDot_dPhi
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
offset = material_homogenizationMemberAt(ip,el) offset = material_homogenizationMemberAt(ip,el)
phi = damageState(homog)%subState0(1,offset) phi = damageState(homog)%subState0(1,offset)
call damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el) call damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el)
phi = max(residualStiffness,min(1.0_pReal,phi + subdt*phiDot)) phi = max(residualStiffness,min(1.0_pReal,phi + subdt*phiDot))
damage_local_updateState = [ abs(phi - damageState(homog)%state(1,offset)) & damage_local_updateState = [ abs(phi - damageState(homog)%state(1,offset)) &
<= err_damage_tolAbs & <= err_damage_tolAbs &
.or. abs(phi - damageState(homog)%state(1,offset)) & .or. abs(phi - damageState(homog)%state(1,offset)) &
<= err_damage_tolRel*abs(damageState(homog)%state(1,offset)), & <= err_damage_tolRel*abs(damageState(homog)%state(1,offset)), &
.true.] .true.]
damageState(homog)%state(1,offset) = phi damageState(homog)%state(1,offset) = phi
end function damage_local_updateState end function damage_local_updateState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates homogenized local damage driving forces !> @brief calculates homogenized local damage driving forces
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el) subroutine damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
el !< element number el !< element number
@ -135,7 +118,7 @@ subroutine damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el
source, & source, &
constituent constituent
real(pReal) :: & real(pReal) :: &
phiDot, dPhiDot_dPhi, localphiDot, dLocalphiDot_dPhi phiDot, dPhiDot_dPhi, localphiDot, dLocalphiDot_dPhi
phiDot = 0.0_pReal phiDot = 0.0_pReal
dPhiDot_dPhi = 0.0_pReal dPhiDot_dPhi = 0.0_pReal
@ -143,7 +126,7 @@ subroutine damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el
phase = material_phaseAt(grain,el) phase = material_phaseAt(grain,el)
constituent = material_phasememberAt(grain,ip,el) constituent = material_phasememberAt(grain,ip,el)
do source = 1, phase_Nsources(phase) do source = 1, phase_Nsources(phase)
select case(phase_source(source,phase)) select case(phase_source(source,phase))
case (SOURCE_damage_isoBrittle_ID) case (SOURCE_damage_isoBrittle_ID)
call source_damage_isobrittle_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) call source_damage_isobrittle_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
@ -163,12 +146,12 @@ subroutine damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el
end select end select
phiDot = phiDot + localphiDot phiDot = phiDot + localphiDot
dPhiDot_dPhi = dPhiDot_dPhi + dLocalphiDot_dPhi dPhiDot_dPhi = dPhiDot_dPhi + dLocalphiDot_dPhi
enddo enddo
enddo enddo
phiDot = phiDot/real(homogenization_Ngrains(material_homogenizationAt(el)),pReal) phiDot = phiDot/real(homogenization_Ngrains(material_homogenizationAt(el)),pReal)
dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Ngrains(material_homogenizationAt(el)),pReal) dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Ngrains(material_homogenizationAt(el)),pReal)
end subroutine damage_local_getSourceAndItsTangent end subroutine damage_local_getSourceAndItsTangent
@ -179,14 +162,13 @@ subroutine damage_local_results(homog,group)
integer, intent(in) :: homog integer, intent(in) :: homog
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: o
associate(prm => param(damage_typeInstance(homog)))
outputsLoop: do o = 1,size(prm%outputID) integer :: o
select case(prm%outputID(o))
associate(prm => param(damage_typeInstance(homog)))
case (damage_ID) outputsLoop: do o = 1,size(prm%output)
select case(prm%output(o))
case ('damage')
call results_writeDataset(group,damage(homog)%p,'phi',& call results_writeDataset(group,damage(homog)%p,'phi',&
'damage indicator','-') 'damage indicator','-')
end select end select

View File

@ -8,7 +8,7 @@ module damage_none
implicit none implicit none
public public
contains contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -28,10 +28,10 @@ subroutine damage_none_init
allocate(damageState(h)%state0 (0,NofMyHomog)) allocate(damageState(h)%state0 (0,NofMyHomog))
allocate(damageState(h)%subState0(0,NofMyHomog)) allocate(damageState(h)%subState0(0,NofMyHomog))
allocate(damageState(h)%state (0,NofMyHomog)) allocate(damageState(h)%state (0,NofMyHomog))
deallocate(damage(h)%p) deallocate(damage(h)%p)
allocate (damage(h)%p(1), source=damage_initialPhi(h)) allocate (damage(h)%p(1), source=damage_initialPhi(h))
enddo enddo
end subroutine damage_none_init end subroutine damage_none_init

View File

@ -18,27 +18,21 @@ module damage_nonlocal
implicit none implicit none
private private
enum, bind(c)
enumerator :: &
undefined_ID, &
damage_ID
end enum
type :: tParameters type :: tParameters
integer(kind(undefined_ID)), dimension(:), allocatable :: & character(len=pStringLen), allocatable, dimension(:) :: &
outputID output
end type tParameters end type tParameters
type(tparameters), dimension(:), allocatable :: & type(tparameters), dimension(:), allocatable :: &
param param
public :: & public :: &
damage_nonlocal_init, & damage_nonlocal_init, &
damage_nonlocal_getSourceAndItsTangent, & damage_nonlocal_getSourceAndItsTangent, &
damage_nonlocal_getDiffusion33, & damage_nonlocal_getDiffusion, &
damage_nonlocal_getMobility, & damage_nonlocal_getMobility, &
damage_nonlocal_putNonLocalDamage, & damage_nonlocal_putNonLocalDamage, &
damage_nonlocal_Results damage_nonlocal_results
contains contains
@ -48,29 +42,18 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine damage_nonlocal_init subroutine damage_nonlocal_init
integer :: maxNinstance,o,NofMyHomog,h integer :: Ninstance,NofMyHomog,h
character(len=pStringLen), dimension(:), allocatable :: outputs
write(6,'(/,a)') ' <<<+- damage_'//DAMAGE_nonlocal_label//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- damage_'//DAMAGE_nonlocal_label//' init -+>>>'; flush(6)
maxNinstance = count(damage_type == DAMAGE_nonlocal_ID)
if (maxNinstance == 0) return
allocate(param(maxNinstance)) Ninstance = count(damage_type == DAMAGE_nonlocal_ID)
allocate(param(Ninstance))
do h = 1, size(damage_type)
do h = 1, size(config_homogenization)
if (damage_type(h) /= DAMAGE_NONLOCAL_ID) cycle if (damage_type(h) /= DAMAGE_NONLOCAL_ID) cycle
associate(prm => param(damage_typeInstance(h)),config => config_homogenization(h)) associate(prm => param(damage_typeInstance(h)),config => config_homogenization(h))
outputs = config%getStrings('(output)',defaultVal=emptyStringArray) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
allocate(prm%outputID(0))
do o=1, size(outputs)
select case(outputs(o))
case ('damage')
prm%outputID = [prm%outputID, damage_ID]
end select
enddo
NofMyHomog = count(material_homogenizationAt == h) NofMyHomog = count(material_homogenizationAt == h)
damageState(h)%sizeState = 1 damageState(h)%sizeState = 1
@ -82,7 +65,7 @@ subroutine damage_nonlocal_init
damageMapping(h)%p => material_homogenizationMemberAt damageMapping(h)%p => material_homogenizationMemberAt
deallocate(damage(h)%p) deallocate(damage(h)%p)
damage(h)%p => damageState(h)%state(1,:) damage(h)%p => damageState(h)%state(1,:)
end associate end associate
enddo enddo
@ -90,10 +73,10 @@ end subroutine damage_nonlocal_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates homogenized damage driving forces !> @brief calculates homogenized damage driving forces
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el) subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
el !< element number el !< element number
@ -105,7 +88,7 @@ subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip,
source, & source, &
constituent constituent
real(pReal) :: & real(pReal) :: &
phiDot, dPhiDot_dPhi, localphiDot, dLocalphiDot_dPhi phiDot, dPhiDot_dPhi, localphiDot, dLocalphiDot_dPhi
phiDot = 0.0_pReal phiDot = 0.0_pReal
dPhiDot_dPhi = 0.0_pReal dPhiDot_dPhi = 0.0_pReal
@ -113,7 +96,7 @@ subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip,
phase = material_phaseAt(grain,el) phase = material_phaseAt(grain,el)
constituent = material_phasememberAt(grain,ip,el) constituent = material_phasememberAt(grain,ip,el)
do source = 1, phase_Nsources(phase) do source = 1, phase_Nsources(phase)
select case(phase_source(source,phase)) select case(phase_source(source,phase))
case (SOURCE_damage_isoBrittle_ID) case (SOURCE_damage_isoBrittle_ID)
call source_damage_isobrittle_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) call source_damage_isobrittle_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
@ -133,44 +116,44 @@ subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip,
end select end select
phiDot = phiDot + localphiDot phiDot = phiDot + localphiDot
dPhiDot_dPhi = dPhiDot_dPhi + dLocalphiDot_dPhi dPhiDot_dPhi = dPhiDot_dPhi + dLocalphiDot_dPhi
enddo enddo
enddo enddo
phiDot = phiDot/real(homogenization_Ngrains(material_homogenizationAt(el)),pReal) phiDot = phiDot/real(homogenization_Ngrains(material_homogenizationAt(el)),pReal)
dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Ngrains(material_homogenizationAt(el)),pReal) dPhiDot_dPhi = dPhiDot_dPhi/real(homogenization_Ngrains(material_homogenizationAt(el)),pReal)
end subroutine damage_nonlocal_getSourceAndItsTangent end subroutine damage_nonlocal_getSourceAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns homogenized non local damage diffusion tensor in reference configuration !> @brief returns homogenized non local damage diffusion tensor in reference configuration
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function damage_nonlocal_getDiffusion33(ip,el) function damage_nonlocal_getDiffusion(ip,el)
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
el !< element number el !< element number
real(pReal), dimension(3,3) :: & real(pReal), dimension(3,3) :: &
damage_nonlocal_getDiffusion33 damage_nonlocal_getDiffusion
integer :: & integer :: &
homog, & homog, &
grain grain
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
damage_nonlocal_getDiffusion33 = 0.0_pReal damage_nonlocal_getDiffusion = 0.0_pReal
do grain = 1, homogenization_Ngrains(homog) do grain = 1, homogenization_Ngrains(homog)
damage_nonlocal_getDiffusion33 = damage_nonlocal_getDiffusion33 + & damage_nonlocal_getDiffusion = damage_nonlocal_getDiffusion + &
crystallite_push33ToRef(grain,ip,el,lattice_DamageDiffusion33(1:3,1:3,material_phaseAt(grain,el))) crystallite_push33ToRef(grain,ip,el,lattice_DamageDiffusion(1:3,1:3,material_phaseAt(grain,el)))
enddo enddo
damage_nonlocal_getDiffusion33 = & damage_nonlocal_getDiffusion = &
charLength**2*damage_nonlocal_getDiffusion33/real(homogenization_Ngrains(homog),pReal) charLength**2*damage_nonlocal_getDiffusion/real(homogenization_Ngrains(homog),pReal)
end function damage_nonlocal_getDiffusion33 end function damage_nonlocal_getDiffusion
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Returns homogenized nonlocal damage mobility !> @brief Returns homogenized nonlocal damage mobility
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
real(pReal) function damage_nonlocal_getMobility(ip,el) real(pReal) function damage_nonlocal_getMobility(ip,el)
@ -179,9 +162,9 @@ real(pReal) function damage_nonlocal_getMobility(ip,el)
el !< element number el !< element number
integer :: & integer :: &
ipc ipc
damage_nonlocal_getMobility = 0.0_pReal damage_nonlocal_getMobility = 0.0_pReal
do ipc = 1, homogenization_Ngrains(material_homogenizationAt(el)) do ipc = 1, homogenization_Ngrains(material_homogenizationAt(el))
damage_nonlocal_getMobility = damage_nonlocal_getMobility + lattice_DamageMobility(material_phaseAt(ipc,el)) damage_nonlocal_getMobility = damage_nonlocal_getMobility + lattice_DamageMobility(material_phaseAt(ipc,el))
enddo enddo
@ -205,7 +188,7 @@ subroutine damage_nonlocal_putNonLocalDamage(phi,ip,el)
integer :: & integer :: &
homog, & homog, &
offset offset
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
offset = damageMapping(homog)%p(ip,el) offset = damageMapping(homog)%p(ip,el)
damage(homog)%p(offset) = phi damage(homog)%p(offset) = phi
@ -220,14 +203,13 @@ subroutine damage_nonlocal_results(homog,group)
integer, intent(in) :: homog integer, intent(in) :: homog
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: o
associate(prm => param(damage_typeInstance(homog)))
outputsLoop: do o = 1,size(prm%outputID) integer :: o
select case(prm%outputID(o))
associate(prm => param(damage_typeInstance(homog)))
case (damage_ID) outputsLoop: do o = 1,size(prm%output)
select case(prm%output(o))
case ('damage')
call results_writeDataset(group,damage(homog)%p,'phi',& call results_writeDataset(group,damage(homog)%p,'phi',&
'damage indicator','-') 'damage indicator','-')
end select end select

View File

@ -249,8 +249,8 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr)
cell = 0 cell = 0
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
cell = cell + 1 cell = cell + 1
vectorField_real(1:3,i,j,k) = matmul(damage_nonlocal_getDiffusion33(1,cell) - K_ref, & vectorField_real(1:3,i,j,k) = matmul(damage_nonlocal_getDiffusion(1,cell) - K_ref, &
vectorField_real(1:3,i,j,k)) vectorField_real(1:3,i,j,k))
enddo; enddo; enddo enddo; enddo; enddo
call utilities_FFTvectorForward call utilities_FFTvectorForward
call utilities_fourierVectorDivergence !< calculate damage divergence in fourier field call utilities_fourierVectorDivergence !< calculate damage divergence in fourier field
@ -294,7 +294,7 @@ subroutine updateReference
mu_ref = 0.0_pReal mu_ref = 0.0_pReal
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
cell = cell + 1 cell = cell + 1
K_ref = K_ref + damage_nonlocal_getDiffusion33(1,cell) K_ref = K_ref + damage_nonlocal_getDiffusion(1,cell)
mu_ref = mu_ref + damage_nonlocal_getMobility(1,cell) mu_ref = mu_ref + damage_nonlocal_getMobility(1,cell)
enddo; enddo; enddo enddo; enddo; enddo
K_ref = K_ref*wgt K_ref = K_ref*wgt

View File

@ -252,8 +252,8 @@ subroutine formResidual(in,x_scal,f_scal,dummy,ierr)
cell = 0 cell = 0
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
cell = cell + 1 cell = cell + 1
vectorField_real(1:3,i,j,k) = matmul(thermal_conduction_getConductivity33(1,cell) - K_ref, & vectorField_real(1:3,i,j,k) = matmul(thermal_conduction_getConductivity(1,cell) - K_ref, &
vectorField_real(1:3,i,j,k)) vectorField_real(1:3,i,j,k))
enddo; enddo; enddo enddo; enddo; enddo
call utilities_FFTvectorForward call utilities_FFTvectorForward
call utilities_fourierVectorDivergence !< calculate temperature divergence in fourier field call utilities_fourierVectorDivergence !< calculate temperature divergence in fourier field
@ -294,9 +294,8 @@ subroutine updateReference
mu_ref = 0.0_pReal mu_ref = 0.0_pReal
do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1) do k = 1, grid3; do j = 1, grid(2); do i = 1,grid(1)
cell = cell + 1 cell = cell + 1
K_ref = K_ref + thermal_conduction_getConductivity33(1,cell) K_ref = K_ref + thermal_conduction_getConductivity(1,cell)
mu_ref = mu_ref + thermal_conduction_getMassDensity(1,cell)* & mu_ref = mu_ref + thermal_conduction_getMassDensity(1,cell)* thermal_conduction_getSpecificHeat(1,cell)
thermal_conduction_getSpecificHeat(1,cell)
enddo; enddo; enddo enddo; enddo; enddo
K_ref = K_ref*wgt K_ref = K_ref*wgt
call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr) call MPI_Allreduce(MPI_IN_PLACE,K_ref,9,MPI_DOUBLE,MPI_SUM,PETSC_COMM_WORLD,ierr)

View File

@ -27,25 +27,12 @@ module kinematics_cleavage_opening
sdot0, & sdot0, &
n n
real(pReal), dimension(:), allocatable :: & real(pReal), dimension(:), allocatable :: &
critDisp, &
critLoad critLoad
end type real(pReal), dimension(:,:,:,:), allocatable :: &
cleavage_systems
end type tParameters
! Begin Deprecated type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance)
integer, dimension(:), allocatable :: &
kinematics_cleavage_opening_totalNcleavage !< total number of cleavage systems
integer, dimension(:,:), allocatable :: &
kinematics_cleavage_opening_Ncleavage !< number of cleavage systems per family
real(pReal), dimension(:), allocatable :: &
kinematics_cleavage_opening_sdot_0, &
kinematics_cleavage_opening_N
real(pReal), dimension(:,:), allocatable :: &
kinematics_cleavage_opening_critDisp, &
kinematics_cleavage_opening_critLoad
! End Deprecated
public :: & public :: &
kinematics_cleavage_opening_init, & kinematics_cleavage_opening_init, &
@ -60,66 +47,59 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine kinematics_cleavage_opening_init subroutine kinematics_cleavage_opening_init
integer, allocatable, dimension(:) :: tempInt integer :: Ninstance,p
real(pReal), allocatable, dimension(:) :: tempFloat character(len=pStringLen) :: extmsg = ''
integer :: maxNinstance,p,instance
write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_cleavage_opening_LABEL//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_cleavage_opening_LABEL//' init -+>>>'; flush(6)
maxNinstance = count(phase_kinematics == KINEMATICS_cleavage_opening_ID) Ninstance = count(phase_kinematics == KINEMATICS_cleavage_opening_ID)
if (maxNinstance == 0) return
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
allocate(kinematics_cleavage_opening_instance(size(config_phase)), source=0) allocate(kinematics_cleavage_opening_instance(size(config_phase)), source=0)
do p = 1, size(config_phase) allocate(param(Ninstance))
kinematics_cleavage_opening_instance(p) = count(phase_kinematics(:,1:p) == kinematics_cleavage_opening_ID) ! ToDo: count correct?
enddo
allocate(kinematics_cleavage_opening_critDisp(lattice_maxNcleavageFamily,maxNinstance), source=0.0_pReal)
allocate(kinematics_cleavage_opening_critLoad(lattice_maxNcleavageFamily,maxNinstance), source=0.0_pReal)
allocate(kinematics_cleavage_opening_Ncleavage(lattice_maxNcleavageFamily,maxNinstance), source=0)
allocate(kinematics_cleavage_opening_totalNcleavage(maxNinstance), source=0)
allocate(kinematics_cleavage_opening_sdot_0(maxNinstance), source=0.0_pReal)
allocate(kinematics_cleavage_opening_N(maxNinstance), source=0.0_pReal)
do p = 1, size(config_phase) do p = 1, size(config_phase)
kinematics_cleavage_opening_instance(p) = count(phase_kinematics(:,1:p) == kinematics_cleavage_opening_ID)
if (all(phase_kinematics(:,p) /= KINEMATICS_cleavage_opening_ID)) cycle if (all(phase_kinematics(:,p) /= KINEMATICS_cleavage_opening_ID)) cycle
instance = kinematics_cleavage_opening_instance(p)
kinematics_cleavage_opening_sdot_0(instance) = config_phase(p)%getFloat('anisobrittle_sdot0')
kinematics_cleavage_opening_N(instance) = config_phase(p)%getFloat('anisobrittle_ratesensitivity')
tempInt = config_phase(p)%getInts('ncleavage')
kinematics_cleavage_opening_Ncleavage(1:size(tempInt),instance) = tempInt
tempFloat = config_phase(p)%getFloats('anisobrittle_criticaldisplacement',requiredSize=size(tempInt)) associate(prm => param(kinematics_cleavage_opening_instance(p)), &
kinematics_cleavage_opening_critDisp(1:size(tempInt),instance) = tempFloat config => config_phase(p))
tempFloat = config_phase(p)%getFloats('anisobrittle_criticalload',requiredSize=size(tempInt)) prm%Ncleavage = config%getInts('ncleavage')
kinematics_cleavage_opening_critLoad(1:size(tempInt),instance) = tempFloat prm%totalNcleavage = sum(prm%Ncleavage)
prm%n = config%getFloat('anisobrittle_ratesensitivity')
prm%sdot0 = config%getFloat('anisobrittle_sdot0')
prm%critLoad = config%getFloats('anisobrittle_criticalload',requiredSize=size(prm%Ncleavage))
prm%cleavage_systems = lattice_SchmidMatrix_cleavage(prm%Ncleavage,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal))
! expand: family => system
prm%critLoad = math_expand(prm%critLoad, prm%Ncleavage)
! sanity checks
if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_n'
if (prm%sdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_sdot0'
if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_critLoad'
kinematics_cleavage_opening_Ncleavage(1:lattice_maxNcleavageFamily,instance) = &
min(lattice_NcleavageSystem(1:lattice_maxNcleavageFamily,p),& ! limit active cleavage systems per family to min of available and requested
kinematics_cleavage_opening_Ncleavage(1:lattice_maxNcleavageFamily,instance))
kinematics_cleavage_opening_totalNcleavage(instance) = sum(kinematics_cleavage_opening_Ncleavage(:,instance)) ! how many cleavage systems altogether
if (kinematics_cleavage_opening_sdot_0(instance) <= 0.0_pReal) &
call IO_error(211,el=instance,ext_msg='sdot_0 ('//KINEMATICS_cleavage_opening_LABEL//')')
if (any(kinematics_cleavage_opening_critDisp(1:size(tempInt),instance) < 0.0_pReal)) &
call IO_error(211,el=instance,ext_msg='critical_displacement ('//KINEMATICS_cleavage_opening_LABEL//')')
if (any(kinematics_cleavage_opening_critLoad(1:size(tempInt),instance) < 0.0_pReal)) &
call IO_error(211,el=instance,ext_msg='critical_load ('//KINEMATICS_cleavage_opening_LABEL//')')
if (kinematics_cleavage_opening_N(instance) <= 0.0_pReal) &
call IO_error(211,el=instance,ext_msg='rate_sensitivity ('//KINEMATICS_cleavage_opening_LABEL//')')
enddo
end subroutine kinematics_cleavage_opening_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient ! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ANISOBRITTLE_LABEL//')')
end associate
enddo
end subroutine kinematics_cleavage_opening_init
!--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc, ip, el) subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
ipc, & !< grain number ipc, & !< grain number
ip, & !< integration point number ip, & !< integration point number
@ -130,73 +110,55 @@ subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc, i
Ld !< damage velocity gradient Ld !< damage velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: & real(pReal), intent(out), dimension(3,3,3,3) :: &
dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor) dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor)
integer :: & integer :: &
instance, phase, &
homog, damageOffset, & homog, damageOffset, &
f, i, index_myFamily, k, l, m, n i, k, l, m, n
real(pReal) :: & real(pReal) :: &
traction_d, traction_t, traction_n, traction_crit, & traction_d, traction_t, traction_n, traction_crit, &
udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
phase = material_phaseAt(ipc,el)
instance = kinematics_cleavage_opening_instance(phase)
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
damageOffset = damageMapping(homog)%p(ip,el) damageOffset = damageMapping(homog)%p(ip,el)
Ld = 0.0_pReal Ld = 0.0_pReal
dLd_dTstar = 0.0_pReal dLd_dTstar = 0.0_pReal
do f = 1,lattice_maxNcleavageFamily associate(prm => param(kinematics_cleavage_opening_instance(material_phaseAt(ipc,el))))
index_myFamily = sum(lattice_NcleavageSystem(1:f-1,phase)) ! at which index starts my family do i = 1,prm%totalNcleavage
do i = 1,kinematics_cleavage_opening_Ncleavage(f,instance) ! process each (active) cleavage system in family traction_crit = prm%critLoad(i)* damage(homog)%p(damageOffset)**2.0_pReal
traction_d = math_mul33xx33(S,lattice_Scleavage(1:3,1:3,1,index_myFamily+i,phase))
traction_t = math_mul33xx33(S,lattice_Scleavage(1:3,1:3,2,index_myFamily+i,phase))
traction_n = math_mul33xx33(S,lattice_Scleavage(1:3,1:3,3,index_myFamily+i,phase))
traction_crit = kinematics_cleavage_opening_critLoad(f,instance)* &
damage(homog)%p(damageOffset)*damage(homog)%p(damageOffset)
udotd = &
sign(1.0_pReal,traction_d)* &
kinematics_cleavage_opening_sdot_0(instance)* &
(max(0.0_pReal, abs(traction_d) - traction_crit)/traction_crit)**kinematics_cleavage_opening_N(instance)
if (abs(udotd) > tol_math_check) then
Ld = Ld + udotd*lattice_Scleavage(1:3,1:3,1,index_myFamily+i,phase)
dudotd_dt = sign(1.0_pReal,traction_d)*udotd*kinematics_cleavage_opening_N(instance)/ &
max(0.0_pReal, abs(traction_d) - traction_crit)
forall (k=1:3,l=1:3,m=1:3,n=1:3) &
dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) + &
dudotd_dt*lattice_Scleavage(k,l,1,index_myFamily+i,phase)* &
lattice_Scleavage(m,n,1,index_myFamily+i,phase)
endif
udott = & traction_d = math_mul33xx33(S,prm%cleavage_systems(1:3,1:3,1,i))
sign(1.0_pReal,traction_t)* & if (abs(traction_d) > traction_crit + tol_math_check) then
kinematics_cleavage_opening_sdot_0(instance)* & udotd = sign(1.0_pReal,traction_d)* prm%sdot0 * ((abs(traction_d) - traction_crit)/traction_crit)**prm%n
(max(0.0_pReal, abs(traction_t) - traction_crit)/traction_crit)**kinematics_cleavage_opening_N(instance) Ld = Ld + udotd*prm%cleavage_systems(1:3,1:3,1,i)
if (abs(udott) > tol_math_check) then dudotd_dt = sign(1.0_pReal,traction_d)*udotd*prm%n / (abs(traction_d) - traction_crit)
Ld = Ld + udott*lattice_Scleavage(1:3,1:3,2,index_myFamily+i,phase) forall (k=1:3,l=1:3,m=1:3,n=1:3) &
dudott_dt = sign(1.0_pReal,traction_t)*udott*kinematics_cleavage_opening_N(instance)/ & dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) &
max(0.0_pReal, abs(traction_t) - traction_crit) + dudotd_dt*prm%cleavage_systems(k,l,1,i) * prm%cleavage_systems(m,n,1,i)
forall (k=1:3,l=1:3,m=1:3,n=1:3) & endif
dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) + &
dudott_dt*lattice_Scleavage(k,l,2,index_myFamily+i,phase)* &
lattice_Scleavage(m,n,2,index_myFamily+i,phase)
endif
udotn = & traction_t = math_mul33xx33(S,prm%cleavage_systems(1:3,1:3,2,i))
sign(1.0_pReal,traction_n)* & if (abs(traction_t) > traction_crit + tol_math_check) then
kinematics_cleavage_opening_sdot_0(instance)* & udott = sign(1.0_pReal,traction_t)* prm%sdot0 * ((abs(traction_t) - traction_crit)/traction_crit)**prm%n
(max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**kinematics_cleavage_opening_N(instance) Ld = Ld + udott*prm%cleavage_systems(1:3,1:3,2,i)
if (abs(udotn) > tol_math_check) then dudott_dt = sign(1.0_pReal,traction_t)*udott*prm%n / (abs(traction_t) - traction_crit)
Ld = Ld + udotn*lattice_Scleavage(1:3,1:3,3,index_myFamily+i,phase) forall (k=1:3,l=1:3,m=1:3,n=1:3) &
dudotn_dt = sign(1.0_pReal,traction_n)*udotn*kinematics_cleavage_opening_N(instance)/ & dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) &
max(0.0_pReal, abs(traction_n) - traction_crit) + dudott_dt*prm%cleavage_systems(k,l,2,i) * prm%cleavage_systems(m,n,2,i)
forall (k=1:3,l=1:3,m=1:3,n=1:3) & endif
dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) + &
dudotn_dt*lattice_Scleavage(k,l,3,index_myFamily+i,phase)* & traction_n = math_mul33xx33(S,prm%cleavage_systems(1:3,1:3,3,i))
lattice_Scleavage(m,n,3,index_myFamily+i,phase) if (abs(traction_n) > traction_crit + tol_math_check) then
endif udotn = sign(1.0_pReal,traction_n)* prm%sdot0 * ((abs(traction_n) - traction_crit)/traction_crit)**prm%n
enddo Ld = Ld + udotn*prm%cleavage_systems(1:3,1:3,3,i)
dudotn_dt = sign(1.0_pReal,traction_n)*udotn*prm%n / (abs(traction_n) - traction_crit)
forall (k=1:3,l=1:3,m=1:3,n=1:3) &
dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) &
+ dudotn_dt*prm%cleavage_systems(k,l,3,i) * prm%cleavage_systems(m,n,3,i)
endif
enddo enddo
end associate
end subroutine kinematics_cleavage_opening_LiAndItsTangent end subroutine kinematics_cleavage_opening_LiAndItsTangent
end module kinematics_cleavage_opening end module kinematics_cleavage_opening

View File

@ -12,12 +12,12 @@ module kinematics_slipplane_opening
use math use math
use lattice use lattice
use material use material
implicit none implicit none
private private
integer, dimension(:), allocatable :: kinematics_slipplane_opening_instance integer, dimension(:), allocatable :: kinematics_slipplane_opening_instance
type :: tParameters !< container type for internal constitutive parameters type :: tParameters !< container type for internal constitutive parameters
integer :: & integer :: &
totalNslip totalNslip
@ -28,14 +28,14 @@ module kinematics_slipplane_opening
n n
real(pReal), dimension(:), allocatable :: & real(pReal), dimension(:), allocatable :: &
critLoad critLoad
real(pReal), dimension(:,:), allocatable :: & real(pReal), dimension(:,:,:), allocatable :: &
slip_direction, & P_d, &
slip_normal, & P_t, &
slip_transverse P_n
end type tParameters end type tParameters
type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance)
public :: & public :: &
kinematics_slipplane_opening_init, & kinematics_slipplane_opening_init, &
kinematics_slipplane_opening_LiAndItsTangent kinematics_slipplane_opening_LiAndItsTangent
@ -49,58 +49,66 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine kinematics_slipplane_opening_init subroutine kinematics_slipplane_opening_init
integer :: maxNinstance,p,instance integer :: Ninstance,p,i
character(len=pStringLen) :: extmsg = ''
real(pReal), dimension(:,:), allocatable :: d,n,t
write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_slipplane_opening_LABEL//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_slipplane_opening_LABEL//' init -+>>>'; flush(6)
maxNinstance = count(phase_kinematics == KINEMATICS_slipplane_opening_ID) Ninstance = count(phase_kinematics == KINEMATICS_slipplane_opening_ID)
if (maxNinstance == 0) return
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
allocate(kinematics_slipplane_opening_instance(size(config_phase)), source=0) allocate(kinematics_slipplane_opening_instance(size(config_phase)), source=0)
allocate(param(Ninstance))
do p = 1, size(config_phase) do p = 1, size(config_phase)
kinematics_slipplane_opening_instance(p) = count(phase_kinematics(:,1:p) == kinematics_slipplane_opening_ID) ! ToDo: count correct? kinematics_slipplane_opening_instance(p) = count(phase_kinematics(:,1:p) == kinematics_slipplane_opening_ID)
enddo
allocate(param(maxNinstance))
do p = 1, size(config_phase)
if (all(phase_kinematics(:,p) /= KINEMATICS_slipplane_opening_ID)) cycle if (all(phase_kinematics(:,p) /= KINEMATICS_slipplane_opening_ID)) cycle
associate(prm => param(kinematics_slipplane_opening_instance(p)), & associate(prm => param(kinematics_slipplane_opening_instance(p)), &
config => config_phase(p)) config => config_phase(p))
instance = kinematics_slipplane_opening_instance(p)
prm%sdot0 = config_phase(p)%getFloat('anisoductile_sdot0')
prm%n = config_phase(p)%getFloat('anisoductile_ratesensitivity')
prm%Nslip = config%getInts('nslip')
prm%critLoad = config_phase(p)%getFloats('anisoductile_criticalload',requiredSize=size(prm%Nslip )) prm%sdot0 = config%getFloat('anisoductile_sdot0')
prm%n = config%getFloat('anisoductile_ratesensitivity')
prm%Nslip = config%getInts('nslip')
prm%totalNslip = sum(prm%Nslip)
d = lattice_slip_direction (prm%Nslip,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal))
t = lattice_slip_transverse(prm%Nslip,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal))
n = lattice_slip_normal (prm%Nslip,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal))
allocate(prm%P_d(3,3,size(d,2)),prm%P_t(3,3,size(t,2)),prm%P_n(3,3,size(n,2)))
do i=1, size(n,2)
prm%P_d(1:3,1:3,i) = math_outer(d(1:3,i), n(1:3,i))
prm%P_t(1:3,1:3,i) = math_outer(t(1:3,i), n(1:3,i))
prm%P_n(1:3,1:3,i) = math_outer(n(1:3,i), n(1:3,i))
enddo
prm%critLoad = config%getFloats('anisoductile_criticalload',requiredSize=size(prm%Nslip))
! expand: family => system
prm%critLoad = math_expand(prm%critLoad, prm%Nslip) prm%critLoad = math_expand(prm%critLoad, prm%Nslip)
prm%slip_direction = lattice_slip_direction (prm%Nslip,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal))
prm%slip_normal = lattice_slip_normal (prm%Nslip,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal))
prm%slip_transverse = lattice_slip_transverse(prm%Nslip,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal))
! if (kinematics_slipplane_opening_sdot_0(instance) <= 0.0_pReal) & ! sanity checks
! call IO_error(211,el=instance,ext_msg='sdot_0 ('//KINEMATICS_slipplane_opening_LABEL//')') if (prm%n <= 0.0_pReal) extmsg = trim(extmsg)//' anisoDuctile_n'
! if (any(kinematics_slipplane_opening_critPlasticStrain(:,instance) < 0.0_pReal)) & if (prm%sdot0 <= 0.0_pReal) extmsg = trim(extmsg)//' anisoDuctile_sdot0'
! call IO_error(211,el=instance,ext_msg='criticaPlasticStrain ('//KINEMATICS_slipplane_opening_LABEL//')') if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' anisoDuctile_critLoad'
! if (kinematics_slipplane_opening_N(instance) <= 0.0_pReal) &
! call IO_error(211,el=instance,ext_msg='rate_sensitivity ('//KINEMATICS_slipplane_opening_LABEL//')')
end associate
enddo
end subroutine kinematics_slipplane_opening_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient ! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ANISODUCTILE_LABEL//')')
end associate
enddo
end subroutine kinematics_slipplane_opening_init
!--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc, ip, el) subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc, ip, el)
@ -114,8 +122,7 @@ subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc,
Ld !< damage velocity gradient Ld !< damage velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: & real(pReal), intent(out), dimension(3,3,3,3) :: &
dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor) dLd_dTstar !< derivative of Ld with respect to Tstar (4th-order tensor)
real(pReal), dimension(3,3) :: &
projection_d, projection_t, projection_n !< projection modes 3x3 tensor
integer :: & integer :: &
instance, phase, & instance, phase, &
homog, damageOffset, & homog, damageOffset, &
@ -123,26 +130,22 @@ subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc,
real(pReal) :: & real(pReal) :: &
traction_d, traction_t, traction_n, traction_crit, & traction_d, traction_t, traction_n, traction_crit, &
udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
phase = material_phaseAt(ipc,el) phase = material_phaseAt(ipc,el)
instance = kinematics_slipplane_opening_instance(phase) instance = kinematics_slipplane_opening_instance(phase)
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
damageOffset = damageMapping(homog)%p(ip,el) damageOffset = damageMapping(homog)%p(ip,el)
associate(prm => param(instance)) associate(prm => param(instance))
Ld = 0.0_pReal Ld = 0.0_pReal
dLd_dTstar = 0.0_pReal dLd_dTstar = 0.0_pReal
do i = 1, prm%totalNslip do i = 1, prm%totalNslip
projection_d = math_outer(prm%slip_direction(1:3,i), prm%slip_normal(1:3,i)) traction_d = math_tensordot(S,prm%P_d(1:3,1:3,i))
projection_t = math_outer(prm%slip_transverse(1:3,i),prm%slip_normal(1:3,i)) traction_t = math_tensordot(S,prm%P_t(1:3,1:3,i))
projection_n = math_outer(prm%slip_normal(1:3,i), prm%slip_normal(1:3,i)) traction_n = math_tensordot(S,prm%P_n(1:3,1:3,i))
traction_d = math_mul33xx33(S,projection_d) traction_crit = prm%critLoad(i)* damage(homog)%p(damageOffset) ! degrading critical load carrying capacity by damage
traction_t = math_mul33xx33(S,projection_t)
traction_n = math_mul33xx33(S,projection_n)
traction_crit = prm%critLoad(i)* damage(homog)%p(damageOffset) ! degrading critical load carrying capacity by damage
udotd = sign(1.0_pReal,traction_d)* prm%sdot0* ( abs(traction_d)/traction_crit & udotd = sign(1.0_pReal,traction_d)* prm%sdot0* ( abs(traction_d)/traction_crit &
- abs(traction_d)/prm%critLoad(i))**prm%n - abs(traction_d)/prm%critLoad(i))**prm%n
@ -151,20 +154,34 @@ subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar, S, ipc,
udotn = prm%sdot0* ( max(0.0_pReal,traction_n)/traction_crit & udotn = prm%sdot0* ( max(0.0_pReal,traction_n)/traction_crit &
- max(0.0_pReal,traction_n)/prm%critLoad(i))**prm%n - max(0.0_pReal,traction_n)/prm%critLoad(i))**prm%n
dudotd_dt = udotd*prm%n/traction_d if (dNeq0(traction_d)) then
dudott_dt = udott*prm%n/traction_t dudotd_dt = udotd*prm%n/traction_d
dudotn_dt = udotn*prm%n/traction_n else
dudotd_dt = 0.0_pReal
endif
if (dNeq0(traction_t)) then
dudott_dt = udott*prm%n/traction_t
else
dudott_dt = 0.0_pReal
endif
if (dNeq0(traction_n)) then
dudotn_dt = udotn*prm%n/traction_n
else
dudotn_dt = 0.0_pReal
endif
forall (k=1:3,l=1:3,m=1:3,n=1:3) & forall (k=1:3,l=1:3,m=1:3,n=1:3) &
dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) + dudotd_dt*projection_d(k,l)*projection_d(m,n) & dLd_dTstar(k,l,m,n) = dLd_dTstar(k,l,m,n) &
+ dudott_dt*projection_t(k,l)*projection_t(m,n) & + dudotd_dt*prm%P_d(k,l,i)*prm%P_d(m,n,i) &
+ dudotn_dt*projection_n(k,l)*projection_n(m,n) + dudott_dt*prm%P_t(k,l,i)*prm%P_t(m,n,i) &
+ dudotn_dt*prm%P_n(k,l,i)*prm%P_n(m,n,i)
Ld = Ld + udotd*projection_d & Ld = Ld &
+ udott*projection_t & + udotd*prm%P_d(1:3,1:3,i) &
+ udotn*projection_n + udott*prm%P_t(1:3,1:3,i) &
+ udotn*prm%P_n(1:3,1:3,i)
enddo enddo
end associate end associate
end subroutine kinematics_slipplane_opening_LiAndItsTangent end subroutine kinematics_slipplane_opening_LiAndItsTangent

View File

@ -11,17 +11,21 @@ module kinematics_thermal_expansion
use math use math
use lattice use lattice
use material use material
implicit none implicit none
private private
integer, dimension(:), allocatable :: kinematics_thermal_expansion_instance
type :: tParameters type :: tParameters
real(pReal), allocatable, dimension(:,:,:) :: & real(pReal) :: &
expansion T_ref
real(pReal), dimension(3,3,3) :: &
expansion = 0.0_pReal
end type tParameters end type tParameters
type(tParameters), dimension(:), allocatable :: param type(tParameters), dimension(:), allocatable :: param
public :: & public :: &
kinematics_thermal_expansion_init, & kinematics_thermal_expansion_init, &
kinematics_thermal_expansion_initialStrain, & kinematics_thermal_expansion_initialStrain, &
@ -35,36 +39,40 @@ contains
!> @details reads in material parameters, allocates arrays, and does sanity checks !> @details reads in material parameters, allocates arrays, and does sanity checks
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine kinematics_thermal_expansion_init subroutine kinematics_thermal_expansion_init
integer :: & integer :: Ninstance,p,i
Ninstance, & real(pReal), dimension(:), allocatable :: temp
p, i
real(pReal), dimension(:), allocatable :: &
temp
write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_thermal_expansion_LABEL//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_thermal_expansion_LABEL//' init -+>>>'; flush(6)
Ninstance = count(phase_kinematics == KINEMATICS_thermal_expansion_ID) Ninstance = count(phase_kinematics == KINEMATICS_thermal_expansion_ID)
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
allocate(kinematics_thermal_expansion_instance(size(config_phase)), source=0)
allocate(param(Ninstance)) allocate(param(Ninstance))
do p = 1, size(phase_kinematics) do p = 1, size(config_phase)
kinematics_thermal_expansion_instance(p) = count(phase_kinematics(:,1:p) == KINEMATICS_thermal_expansion_ID)
if (all(phase_kinematics(:,p) /= KINEMATICS_thermal_expansion_ID)) cycle if (all(phase_kinematics(:,p) /= KINEMATICS_thermal_expansion_ID)) cycle
! ToDo: Here we need to decide how to extend the concept of instances to associate(prm => param(kinematics_thermal_expansion_instance(p)), &
! kinetics and sources. I would suggest that the same mechanism exists at maximum once per phase config => config_phase(p))
prm%T_ref = config%getFloat('reference_temperature', defaultVal=0.0_pReal)
! read up to three parameters (constant, linear, quadratic with T) ! read up to three parameters (constant, linear, quadratic with T)
temp = config_phase(p)%getFloats('thermal_expansion11') temp = config%getFloats('thermal_expansion11')
!lattice_thermalExpansion33(1,1,1:size(temp),p) = temp prm%expansion(1,1,1:size(temp)) = temp
temp = config_phase(p)%getFloats('thermal_expansion22', & temp = config%getFloats('thermal_expansion22',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp))
defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp)) prm%expansion(2,2,1:size(temp)) = temp
!lattice_thermalExpansion33(2,2,1:size(temp),p) = temp temp = config%getFloats('thermal_expansion33',defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp))
temp = config_phase(p)%getFloats('thermal_expansion33', & prm%expansion(3,3,1:size(temp)) = temp
defaultVal=[(0.0_pReal, i=1,size(temp))],requiredSize=size(temp)) do i=1, size(prm%expansion,3)
prm%expansion(1:3,1:3,i) = lattice_applyLatticeSymmetry33(prm%expansion(1:3,1:3,i),config%getString('lattice_structure'))
enddo
end associate
enddo enddo
end subroutine kinematics_thermal_expansion_init end subroutine kinematics_thermal_expansion_init
@ -74,30 +82,30 @@ end subroutine kinematics_thermal_expansion_init
!> @brief report initial thermal strain based on current temperature deviation from reference !> @brief report initial thermal strain based on current temperature deviation from reference
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
pure function kinematics_thermal_expansion_initialStrain(homog,phase,offset) pure function kinematics_thermal_expansion_initialStrain(homog,phase,offset)
integer, intent(in) :: & integer, intent(in) :: &
phase, & phase, &
homog, offset homog, &
offset
real(pReal), dimension(3,3) :: & real(pReal), dimension(3,3) :: &
kinematics_thermal_expansion_initialStrain !< initial thermal strain (should be small strain, though) kinematics_thermal_expansion_initialStrain !< initial thermal strain (should be small strain, though)
associate(prm => param(kinematics_thermal_expansion_instance(phase)))
kinematics_thermal_expansion_initialStrain = & kinematics_thermal_expansion_initialStrain = &
(temperature(homog)%p(offset) - lattice_referenceTemperature(phase))**1 / 1. * & (temperature(homog)%p(offset) - prm%T_ref)**1 / 1. * prm%expansion(1:3,1:3,1) + & ! constant coefficient
lattice_thermalExpansion33(1:3,1:3,1,phase) + & ! constant coefficient (temperature(homog)%p(offset) - prm%T_ref)**2 / 2. * prm%expansion(1:3,1:3,2) + & ! linear coefficient
(temperature(homog)%p(offset) - lattice_referenceTemperature(phase))**2 / 2. * & (temperature(homog)%p(offset) - prm%T_ref)**3 / 3. * prm%expansion(1:3,1:3,3) ! quadratic coefficient
lattice_thermalExpansion33(1:3,1:3,2,phase) + & ! linear coefficient end associate
(temperature(homog)%p(offset) - lattice_referenceTemperature(phase))**3 / 3. * &
lattice_thermalExpansion33(1:3,1:3,3,phase) ! quadratic coefficient
end function kinematics_thermal_expansion_initialStrain end function kinematics_thermal_expansion_initialStrain
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient !> @brief contains the constitutive equation for calculating the velocity gradient
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar, ipc, ip, el) subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar, ipc, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
ipc, & !< grain number ipc, & !< grain number
ip, & !< integration point number ip, & !< integration point number
@ -106,31 +114,32 @@ subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar, ipc, ip,
Li !< thermal velocity gradient Li !< thermal velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: & real(pReal), intent(out), dimension(3,3,3,3) :: &
dLi_dTstar !< derivative of Li with respect to Tstar (4th-order tensor defined to be zero) dLi_dTstar !< derivative of Li with respect to Tstar (4th-order tensor defined to be zero)
integer :: & integer :: &
phase, & phase, &
homog, offset homog
real(pReal) :: & real(pReal) :: &
T, TRef, TDot T, TDot
phase = material_phaseAt(ipc,el) phase = material_phaseAt(ipc,el)
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
offset = thermalMapping(homog)%p(ip,el) T = temperature(homog)%p(thermalMapping(homog)%p(ip,el))
T = temperature(homog)%p(offset) TDot = temperatureRate(homog)%p(thermalMapping(homog)%p(ip,el))
TDot = temperatureRate(homog)%p(offset)
TRef = lattice_referenceTemperature(phase) associate(prm => param(kinematics_thermal_expansion_instance(phase)))
Li = TDot * ( & Li = TDot * ( &
lattice_thermalExpansion33(1:3,1:3,1,phase)*(T - TRef)**0 & ! constant coefficient prm%expansion(1:3,1:3,1)*(T - prm%T_ref)**0 & ! constant coefficient
+ lattice_thermalExpansion33(1:3,1:3,2,phase)*(T - TRef)**1 & ! linear coefficient + prm%expansion(1:3,1:3,2)*(T - prm%T_ref)**1 & ! linear coefficient
+ lattice_thermalExpansion33(1:3,1:3,3,phase)*(T - TRef)**2 & ! quadratic coefficient + prm%expansion(1:3,1:3,3)*(T - prm%T_ref)**2 & ! quadratic coefficient
) / & ) / &
(1.0_pReal & (1.0_pReal &
+ lattice_thermalExpansion33(1:3,1:3,1,phase)*(T - TRef)**1 / 1. & + prm%expansion(1:3,1:3,1)*(T - prm%T_ref)**1 / 1. &
+ lattice_thermalExpansion33(1:3,1:3,2,phase)*(T - TRef)**2 / 2. & + prm%expansion(1:3,1:3,2)*(T - prm%T_ref)**2 / 2. &
+ lattice_thermalExpansion33(1:3,1:3,3,phase)*(T - TRef)**3 / 3. & + prm%expansion(1:3,1:3,3)*(T - prm%T_ref)**3 / 3. &
) )
dLi_dTstar = 0.0_pReal end associate
dLi_dTstar = 0.0_pReal
end subroutine kinematics_thermal_expansion_LiAndItsTangent end subroutine kinematics_thermal_expansion_LiAndItsTangent
end module kinematics_thermal_expansion end module kinematics_thermal_expansion

File diff suppressed because it is too large Load Diff

View File

@ -11,30 +11,31 @@ module prec
implicit none implicit none
public public
! https://software.intel.com/en-us/blogs/2017/03/27/doctor-fortran-in-it-takes-all-kinds ! https://software.intel.com/en-us/blogs/2017/03/27/doctor-fortran-in-it-takes-all-kinds
integer, parameter, public :: pReal = IEEE_selected_real_kind(15,307) !< number with 15 significant digits, up to 1e+-307 (typically 64 bit) integer, parameter :: pReal = IEEE_selected_real_kind(15,307) !< number with 15 significant digits, up to 1e+-307 (typically 64 bit)
#if(INT==8) #if(INT==8)
integer, parameter, public :: pInt = selected_int_kind(18) !< number with at least up to +-1e18 (typically 64 bit) integer, parameter :: pInt = selected_int_kind(18) !< number with at least up to +-1e18 (typically 64 bit)
#else #else
integer, parameter, public :: pInt = selected_int_kind(9) !< number with at least up to +-1e9 (typically 32 bit) integer, parameter :: pInt = selected_int_kind(9) !< number with at least up to +-1e9 (typically 32 bit)
#endif #endif
integer, parameter, public :: pLongInt = selected_int_kind(18) !< number with at least up to +-1e18 (typically 64 bit) integer, parameter :: pLongInt = selected_int_kind(18) !< number with at least up to +-1e18 (typically 64 bit)
integer, parameter, public :: pStringLen = 256 !< default string length integer, parameter :: pStringLen = 256 !< default string length
integer, parameter, public :: pPathLen = 4096 !< maximum length of a path name on linux integer, parameter :: pPathLen = 4096 !< maximum length of a path name on linux
real(pReal), parameter, public :: tol_math_check = 1.0e-8_pReal !< tolerance for internal math self-checks (rotation) real(pReal), parameter :: tol_math_check = 1.0e-8_pReal !< tolerance for internal math self-checks (rotation)
type, public :: group_float !< variable length datatype used for storage of state type :: group_float !< variable length datatype used for storage of state
real(pReal), dimension(:), pointer :: p real(pReal), dimension(:), pointer :: p
end type group_float end type group_float
type, public :: group_int type :: group_int
integer, dimension(:), pointer :: p integer, dimension(:), pointer :: p
end type group_int end type group_int
! http://stackoverflow.com/questions/3948210/can-i-have-a-pointer-to-an-item-in-an-allocatable-array ! http://stackoverflow.com/questions/3948210/can-i-have-a-pointer-to-an-item-in-an-allocatable-array
type, public :: tState type :: tState
integer :: & integer :: &
sizeState = 0, & !< size of state sizeState = 0, & !< size of state
sizeDotState = 0, & !< size of dot state, i.e. state(1:sizeDot) follows time evolution by dotState rates sizeDotState = 0, & !< size of dot state, i.e. state(1:sizeDot) follows time evolution by dotState rates
@ -57,7 +58,7 @@ module prec
RKCK45dotState RKCK45dotState
end type end type
type, extends(tState), public :: tPlasticState type, extends(tState) :: tPlasticState
logical :: & logical :: &
nonlocal = .false. nonlocal = .false.
real(pReal), pointer, dimension(:,:) :: & real(pReal), pointer, dimension(:,:) :: &
@ -65,22 +66,22 @@ module prec
accumulatedSlip !< accumulated plastic slip accumulatedSlip !< accumulated plastic slip
end type end type
type, public :: tSourceState type :: tSourceState
type(tState), dimension(:), allocatable :: p !< tState for each active source mechanism in a phase type(tState), dimension(:), allocatable :: p !< tState for each active source mechanism in a phase
end type end type
type, public :: tHomogMapping type :: tHomogMapping
integer, pointer, dimension(:,:) :: p integer, pointer, dimension(:,:) :: p
end type end type
real(pReal), private, parameter :: PREAL_EPSILON = epsilon(0.0_pReal) !< minimum positive number such that 1.0 + EPSILON /= 1.0. real(pReal), private, parameter :: PREAL_EPSILON = epsilon(0.0_pReal) !< minimum positive number such that 1.0 + EPSILON /= 1.0.
real(pReal), private, parameter :: PREAL_MIN = tiny(0.0_pReal) !< smallest normalized floating point number real(pReal), private, parameter :: PREAL_MIN = tiny(0.0_pReal) !< smallest normalized floating point number
integer, dimension(0), parameter, public :: & integer, dimension(0), parameter :: &
emptyIntArray = [integer::] emptyIntArray = [integer::]
real(pReal), dimension(0), parameter, public :: & real(pReal), dimension(0), parameter :: &
emptyRealArray = [real(pReal)::] emptyRealArray = [real(pReal)::]
character(len=pStringLen), dimension(0), parameter, public :: & character(len=pStringLen), dimension(0), parameter :: &
emptyStringArray = [character(len=pStringLen)::] emptyStringArray = [character(len=pStringLen)::]
private :: & private :: &

View File

@ -10,7 +10,7 @@ module quaternions
use IO use IO
implicit none implicit none
public private
real(pReal), parameter, public :: P = -1.0_pReal !< parameter for orientation conversion. real(pReal), parameter, public :: P = -1.0_pReal !< parameter for orientation conversion.
@ -95,9 +95,13 @@ module quaternions
interface aimag interface aimag
module procedure aimag__ module procedure aimag__
end interface aimag end interface aimag
private :: & public :: &
unitTest quaternions_init, &
assignment(=), &
conjg, aimag, &
log, exp, &
real
contains contains
@ -511,6 +515,7 @@ subroutine unitTest
q_2 = conjg(q_2) - inverse(q_2) q_2 = conjg(q_2) - inverse(q_2)
if(any(dNeq0(q_2%asArray(),1.0e-15_pReal))) call IO_error(0,ext_msg='inverse/conjg') if(any(dNeq0(q_2%asArray(),1.0e-15_pReal))) call IO_error(0,ext_msg='inverse/conjg')
endif endif
if(dNeq(dot_product(qu,qu),dot_product(q,q))) call IO_error(0,ext_msg='dot_product')
#if !(defined(__GFORTRAN__) && __GNUC__ < 9) #if !(defined(__GFORTRAN__) && __GNUC__ < 9)
if (norm2(aimag(q)) > 0.0_pReal) then if (norm2(aimag(q)) > 0.0_pReal) then

View File

@ -9,8 +9,8 @@ module source_damage_anisoBrittle
use debug use debug
use IO use IO
use math use math
use material
use discretization use discretization
use material
use config use config
use lattice use lattice
use results use results
@ -21,17 +21,8 @@ module source_damage_anisoBrittle
integer, dimension(:), allocatable :: & integer, dimension(:), allocatable :: &
source_damage_anisoBrittle_offset, & !< which source is my current source mechanism? source_damage_anisoBrittle_offset, & !< which source is my current source mechanism?
source_damage_anisoBrittle_instance !< instance of source mechanism source_damage_anisoBrittle_instance !< instance of source mechanism
integer, dimension(:,:), allocatable :: &
source_damage_anisoBrittle_Ncleavage !< number of cleavage systems per family
enum, bind(c) type :: tParameters !< container type for internal constitutive parameters
enumerator :: undefined_ID, &
damage_drivingforce_ID
end enum
type :: tParameters !< container type for internal constitutive parameters
real(pReal) :: & real(pReal) :: &
aTol, & aTol, &
sdot_0, & sdot_0, &
@ -45,8 +36,8 @@ module source_damage_anisoBrittle
totalNcleavage totalNcleavage
integer, dimension(:), allocatable :: & integer, dimension(:), allocatable :: &
Ncleavage Ncleavage
integer(kind(undefined_ID)), allocatable, dimension(:) :: & character(len=pStringLen), allocatable, dimension(:) :: &
outputID !< ID of each post result output output
end type tParameters end type tParameters
type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance)
@ -67,101 +58,69 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_damage_anisoBrittle_init subroutine source_damage_anisoBrittle_init
integer :: Ninstance,phase,instance,source,sourceOffset integer :: Ninstance,sourceOffset,NofMyPhase,p
integer :: NofMyPhase,p ,i character(len=pStringLen) :: extmsg = ''
integer(kind(undefined_ID)) :: &
outputID
character(len=pStringLen) :: & write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ANISOBRITTLE_LABEL//' init -+>>>'; flush(6)
extmsg = ''
character(len=pStringLen), dimension(:), allocatable :: &
outputs
write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ANISOBRITTLE_LABEL//' init -+>>>'; flush(6) Ninstance = count(phase_source == SOURCE_DAMAGE_ANISOBRITTLE_ID)
Ninstance = count(phase_source == SOURCE_damage_anisoBrittle_ID)
if (Ninstance == 0) return
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
allocate(source_damage_anisoBrittle_offset(material_Nphase), source=0)
allocate(source_damage_anisoBrittle_instance(material_Nphase), source=0)
do phase = 1, material_Nphase
source_damage_anisoBrittle_instance(phase) = count(phase_source(:,1:phase) == source_damage_anisoBrittle_ID)
do source = 1, phase_Nsources(phase)
if (phase_source(source,phase) == source_damage_anisoBrittle_ID) &
source_damage_anisoBrittle_offset(phase) = source
enddo
enddo
allocate(source_damage_anisoBrittle_Ncleavage(lattice_maxNcleavageFamily,Ninstance), source=0)
allocate(source_damage_anisoBrittle_offset (size(config_phase)), source=0)
allocate(source_damage_anisoBrittle_instance(size(config_phase)), source=0)
allocate(param(Ninstance)) allocate(param(Ninstance))
do p=1, size(config_phase) do p = 1, size(config_phase)
source_damage_anisoBrittle_instance(p) = count(phase_source(:,1:p) == SOURCE_DAMAGE_ANISOBRITTLE_ID)
do sourceOffset = 1, phase_Nsources(p)
if (phase_source(sourceOffset,p) == SOURCE_DAMAGE_ANISOBRITTLE_ID) then
source_damage_anisoBrittle_offset(p) = sourceOffset
exit
endif
enddo
if (all(phase_source(:,p) /= SOURCE_DAMAGE_ANISOBRITTLE_ID)) cycle if (all(phase_source(:,p) /= SOURCE_DAMAGE_ANISOBRITTLE_ID)) cycle
associate(prm => param(source_damage_anisoBrittle_instance(p)), & associate(prm => param(source_damage_anisoBrittle_instance(p)), &
config => config_phase(p)) config => config_phase(p))
prm%aTol = config%getFloat('anisobrittle_atol',defaultVal = 1.0e-3_pReal)
prm%Ncleavage = config%getInts('ncleavage',defaultVal=emptyIntArray)
prm%totalNcleavage = sum(prm%Ncleavage)
prm%aTol = config%getFloat('anisobrittle_atol',defaultVal = 1.0e-3_pReal)
prm%N = config%getFloat('anisobrittle_ratesensitivity') prm%N = config%getFloat('anisobrittle_ratesensitivity')
prm%sdot_0 = config%getFloat('anisobrittle_sdot0') prm%sdot_0 = config%getFloat('anisobrittle_sdot0')
prm%critDisp = config%getFloats('anisobrittle_criticaldisplacement',requiredSize=size(prm%Ncleavage))
prm%critLoad = config%getFloats('anisobrittle_criticalload', requiredSize=size(prm%Ncleavage))
prm%cleavage_systems = lattice_SchmidMatrix_cleavage(prm%Ncleavage,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal))
! expand: family => system
prm%critDisp = math_expand(prm%critDisp, prm%Ncleavage)
prm%critLoad = math_expand(prm%critLoad, prm%Ncleavage)
! sanity checks ! sanity checks
if (prm%aTol < 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_atol' if (prm%aTol < 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_atol'
if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_n'
if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_ratesensitivity' if (prm%sdot_0 <= 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_sdot0'
if (prm%sdot_0 <= 0.0_pReal) extmsg = trim(extmsg)//' anisobrittle_sdot0' if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_critLoad'
if (any(prm%critDisp < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_critDisp'
prm%Ncleavage = config%getInts('ncleavage',defaultVal=emptyIntArray)
prm%critDisp = config%getFloats('anisobrittle_criticaldisplacement',requiredSize=size(prm%Ncleavage))
prm%critLoad = config%getFloats('anisobrittle_criticalload', requiredSize=size(prm%Ncleavage))
prm%cleavage_systems = lattice_SchmidMatrix_cleavage (prm%Ncleavage,config%getString('lattice_structure'),&
config%getFloat('c/a',defaultVal=0.0_pReal))
! expand: family => system
prm%critDisp = math_expand(prm%critDisp, prm%Ncleavage)
prm%critLoad = math_expand(prm%critLoad, prm%Ncleavage)
if (any(prm%critLoad < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_criticalload'
if (any(prm%critDisp < 0.0_pReal)) extmsg = trim(extmsg)//' anisobrittle_criticaldisplacement'
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range ! exit if any parameter is out of range
if (extmsg /= '') & if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ANISOBRITTLE_LABEL//')')
call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ANISOBRITTLE_LABEL//')')
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! output pararameters ! output pararameters
outputs = config%getStrings('(output)',defaultVal=emptyStringArray) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
allocate(prm%outputID(0))
do i=1, size(outputs)
outputID = undefined_ID
select case(outputs(i))
case ('anisobrittle_drivingforce')
prm%outputID = [prm%outputID, damage_drivingforce_ID]
end select NofMyPhase = count(material_phaseAt==p) * discretization_nIP
call material_allocateSourceState(p,sourceOffset,NofMyPhase,1,1,0)
enddo sourceState(p)%p(sourceOffset)%aTolState=prm%aTol
end associate end associate
phase = p
NofMyPhase=count(material_phaseAt==phase) * discretization_nIP
instance = source_damage_anisoBrittle_instance(phase)
sourceOffset = source_damage_anisoBrittle_offset(phase)
call material_allocateSourceState(phase,sourceOffset,NofMyPhase,1,1,0)
sourceState(phase)%p(sourceOffset)%aTolState=param(instance)%aTol
source_damage_anisoBrittle_Ncleavage(1:size(param(instance)%Ncleavage),instance) = param(instance)%Ncleavage
enddo enddo
end subroutine source_damage_anisoBrittle_init end subroutine source_damage_anisoBrittle_init
@ -178,49 +137,42 @@ subroutine source_damage_anisoBrittle_dotState(S, ipc, ip, el)
el !< element el !< element
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
S S
integer :: & integer :: &
phase, & phase, &
constituent, & constituent, &
instance, &
sourceOffset, & sourceOffset, &
damageOffset, & damageOffset, &
homog, & homog, &
f, i, index_myFamily, index i
real(pReal) :: & real(pReal) :: &
traction_d, traction_t, traction_n, traction_crit traction_d, traction_t, traction_n, traction_crit
phase = material_phaseAt(ipc,el) phase = material_phaseAt(ipc,el)
constituent = material_phasememberAt(ipc,ip,el) constituent = material_phasememberAt(ipc,ip,el)
instance = source_damage_anisoBrittle_instance(phase)
sourceOffset = source_damage_anisoBrittle_offset(phase) sourceOffset = source_damage_anisoBrittle_offset(phase)
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
damageOffset = damageMapping(homog)%p(ip,el) damageOffset = damageMapping(homog)%p(ip,el)
associate(prm => param(source_damage_anisoBrittle_instance(phase)))
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = 0.0_pReal sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = 0.0_pReal
do i = 1, prm%totalNcleavage
index = 1
do f = 1,lattice_maxNcleavageFamily
index_myFamily = sum(lattice_NcleavageSystem(1:f-1,phase)) ! at which index starts my family
do i = 1,source_damage_anisoBrittle_Ncleavage(f,instance) ! process each (active) cleavage system in family
traction_d = math_mul33xx33(S,lattice_Scleavage(1:3,1:3,1,index_myFamily+i,phase)) traction_d = math_mul33xx33(S,prm%cleavage_systems(1:3,1:3,1,i))
traction_t = math_mul33xx33(S,lattice_Scleavage(1:3,1:3,2,index_myFamily+i,phase)) traction_t = math_mul33xx33(S,prm%cleavage_systems(1:3,1:3,2,i))
traction_n = math_mul33xx33(S,lattice_Scleavage(1:3,1:3,3,index_myFamily+i,phase)) traction_n = math_mul33xx33(S,prm%cleavage_systems(1:3,1:3,3,i))
traction_crit = param(instance)%critLoad(index)* &
damage(homog)%p(damageOffset)*damage(homog)%p(damageOffset)
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = & traction_crit = prm%critLoad(i)*damage(homog)%p(damageOffset)**2.0_pReal
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) + &
param(instance)%sdot_0* & sourceState(phase)%p(sourceOffset)%dotState(1,constituent) &
((max(0.0_pReal, abs(traction_d) - traction_crit)/traction_crit)**param(instance)%N + & = sourceState(phase)%p(sourceOffset)%dotState(1,constituent) &
(max(0.0_pReal, abs(traction_t) - traction_crit)/traction_crit)**param(instance)%N + & + prm%sdot_0 / prm%critDisp(i) &
(max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**param(instance)%N)/ & * ((max(0.0_pReal, abs(traction_d) - traction_crit)/traction_crit)**prm%N + &
param(instance)%critDisp(index) (max(0.0_pReal, abs(traction_t) - traction_crit)/traction_crit)**prm%N + &
(max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**prm%N)
index = index + 1
enddo
enddo enddo
end associate
end subroutine source_damage_anisoBrittle_dotState end subroutine source_damage_anisoBrittle_dotState
@ -238,16 +190,17 @@ subroutine source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalph
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
integer :: & integer :: &
sourceOffset sourceOffset
sourceOffset = source_damage_anisoBrittle_offset(phase) sourceOffset = source_damage_anisoBrittle_offset(phase)
localphiDot = 1.0_pReal &
- sourceState(phase)%p(sourceOffset)%state(1,constituent)*phi
dLocalphiDot_dPhi = -sourceState(phase)%p(sourceOffset)%state(1,constituent) dLocalphiDot_dPhi = -sourceState(phase)%p(sourceOffset)%state(1,constituent)
localphiDot = 1.0_pReal &
+ dLocalphiDot_dPhi*phi
end subroutine source_damage_anisoBrittle_getRateAndItsTangent end subroutine source_damage_anisoBrittle_getRateAndItsTangent
@ -256,21 +209,20 @@ end subroutine source_damage_anisoBrittle_getRateAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_damage_anisoBrittle_results(phase,group) subroutine source_damage_anisoBrittle_results(phase,group)
integer, intent(in) :: phase integer, intent(in) :: phase
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: sourceOffset, o, instance
instance = source_damage_anisoBrittle_instance(phase)
sourceOffset = source_damage_anisoBrittle_offset(phase)
associate(prm => param(instance), stt => sourceState(phase)%p(sourceOffset)%state) integer :: o
outputsLoop: do o = 1,size(prm%outputID)
select case(prm%outputID(o)) associate(prm => param(source_damage_anisoBrittle_instance(phase)), &
case (damage_drivingforce_ID) stt => sourceState(phase)%p(source_damage_anisoBrittle_offset(phase))%state)
call results_writeDataset(group,stt,'tbd','driving force','tbd') outputsLoop: do o = 1,size(prm%output)
end select select case(trim(prm%output(o)))
enddo outputsLoop case ('anisobrittle_drivingforce')
end associate call results_writeDataset(group,stt,'tbd','driving force','tbd')
end select
enddo outputsLoop
end associate
end subroutine source_damage_anisoBrittle_results end subroutine source_damage_anisoBrittle_results

View File

@ -13,21 +13,15 @@ module source_damage_anisoDuctile
use material use material
use config use config
use results use results
implicit none implicit none
private private
integer, dimension(:), allocatable :: & integer, dimension(:), allocatable :: &
source_damage_anisoDuctile_offset, & !< which source is my current damage mechanism? source_damage_anisoDuctile_offset, & !< which source is my current damage mechanism?
source_damage_anisoDuctile_instance !< instance of damage source mechanism source_damage_anisoDuctile_instance !< instance of damage source mechanism
enum, bind(c) type, private :: tParameters !< container type for internal constitutive parameters
enumerator :: undefined_ID, &
damage_drivingforce_ID
end enum
type, private :: tParameters !< container type for internal constitutive parameters
real(pReal) :: & real(pReal) :: &
aTol, & aTol, &
N N
@ -37,13 +31,13 @@ module source_damage_anisoDuctile
totalNslip totalNslip
integer, dimension(:), allocatable :: & integer, dimension(:), allocatable :: &
Nslip Nslip
integer(kind(undefined_ID)), allocatable, dimension(:) :: & character(len=pStringLen), allocatable, dimension(:) :: &
outputID output
end type tParameters end type tParameters
type(tParameters), dimension(:), allocatable, private :: param !< containers of constitutive parameters (len Ninstance) type(tParameters), dimension(:), allocatable, private :: param !< containers of constitutive parameters (len Ninstance)
public :: & public :: &
source_damage_anisoDuctile_init, & source_damage_anisoDuctile_init, &
source_damage_anisoDuctile_dotState, & source_damage_anisoDuctile_dotState, &
@ -58,93 +52,64 @@ contains
!> @details reads in material parameters, allocates arrays, and does sanity checks !> @details reads in material parameters, allocates arrays, and does sanity checks
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_damage_anisoDuctile_init subroutine source_damage_anisoDuctile_init
integer :: Ninstance,phase,instance,source,sourceOffset integer :: Ninstance,sourceOffset,NofMyPhase,p
integer :: NofMyPhase,p ,i character(len=pStringLen) :: extmsg = ''
integer(kind(undefined_ID)) :: & write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ANISODUCTILE_LABEL//' init -+>>>'; flush(6)
outputID
Ninstance = count(phase_source == SOURCE_DAMAGE_ANISODUCTILE_ID)
character(len=pStringLen) :: &
extmsg = ''
character(len=pStringLen), dimension(:), allocatable :: &
outputs
write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ANISODUCTILE_LABEL//' init -+>>>'; flush(6)
Ninstance = count(phase_source == SOURCE_damage_anisoDuctile_ID)
if (Ninstance == 0) return
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
allocate(source_damage_anisoDuctile_offset(size(config_phase)), source=0) allocate(source_damage_anisoDuctile_offset (size(config_phase)), source=0)
allocate(source_damage_anisoDuctile_instance(size(config_phase)), source=0) allocate(source_damage_anisoDuctile_instance(size(config_phase)), source=0)
do phase = 1, size(config_phase)
source_damage_anisoDuctile_instance(phase) = count(phase_source(:,1:phase) == source_damage_anisoDuctile_ID)
do source = 1, phase_Nsources(phase)
if (phase_source(source,phase) == source_damage_anisoDuctile_ID) &
source_damage_anisoDuctile_offset(phase) = source
enddo
enddo
allocate(param(Ninstance)) allocate(param(Ninstance))
do p=1, size(config_phase) do p = 1, size(config_phase)
source_damage_anisoDuctile_instance(p) = count(phase_source(:,1:p) == SOURCE_DAMAGE_ANISODUCTILE_ID)
do sourceOffset = 1, phase_Nsources(p)
if (phase_source(sourceOffset,p) == SOURCE_DAMAGE_ANISODUCTILE_ID) then
source_damage_anisoDuctile_offset(p) = sourceOffset
exit
endif
enddo
if (all(phase_source(:,p) /= SOURCE_DAMAGE_ANISODUCTILE_ID)) cycle if (all(phase_source(:,p) /= SOURCE_DAMAGE_ANISODUCTILE_ID)) cycle
associate(prm => param(source_damage_anisoDuctile_instance(p)), & associate(prm => param(source_damage_anisoDuctile_instance(p)), &
config => config_phase(p)) config => config_phase(p))
prm%aTol = config%getFloat('anisoductile_atol',defaultVal = 1.0e-3_pReal) prm%Nslip = config%getInts('nslip',defaultVal=emptyIntArray)
prm%N = config%getFloat('anisoductile_ratesensitivity')
prm%totalNslip = sum(prm%Nslip) prm%totalNslip = sum(prm%Nslip)
! sanity checks
if (prm%aTol < 0.0_pReal) extmsg = trim(extmsg)//' anisoductile_atol' prm%aTol = config%getFloat('anisoductile_atol',defaultVal = 1.0e-3_pReal)
prm%N = config%getFloat('anisoductile_ratesensitivity')
if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' anisoductile_ratesensitivity'
prm%Nslip = config%getInts('nslip',defaultVal=emptyIntArray)
prm%critPlasticStrain = config%getFloats('anisoductile_criticalplasticstrain',requiredSize=size(prm%Nslip)) prm%critPlasticStrain = config%getFloats('anisoductile_criticalplasticstrain',requiredSize=size(prm%Nslip))
! expand: family => system ! expand: family => system
prm%critPlasticStrain = math_expand(prm%critPlasticStrain, prm%Nslip) prm%critPlasticStrain = math_expand(prm%critPlasticStrain, prm%Nslip)
if (any(prm%critPlasticStrain < 0.0_pReal)) extmsg = trim(extmsg)//' anisoductile_criticalplasticstrain' ! sanity checks
if (prm%aTol < 0.0_pReal) extmsg = trim(extmsg)//' anisoductile_atol'
if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' anisoductile_ratesensitivity'
if (any(prm%critPlasticStrain < 0.0_pReal)) extmsg = trim(extmsg)//' anisoductile_criticalplasticstrain'
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range ! exit if any parameter is out of range
if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ANISODUCTILE_LABEL//')') if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ANISODUCTILE_LABEL//')')
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! output pararameters ! output pararameters
outputs = config%getStrings('(output)',defaultVal=emptyStringArray) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
allocate(prm%outputID(0))
do i=1, size(outputs) NofMyPhase=count(material_phaseAt==p) * discretization_nIP
outputID = undefined_ID call material_allocateSourceState(p,sourceOffset,NofMyPhase,1,1,0)
select case(outputs(i)) sourceState(p)%p(sourceOffset)%aTolState=prm%aTol
case ('anisoductile_drivingforce')
prm%outputID = [prm%outputID, damage_drivingforce_ID]
end select
enddo
end associate end associate
phase = p
NofMyPhase=count(material_phaseAt==phase) * discretization_nIP
instance = source_damage_anisoDuctile_instance(phase)
sourceOffset = source_damage_anisoDuctile_offset(phase)
call material_allocateSourceState(phase,sourceOffset,NofMyPhase,1,1,0)
sourceState(phase)%p(sourceOffset)%aTolState=param(instance)%aTol
enddo enddo
end subroutine source_damage_anisoDuctile_init end subroutine source_damage_anisoDuctile_init
@ -157,29 +122,29 @@ subroutine source_damage_anisoDuctile_dotState(ipc, ip, el)
ipc, & !< component-ID of integration point ipc, & !< component-ID of integration point
ip, & !< integration point ip, & !< integration point
el !< element el !< element
integer :: & integer :: &
phase, & phase, &
constituent, & constituent, &
sourceOffset, & sourceOffset, &
homog, damageOffset, & damageOffset, &
instance, & homog, &
i i
phase = material_phaseAt(ipc,el) phase = material_phaseAt(ipc,el)
constituent = material_phasememberAt(ipc,ip,el) constituent = material_phasememberAt(ipc,ip,el)
instance = source_damage_anisoDuctile_instance(phase)
sourceOffset = source_damage_anisoDuctile_offset(phase) sourceOffset = source_damage_anisoDuctile_offset(phase)
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
damageOffset = damageMapping(homog)%p(ip,el) damageOffset = damageMapping(homog)%p(ip,el)
associate(prm => param(source_damage_anisoDuctile_instance(phase)))
do i = 1, param(instance)%totalNslip do i = 1, prm%totalNslip
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = & sourceState(phase)%p(sourceOffset)%dotState(1,constituent) &
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) + & = sourceState(phase)%p(sourceOffset)%dotState(1,constituent) &
plasticState(phase)%slipRate(i,constituent)/ & + plasticState(phase)%slipRate(i,constituent)/(damage(homog)%p(damageOffset)**prm%N)/prm%critPlasticStrain(i)
((damage(homog)%p(damageOffset))**param(instance)%N)/param(instance)%critPlasticStrain(i)
enddo enddo
end associate
end subroutine source_damage_anisoDuctile_dotState end subroutine source_damage_anisoDuctile_dotState
@ -196,16 +161,17 @@ subroutine source_damage_anisoDuctile_getRateAndItsTangent(localphiDot, dLocalph
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
integer :: & integer :: &
sourceOffset sourceOffset
sourceOffset = source_damage_anisoDuctile_offset(phase) sourceOffset = source_damage_anisoDuctile_offset(phase)
localphiDot = 1.0_pReal &
- sourceState(phase)%p(sourceOffset)%state(1,constituent) * phi
dLocalphiDot_dPhi = -sourceState(phase)%p(sourceOffset)%state(1,constituent) dLocalphiDot_dPhi = -sourceState(phase)%p(sourceOffset)%state(1,constituent)
localphiDot = 1.0_pReal &
+ dLocalphiDot_dPhi*phi
end subroutine source_damage_anisoDuctile_getRateAndItsTangent end subroutine source_damage_anisoDuctile_getRateAndItsTangent
@ -214,21 +180,20 @@ end subroutine source_damage_anisoDuctile_getRateAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_damage_anisoDuctile_results(phase,group) subroutine source_damage_anisoDuctile_results(phase,group)
integer, intent(in) :: phase integer, intent(in) :: phase
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: sourceOffset, o, instance
instance = source_damage_anisoDuctile_instance(phase)
sourceOffset = source_damage_anisoDuctile_offset(phase)
associate(prm => param(instance), stt => sourceState(phase)%p(sourceOffset)%state) integer :: o
outputsLoop: do o = 1,size(prm%outputID)
select case(prm%outputID(o)) associate(prm => param(source_damage_anisoDuctile_instance(phase)), &
case (damage_drivingforce_ID) stt => sourceState(phase)%p(source_damage_anisoDuctile_offset(phase))%state)
call results_writeDataset(group,stt,'tbd','driving force','tbd') outputsLoop: do o = 1,size(prm%output)
end select select case(trim(prm%output(o)))
enddo outputsLoop case ('anisoductile_drivingforce')
end associate call results_writeDataset(group,stt,'tbd','driving force','tbd')
end select
enddo outputsLoop
end associate
end subroutine source_damage_anisoDuctile_results end subroutine source_damage_anisoDuctile_results

View File

@ -16,34 +16,28 @@ module source_damage_isoBrittle
implicit none implicit none
private private
integer, dimension(:), allocatable :: & integer, dimension(:), allocatable :: &
source_damage_isoBrittle_offset, & source_damage_isoBrittle_offset, &
source_damage_isoBrittle_instance source_damage_isoBrittle_instance
enum, bind(c)
enumerator :: &
undefined_ID, &
damage_drivingforce_ID
end enum
type, private :: tParameters !< container type for internal constitutive parameters type, private :: tParameters !< container type for internal constitutive parameters
real(pReal) :: & real(pReal) :: &
critStrainEnergy, & critStrainEnergy, &
N, & N, &
aTol aTol
integer(kind(undefined_ID)), allocatable, dimension(:) :: & character(len=pStringLen), allocatable, dimension(:) :: &
outputID output
end type tParameters end type tParameters
type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance)
public :: & public :: &
source_damage_isoBrittle_init, & source_damage_isoBrittle_init, &
source_damage_isoBrittle_deltaState, & source_damage_isoBrittle_deltaState, &
source_damage_isoBrittle_getRateAndItsTangent, & source_damage_isoBrittle_getRateAndItsTangent, &
source_damage_isoBrittle_Results source_damage_isoBrittle_results
contains contains
@ -54,52 +48,41 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_damage_isoBrittle_init subroutine source_damage_isoBrittle_init
integer :: Ninstance,phase,instance,source,sourceOffset integer :: Ninstance,sourceOffset,NofMyPhase,p
integer :: NofMyPhase,p,i character(len=pStringLen) :: extmsg = ''
integer(kind(undefined_ID)) :: &
outputID write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ISOBRITTLE_LABEL//' init -+>>>'; flush(6)
character(len=pStringLen) :: & Ninstance = count(phase_source == SOURCE_DAMAGE_ISOBRITTLE_ID)
extmsg = ''
character(len=pStringLen), dimension(:), allocatable :: &
outputs
write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ISOBRITTLE_LABEL//' init -+>>>'; flush(6)
Ninstance = count(phase_source == SOURCE_damage_isoBrittle_ID)
if (Ninstance == 0) return
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
allocate(source_damage_isoBrittle_offset(material_Nphase), source=0) allocate(source_damage_isoBrittle_offset (size(config_phase)), source=0)
allocate(source_damage_isoBrittle_instance(material_Nphase), source=0) allocate(source_damage_isoBrittle_instance(size(config_phase)), source=0)
do phase = 1, material_Nphase
source_damage_isoBrittle_instance(phase) = count(phase_source(:,1:phase) == source_damage_isoBrittle_ID)
do source = 1, phase_Nsources(phase)
if (phase_source(source,phase) == source_damage_isoBrittle_ID) &
source_damage_isoBrittle_offset(phase) = source
enddo
enddo
allocate(param(Ninstance)) allocate(param(Ninstance))
do p=1, size(config_phase) do p = 1, size(config_phase)
source_damage_isoBrittle_instance(p) = count(phase_source(:,1:p) == SOURCE_DAMAGE_ISOBRITTLE_ID)
do sourceOffset = 1, phase_Nsources(p)
if (phase_source(sourceOffset,p) == SOURCE_DAMAGE_ISOBRITTLE_ID) then
source_damage_isoBrittle_offset(p) = sourceOffset
exit
endif
enddo
if (all(phase_source(:,p) /= SOURCE_DAMAGE_ISOBRITTLE_ID)) cycle if (all(phase_source(:,p) /= SOURCE_DAMAGE_ISOBRITTLE_ID)) cycle
associate(prm => param(source_damage_isoBrittle_instance(p)), & associate(prm => param(source_damage_isoBrittle_instance(p)), &
config => config_phase(p)) config => config_phase(p))
prm%aTol = config%getFloat('isobrittle_atol',defaultVal = 1.0e-3_pReal) prm%aTol = config%getFloat('isobrittle_atol',defaultVal = 1.0e-3_pReal)
prm%N = config%getFloat('isobrittle_n') prm%N = config%getFloat('isobrittle_n')
prm%critStrainEnergy = config%getFloat('isobrittle_criticalstrainenergy') prm%critStrainEnergy = config%getFloat('isobrittle_criticalstrainenergy')
! sanity checks ! sanity checks
if (prm%aTol < 0.0_pReal) extmsg = trim(extmsg)//' isobrittle_atol' if (prm%aTol < 0.0_pReal) extmsg = trim(extmsg)//' isobrittle_atol'
if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' isobrittle_n'
if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' isobrittle_n' if (prm%critStrainEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' isobrittle_criticalstrainenergy'
if (prm%critStrainEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' isobrittle_criticalstrainenergy'
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range ! exit if any parameter is out of range
if (extmsg /= '') & if (extmsg /= '') &
@ -107,34 +90,18 @@ subroutine source_damage_isoBrittle_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! output pararameters ! output pararameters
outputs = config%getStrings('(output)',defaultVal=emptyStringArray) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
allocate(prm%outputID(0))
do i=1, size(outputs)
outputID = undefined_ID
select case(outputs(i))
case ('isobrittle_drivingforce')
prm%outputID = [prm%outputID, damage_drivingforce_ID]
end select
enddo NofMyPhase = count(material_phaseAt==p) * discretization_nIP
call material_allocateSourceState(p,sourceOffset,NofMyPhase,1,1,1)
sourceState(p)%p(sourceOffset)%aTolState=prm%aTol
end associate end associate
phase = p
NofMyPhase = count(material_phaseAt==phase) * discretization_nIP
instance = source_damage_isoBrittle_instance(phase)
sourceOffset = source_damage_isoBrittle_offset(phase)
call material_allocateSourceState(phase,sourceOffset,NofMyPhase,1,1,1)
sourceState(phase)%p(sourceOffset)%aTolState=param(instance)%aTol
enddo enddo
end subroutine source_damage_isoBrittle_init end subroutine source_damage_isoBrittle_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates derived quantities from state !> @brief calculates derived quantities from state
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -148,24 +115,26 @@ subroutine source_damage_isoBrittle_deltaState(C, Fe, ipc, ip, el)
Fe Fe
real(pReal), intent(in), dimension(6,6) :: & real(pReal), intent(in), dimension(6,6) :: &
C C
integer :: & integer :: &
phase, constituent, instance, sourceOffset phase, &
constituent, &
sourceOffset
real(pReal), dimension(6) :: &
strain
real(pReal) :: & real(pReal) :: &
strain(6), &
strainenergy strainenergy
phase = material_phaseAt(ipc,el) !< phase ID at ipc,ip,el phase = material_phaseAt(ipc,el) !< phase ID at ipc,ip,el
constituent = material_phasememberAt(ipc,ip,el) !< state array offset for phase ID at ipc,ip,el constituent = material_phasememberAt(ipc,ip,el) !< state array offset for phase ID at ipc,ip,el
! ToDo: capability for multiple instances of SAME source within given phase. Needs Ninstance loop from here on!
instance = source_damage_isoBrittle_instance(phase) !< instance of damage_isoBrittle source
sourceOffset = source_damage_isoBrittle_offset(phase) sourceOffset = source_damage_isoBrittle_offset(phase)
strain = 0.5_pReal*math_sym33to6(matmul(transpose(Fe),Fe)-math_I3) strain = 0.5_pReal*math_sym33to6(matmul(transpose(Fe),Fe)-math_I3)
strainenergy = 2.0_pReal*sum(strain*matmul(C,strain))/param(instance)%critStrainEnergy associate(prm => param(source_damage_isoBrittle_instance(phase)))
strainenergy = 2.0_pReal*sum(strain*matmul(C,strain))/prm%critStrainEnergy
! ToDo: check strainenergy = 2.0_pReal*dot_product(strain,matmul(C,strain))/param(instance)%critStrainEnergy ! ToDo: check strainenergy = 2.0_pReal*dot_product(strain,matmul(C,strain))/param(instance)%critStrainEnergy
if (strainenergy > sourceState(phase)%p(sourceOffset)%subState0(1,constituent)) then if (strainenergy > sourceState(phase)%p(sourceOffset)%subState0(1,constituent)) then
sourceState(phase)%p(sourceOffset)%deltaState(1,constituent) = & sourceState(phase)%p(sourceOffset)%deltaState(1,constituent) = &
strainenergy - sourceState(phase)%p(sourceOffset)%state(1,constituent) strainenergy - sourceState(phase)%p(sourceOffset)%state(1,constituent)
@ -174,9 +143,11 @@ subroutine source_damage_isoBrittle_deltaState(C, Fe, ipc, ip, el)
sourceState(phase)%p(sourceOffset)%subState0(1,constituent) - & sourceState(phase)%p(sourceOffset)%subState0(1,constituent) - &
sourceState(phase)%p(sourceOffset)%state(1,constituent) sourceState(phase)%p(sourceOffset)%state(1,constituent)
endif endif
end associate
end subroutine source_damage_isoBrittle_deltaState end subroutine source_damage_isoBrittle_deltaState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns local part of nonlocal damage driving force !> @brief returns local part of nonlocal damage driving force
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
@ -190,18 +161,19 @@ subroutine source_damage_isoBrittle_getRateAndItsTangent(localphiDot, dLocalphiD
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
integer :: &
instance, sourceOffset
instance = source_damage_isoBrittle_instance(phase) integer :: &
sourceOffset
sourceOffset = source_damage_isoBrittle_offset(phase) sourceOffset = source_damage_isoBrittle_offset(phase)
localphiDot = (1.0_pReal - phi)**(param(instance)%N - 1.0_pReal) - & associate(prm => param(source_damage_isoBrittle_instance(phase)))
phi*sourceState(phase)%p(sourceOffset)%state(1,constituent) localphiDot = (1.0_pReal - phi)**(prm%n - 1.0_pReal) &
dLocalphiDot_dPhi = - (param(instance)%N - 1.0_pReal)* & - phi*sourceState(phase)%p(sourceOffset)%state(1,constituent)
(1.0_pReal - phi)**max(0.0_pReal,param(instance)%N - 2.0_pReal) & dLocalphiDot_dPhi = - (prm%n - 1.0_pReal)* (1.0_pReal - phi)**max(0.0_pReal,prm%n - 2.0_pReal) &
- sourceState(phase)%p(sourceOffset)%state(1,constituent) - sourceState(phase)%p(sourceOffset)%state(1,constituent)
end associate
end subroutine source_damage_isoBrittle_getRateAndItsTangent end subroutine source_damage_isoBrittle_getRateAndItsTangent
@ -210,21 +182,20 @@ end subroutine source_damage_isoBrittle_getRateAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_damage_isoBrittle_results(phase,group) subroutine source_damage_isoBrittle_results(phase,group)
integer, intent(in) :: phase integer, intent(in) :: phase
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: sourceOffset, o, instance
instance = source_damage_isoBrittle_instance(phase)
sourceOffset = source_damage_isoBrittle_offset(phase)
associate(prm => param(instance), stt => sourceState(phase)%p(sourceOffset)%state) integer :: o
outputsLoop: do o = 1,size(prm%outputID)
select case(prm%outputID(o)) associate(prm => param(source_damage_isoBrittle_instance(phase)), &
case (damage_drivingforce_ID) stt => sourceState(phase)%p(source_damage_isoBrittle_offset(phase))%state)
call results_writeDataset(group,stt,'tbd','driving force','tbd') outputsLoop: do o = 1,size(prm%output)
end select select case(trim(prm%output(o)))
enddo outputsLoop case ('isobrittle_drivingforce')
end associate call results_writeDataset(group,stt,'tbd','driving force','tbd')
end select
enddo outputsLoop
end associate
end subroutine source_damage_isoBrittle_results end subroutine source_damage_isoBrittle_results

View File

@ -5,42 +5,38 @@
!> @details to be done !> @details to be done
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
module source_damage_isoDuctile module source_damage_isoDuctile
use prec use prec
use debug use debug
use IO use IO
use discretization use discretization
use material use material
use config use config
use results use results
implicit none implicit none
private private
integer, dimension(:), allocatable :: &
source_damage_isoDuctile_offset, & !< which source is my current damage mechanism?
source_damage_isoDuctile_instance !< instance of damage source mechanism
enum, bind(c) integer, dimension(:), allocatable :: &
enumerator :: undefined_ID, & source_damage_isoDuctile_offset, & !< which source is my current damage mechanism?
damage_drivingforce_ID source_damage_isoDuctile_instance !< instance of damage source mechanism
end enum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ToDo
type, private :: tParameters !< container type for internal constitutive parameters type, private :: tParameters !< container type for internal constitutive parameters
real(pReal) :: & real(pReal) :: &
critPlasticStrain, & critPlasticStrain, &
N, & N, &
aTol aTol
integer(kind(undefined_ID)), allocatable, dimension(:) :: & character(len=pStringLen), allocatable, dimension(:) :: &
outputID output
end type tParameters end type tParameters
type(tParameters), dimension(:), allocatable, private :: param !< containers of constitutive parameters (len Ninstance) type(tParameters), dimension(:), allocatable, private :: param !< containers of constitutive parameters (len Ninstance)
public :: & public :: &
source_damage_isoDuctile_init, & source_damage_isoDuctile_init, &
source_damage_isoDuctile_dotState, & source_damage_isoDuctile_dotState, &
source_damage_isoDuctile_getRateAndItsTangent, & source_damage_isoDuctile_getRateAndItsTangent, &
source_damage_isoDuctile_Results source_damage_isoDuctile_Results
contains contains
@ -51,135 +47,115 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_damage_isoDuctile_init subroutine source_damage_isoDuctile_init
integer :: Ninstance,phase,instance,source,sourceOffset integer :: Ninstance,sourceOffset,NofMyPhase,p
integer :: NofMyPhase,p,i character(len=pStringLen) :: extmsg = ''
integer(kind(undefined_ID)) :: &
outputID
character(len=pStringLen) :: & write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ISODUCTILE_LABEL//' init -+>>>'; flush(6)
extmsg = ''
character(len=pStringLen), dimension(:), allocatable :: &
outputs
write(6,'(/,a)') ' <<<+- source_'//SOURCE_DAMAGE_ISODUCTILE_LABEL//' init -+>>>' Ninstance = count(phase_source == SOURCE_DAMAGE_ISODUCTILE_ID)
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
Ninstance = count(phase_source == SOURCE_damage_isoDuctile_ID) allocate(source_damage_isoDuctile_offset (size(config_phase)), source=0)
if (Ninstance == 0) return allocate(source_damage_isoDuctile_instance(size(config_phase)), source=0)
allocate(param(Ninstance))
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
allocate(source_damage_isoDuctile_offset(material_Nphase), source=0)
allocate(source_damage_isoDuctile_instance(material_Nphase), source=0)
do phase = 1, material_Nphase
source_damage_isoDuctile_instance(phase) = count(phase_source(:,1:phase) == source_damage_isoDuctile_ID)
do source = 1, phase_Nsources(phase)
if (phase_source(source,phase) == source_damage_isoDuctile_ID) &
source_damage_isoDuctile_offset(phase) = source
enddo
enddo
allocate(param(Ninstance)) do p = 1, size(config_phase)
source_damage_isoDuctile_instance(p) = count(phase_source(:,1:p) == SOURCE_DAMAGE_ISODUCTILE_ID)
do p=1, size(config_phase) do sourceOffset = 1, phase_Nsources(p)
if (all(phase_source(:,p) /= SOURCE_DAMAGE_ISODUCTILE_ID)) cycle if (phase_source(sourceOffset,p) == SOURCE_DAMAGE_ISODUCTILE_ID) then
associate(prm => param(source_damage_isoDuctile_instance(p)), & source_damage_isoDuctile_offset(p) = sourceOffset
config => config_phase(p)) exit
endif
prm%aTol = config%getFloat('isoductile_atol',defaultVal = 1.0e-3_pReal) enddo
if (all(phase_source(:,p) /= SOURCE_DAMAGE_ISODUCTILE_ID)) cycle
associate(prm => param(source_damage_isoDuctile_instance(p)), &
config => config_phase(p))
prm%aTol = config%getFloat('isoductile_atol',defaultVal = 1.0e-3_pReal)
prm%N = config%getFloat('isoductile_ratesensitivity')
prm%critPlasticStrain = config%getFloat('isoductile_criticalplasticstrain')
! sanity checks
if (prm%aTol < 0.0_pReal) extmsg = trim(extmsg)//' isoductile_atol'
if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' isoductile_ratesensitivity'
if (prm%critPlasticStrain <= 0.0_pReal) extmsg = trim(extmsg)//' isoductile_criticalplasticstrain'
prm%N = config%getFloat('isoductile_ratesensitivity')
prm%critPlasticStrain = config%getFloat('isoductile_criticalplasticstrain')
! sanity checks
if (prm%aTol < 0.0_pReal) extmsg = trim(extmsg)//' isoductile_atol'
if (prm%N <= 0.0_pReal) extmsg = trim(extmsg)//' isoductile_ratesensitivity'
if (prm%critPlasticStrain <= 0.0_pReal) extmsg = trim(extmsg)//' isoductile_criticalplasticstrain'
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! exit if any parameter is out of range ! exit if any parameter is out of range
if (extmsg /= '') & if (extmsg /= '') &
call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ISODUCTILE_LABEL//')') call IO_error(211,ext_msg=trim(extmsg)//'('//SOURCE_DAMAGE_ISODUCTILE_LABEL//')')
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! output pararameters ! output pararameters
outputs = config%getStrings('(output)',defaultVal=emptyStringArray) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
allocate(prm%outputID(0))
do i=1, size(outputs)
outputID = undefined_ID
select case(outputs(i))
case ('isoductile_drivingforce')
prm%outputID = [prm%outputID, damage_drivingforce_ID]
end select NofMyPhase=count(material_phaseAt==p) * discretization_nIP
call material_allocateSourceState(p,sourceOffset,NofMyPhase,1,1,0)
sourceState(p)%p(sourceOffset)%aTolState=prm%aTol
enddo end associate
enddo
end associate
phase = p
NofMyPhase=count(material_phaseAt==phase) * discretization_nIP
instance = source_damage_isoDuctile_instance(phase)
sourceOffset = source_damage_isoDuctile_offset(phase)
call material_allocateSourceState(phase,sourceOffset,NofMyPhase,1,1,0)
sourceState(phase)%p(sourceOffset)%aTolState=param(instance)%aTol
enddo
end subroutine source_damage_isoDuctile_init end subroutine source_damage_isoDuctile_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief calculates derived quantities from state !> @brief calculates derived quantities from state
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_damage_isoDuctile_dotState(ipc, ip, el) subroutine source_damage_isoDuctile_dotState(ipc, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
ipc, & !< component-ID of integration point ipc, & !< component-ID of integration point
ip, & !< integration point ip, & !< integration point
el !< element el !< element
integer :: &
phase, constituent, instance, homog, sourceOffset, damageOffset
phase = material_phaseAt(ipc,el) integer :: &
constituent = material_phasememberAt(ipc,ip,el) phase, &
instance = source_damage_isoDuctile_instance(phase) constituent, &
sourceOffset = source_damage_isoDuctile_offset(phase) sourceOffset, &
homog = material_homogenizationAt(el) damageOffset, &
damageOffset = damageMapping(homog)%p(ip,el) homog
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = & phase = material_phaseAt(ipc,el)
sum(plasticState(phase)%slipRate(:,constituent))/ & constituent = material_phasememberAt(ipc,ip,el)
((damage(homog)%p(damageOffset))**param(instance)%N)/ & sourceOffset = source_damage_isoDuctile_offset(phase)
param(instance)%critPlasticStrain homog = material_homogenizationAt(el)
damageOffset = damageMapping(homog)%p(ip,el)
associate(prm => param(source_damage_isoDuctile_instance(phase)))
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = &
sum(plasticState(phase)%slipRate(:,constituent))/(damage(homog)%p(damageOffset)**prm%N)/prm%critPlasticStrain
end associate
end subroutine source_damage_isoDuctile_dotState end subroutine source_damage_isoDuctile_dotState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns local part of nonlocal damage driving force !> @brief returns local part of nonlocal damage driving force
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_damage_isoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent) subroutine source_damage_isoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
integer, intent(in) :: & integer, intent(in) :: &
phase, & phase, &
constituent constituent
real(pReal), intent(in) :: & real(pReal), intent(in) :: &
phi phi
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
localphiDot, & localphiDot, &
dLocalphiDot_dPhi dLocalphiDot_dPhi
integer :: &
sourceOffset integer :: &
sourceOffset
sourceOffset = source_damage_isoDuctile_offset(phase)
dLocalphiDot_dPhi = -sourceState(phase)%p(sourceOffset)%state(1,constituent)
localphiDot = 1.0_pReal &
+ dLocalphiDot_dPhi*phi
sourceOffset = source_damage_isoDuctile_offset(phase)
localphiDot = 1.0_pReal &
- sourceState(phase)%p(sourceOffset)%state(1,constituent) * phi
dLocalphiDot_dPhi = -sourceState(phase)%p(sourceOffset)%state(1,constituent)
end subroutine source_damage_isoDuctile_getRateAndItsTangent end subroutine source_damage_isoDuctile_getRateAndItsTangent
@ -188,23 +164,21 @@ end subroutine source_damage_isoDuctile_getRateAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_damage_isoDuctile_results(phase,group) subroutine source_damage_isoDuctile_results(phase,group)
integer, intent(in) :: phase integer, intent(in) :: phase
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: sourceOffset, o, instance
instance = source_damage_isoDuctile_instance(phase)
sourceOffset = source_damage_isoDuctile_offset(phase)
associate(prm => param(instance), stt => sourceState(phase)%p(sourceOffset)%state) integer :: o
outputsLoop: do o = 1,size(prm%outputID)
select case(prm%outputID(o)) associate(prm => param(source_damage_isoDuctile_instance(phase)), &
case (damage_drivingforce_ID) stt => sourceState(phase)%p(source_damage_isoDuctile_offset(phase))%state)
call results_writeDataset(group,stt,'tbd','driving force','tbd') outputsLoop: do o = 1,size(prm%output)
end select select case(trim(prm%output(o)))
enddo outputsLoop case ('isoductile_drivingforce')
end associate call results_writeDataset(group,stt,'tbd','driving force','tbd')
end select
enddo outputsLoop
end associate
end subroutine source_damage_isoDuctile_results end subroutine source_damage_isoDuctile_results
end module source_damage_isoDuctile end module source_damage_isoDuctile

View File

@ -10,26 +10,26 @@ module source_thermal_dissipation
use discretization use discretization
use material use material
use config use config
implicit none implicit none
private private
integer, dimension(:), allocatable :: & integer, dimension(:), allocatable :: &
source_thermal_dissipation_offset, & !< which source is my current thermal dissipation mechanism? source_thermal_dissipation_offset, & !< which source is my current thermal dissipation mechanism?
source_thermal_dissipation_instance !< instance of thermal dissipation source mechanism source_thermal_dissipation_instance !< instance of thermal dissipation source mechanism
type :: tParameters !< container type for internal constitutive parameters type :: tParameters !< container type for internal constitutive parameters
real(pReal) :: & real(pReal) :: &
kappa kappa
end type tParameters end type tParameters
type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance)
public :: & public :: &
source_thermal_dissipation_init, & source_thermal_dissipation_init, &
source_thermal_dissipation_getRateAndItsTangent source_thermal_dissipation_getRateAndItsTangent
contains contains
@ -38,47 +38,47 @@ contains
!> @details reads in material parameters, allocates arrays, and does sanity checks !> @details reads in material parameters, allocates arrays, and does sanity checks
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_thermal_dissipation_init subroutine source_thermal_dissipation_init
integer :: Ninstance,instance,source,sourceOffset,NofMyPhase,p integer :: Ninstance,sourceOffset,NofMyPhase,p
write(6,'(/,a)') ' <<<+- source_'//SOURCE_thermal_dissipation_label//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- source_'//SOURCE_thermal_dissipation_label//' init -+>>>'; flush(6)
Ninstance = count(phase_source == SOURCE_THERMAL_DISSIPATION_ID)
Ninstance = count(phase_source == SOURCE_thermal_dissipation_ID)
if (Ninstance == 0) return
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
write(6,'(a16,1x,i5,/)') '# instances:',Ninstance write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
allocate(source_thermal_dissipation_offset(material_Nphase), source=0) allocate(source_thermal_dissipation_offset (size(config_phase)), source=0)
allocate(source_thermal_dissipation_instance(material_Nphase), source=0) allocate(source_thermal_dissipation_instance(size(config_phase)), source=0)
allocate(param(Ninstance)) allocate(param(Ninstance))
do p = 1, material_Nphase do p = 1, size(config_phase)
source_thermal_dissipation_instance(p) = count(phase_source(:,1:p) == SOURCE_thermal_dissipation_ID) source_thermal_dissipation_instance(p) = count(phase_source(:,1:p) == SOURCE_THERMAL_DISSIPATION_ID)
do source = 1, phase_Nsources(p) do sourceOffset = 1, phase_Nsources(p)
if (phase_source(source,p) == SOURCE_thermal_dissipation_ID) & if (phase_source(sourceOffset,p) == SOURCE_THERMAL_DISSIPATION_ID) then
source_thermal_dissipation_offset(p) = source source_thermal_dissipation_offset(p) = sourceOffset
enddo exit
enddo endif
enddo
do p=1, size(config_phase)
if (all(phase_source(:,p) /= SOURCE_THERMAL_DISSIPATION_ID)) cycle if (all(phase_source(:,p) /= SOURCE_THERMAL_DISSIPATION_ID)) cycle
instance = source_thermal_dissipation_instance(p) associate(prm => param(source_thermal_dissipation_instance(p)), &
param(instance)%kappa = config_phase(p)%getFloat('dissipation_coldworkcoeff') config => config_phase(p))
prm%kappa = config%getFloat('dissipation_coldworkcoeff')
NofMyPhase = count(material_phaseAt==p) * discretization_nIP NofMyPhase = count(material_phaseAt==p) * discretization_nIP
sourceOffset = source_thermal_dissipation_offset(p)
call material_allocateSourceState(p,sourceOffset,NofMyPhase,0,0,0) call material_allocateSourceState(p,sourceOffset,NofMyPhase,0,0,0)
end associate
enddo enddo
end subroutine source_thermal_dissipation_init end subroutine source_thermal_dissipation_init
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns dissipation rate !> @brief Ninstances dissipation rate
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_thermal_dissipation_getRateAndItsTangent(TDot, dTDOT_dT, Tstar, Lp, phase) subroutine source_thermal_dissipation_getRateAndItsTangent(TDot, dTDot_dT, Tstar, Lp, phase)
integer, intent(in) :: & integer, intent(in) :: &
phase phase
@ -86,17 +86,16 @@ subroutine source_thermal_dissipation_getRateAndItsTangent(TDot, dTDOT_dT, Tstar
Tstar Tstar
real(pReal), intent(in), dimension(3,3) :: & real(pReal), intent(in), dimension(3,3) :: &
Lp Lp
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
TDot, & TDot, &
dTDOT_dT dTDot_dT
integer :: &
instance associate(prm => param(source_thermal_dissipation_instance(phase)))
TDot = prm%kappa*sum(abs(Tstar*Lp))
instance = source_thermal_dissipation_instance(phase) dTDot_dT = 0.0_pReal
end associate
TDot = param(instance)%kappa*sum(abs(Tstar*Lp))
dTDOT_dT = 0.0_pReal
end subroutine source_thermal_dissipation_getRateAndItsTangent end subroutine source_thermal_dissipation_getRateAndItsTangent
end module source_thermal_dissipation end module source_thermal_dissipation

View File

@ -18,7 +18,7 @@ module source_thermal_externalheat
source_thermal_externalheat_offset, & !< which source is my current thermal dissipation mechanism? source_thermal_externalheat_offset, & !< which source is my current thermal dissipation mechanism?
source_thermal_externalheat_instance !< instance of thermal dissipation source mechanism source_thermal_externalheat_instance !< instance of thermal dissipation source mechanism
type :: tParameters !< container type for internal constitutive parameters type :: tParameters !< container type for internal constitutive parameters
real(pReal), dimension(:), allocatable :: & real(pReal), dimension(:), allocatable :: &
time, & time, &
heat_rate heat_rate
@ -42,44 +42,41 @@ contains
!> @details reads in material parameters, allocates arrays, and does sanity checks !> @details reads in material parameters, allocates arrays, and does sanity checks
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_thermal_externalheat_init subroutine source_thermal_externalheat_init
integer :: maxNinstance,instance,source,sourceOffset,NofMyPhase,p integer :: Ninstance,sourceOffset,NofMyPhase,p
write(6,'(/,a)') ' <<<+- source_'//SOURCE_thermal_externalheat_label//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- source_'//SOURCE_thermal_externalheat_label//' init -+>>>'; flush(6)
Ninstance = count(phase_source == SOURCE_thermal_externalheat_ID)
maxNinstance = count(phase_source == SOURCE_thermal_externalheat_ID)
if (maxNinstance == 0) return
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) &
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance write(6,'(a16,1x,i5,/)') '# instances:',Ninstance
allocate(source_thermal_externalheat_offset(material_Nphase), source=0) allocate(source_thermal_externalheat_offset (size(config_phase)), source=0)
allocate(source_thermal_externalheat_instance(material_Nphase), source=0) allocate(source_thermal_externalheat_instance(size(config_phase)), source=0)
allocate(param(Ninstance))
do p = 1, material_Nphase
do p = 1, size(config_phase)
source_thermal_externalheat_instance(p) = count(phase_source(:,1:p) == SOURCE_thermal_externalheat_ID) source_thermal_externalheat_instance(p) = count(phase_source(:,1:p) == SOURCE_thermal_externalheat_ID)
do source = 1, phase_Nsources(p) do sourceOffset = 1, phase_Nsources(p)
if (phase_source(source,p) == SOURCE_thermal_externalheat_ID) & if (phase_source(sourceOffset,p) == SOURCE_thermal_externalheat_ID) then
source_thermal_externalheat_offset(p) = source source_thermal_externalheat_offset(p) = sourceOffset
enddo exit
enddo endif
enddo
allocate(param(maxNinstance))
do p=1, size(config_phase)
if (all(phase_source(:,p) /= SOURCE_thermal_externalheat_ID)) cycle if (all(phase_source(:,p) /= SOURCE_thermal_externalheat_ID)) cycle
instance = source_thermal_externalheat_instance(p) associate(prm => param(source_thermal_externalheat_instance(p)), &
sourceOffset = source_thermal_externalheat_offset(p) config => config_phase(p))
prm%time = config%getFloats('externalheat_time')
prm%nIntervals = size(prm%time) - 1
prm%heat_rate = config%getFloats('externalheat_rate',requiredSize = size(prm%time))
NofMyPhase = count(material_phaseAt==p) * discretization_nIP NofMyPhase = count(material_phaseAt==p) * discretization_nIP
param(instance)%time = config_phase(p)%getFloats('externalheat_time')
param(instance)%nIntervals = size(param(instance)%time) - 1
param(instance)%heat_rate = config_phase(p)%getFloats('externalheat_rate',requiredSize = size(param(instance)%time))
call material_allocateSourceState(p,sourceOffset,NofMyPhase,1,1,0) call material_allocateSourceState(p,sourceOffset,NofMyPhase,1,1,0)
end associate
enddo enddo
end subroutine source_thermal_externalheat_init end subroutine source_thermal_externalheat_init
@ -90,51 +87,54 @@ end subroutine source_thermal_externalheat_init
!> @details state only contains current time to linearly interpolate given heat powers !> @details state only contains current time to linearly interpolate given heat powers
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_thermal_externalheat_dotState(phase, of) subroutine source_thermal_externalheat_dotState(phase, of)
integer, intent(in) :: & integer, intent(in) :: &
phase, & phase, &
of of
integer :: & integer :: &
sourceOffset sourceOffset
sourceOffset = source_thermal_externalheat_offset(phase) sourceOffset = source_thermal_externalheat_offset(phase)
sourceState(phase)%p(sourceOffset)%dotState(1,of) = 1.0_pReal ! state is current time sourceState(phase)%p(sourceOffset)%dotState(1,of) = 1.0_pReal ! state is current time
end subroutine source_thermal_externalheat_dotState end subroutine source_thermal_externalheat_dotState
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns local heat generation rate !> @brief returns local heat generation rate
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine source_thermal_externalheat_getRateAndItsTangent(TDot, dTDot_dT, phase, of) subroutine source_thermal_externalheat_getRateAndItsTangent(TDot, dTDot_dT, phase, of)
integer, intent(in) :: & integer, intent(in) :: &
phase, & phase, &
of of
real(pReal), intent(out) :: & real(pReal), intent(out) :: &
TDot, & TDot, &
dTDot_dT dTDot_dT
integer :: & integer :: &
instance, sourceOffset, interval sourceOffset, interval
real(pReal) :: & real(pReal) :: &
frac_time frac_time
instance = source_thermal_externalheat_instance(phase)
sourceOffset = source_thermal_externalheat_offset(phase) sourceOffset = source_thermal_externalheat_offset(phase)
do interval = 1, param(instance)%nIntervals ! scan through all rate segments associate(prm => param(source_thermal_externalheat_instance(phase)))
frac_time = (sourceState(phase)%p(sourceOffset)%state(1,of) - param(instance)%time(interval)) & do interval = 1, prm%nIntervals ! scan through all rate segments
/ (param(instance)%time(interval+1) - param(instance)%time(interval)) ! fractional time within segment frac_time = (sourceState(phase)%p(sourceOffset)%state(1,of) - prm%time(interval)) &
/ (prm%time(interval+1) - prm%time(interval)) ! fractional time within segment
if ( (frac_time < 0.0_pReal .and. interval == 1) & if ( (frac_time < 0.0_pReal .and. interval == 1) &
.or. (frac_time >= 1.0_pReal .and. interval == param(instance)%nIntervals) & .or. (frac_time >= 1.0_pReal .and. interval == prm%nIntervals) &
.or. (frac_time >= 0.0_pReal .and. frac_time < 1.0_pReal) ) & .or. (frac_time >= 0.0_pReal .and. frac_time < 1.0_pReal) ) &
TDot = param(instance)%heat_rate(interval ) * (1.0_pReal - frac_time) + & TDot = prm%heat_rate(interval ) * (1.0_pReal - frac_time) + &
param(instance)%heat_rate(interval+1) * frac_time ! interpolate heat rate between segment boundaries... prm%heat_rate(interval+1) * frac_time ! interpolate heat rate between segment boundaries...
! ...or extrapolate if outside of bounds ! ...or extrapolate if outside of bounds
enddo enddo
dTDot_dT = 0.0 dTDot_dT = 0.0
end associate
end subroutine source_thermal_externalheat_getRateAndItsTangent end subroutine source_thermal_externalheat_getRateAndItsTangent
end module source_thermal_externalheat end module source_thermal_externalheat

View File

@ -11,7 +11,7 @@ module thermal_conduction
use crystallite use crystallite
use source_thermal_dissipation use source_thermal_dissipation
use source_thermal_externalheat use source_thermal_externalheat
implicit none implicit none
private private
@ -19,14 +19,14 @@ module thermal_conduction
character(len=pStringLen), allocatable, dimension(:) :: & character(len=pStringLen), allocatable, dimension(:) :: &
output output
end type tParameters end type tParameters
type(tparameters), dimension(:), allocatable :: & type(tparameters), dimension(:), allocatable :: &
param param
public :: & public :: &
thermal_conduction_init, & thermal_conduction_init, &
thermal_conduction_getSourceAndItsTangent, & thermal_conduction_getSourceAndItsTangent, &
thermal_conduction_getConductivity33, & thermal_conduction_getConductivity, &
thermal_conduction_getSpecificHeat, & thermal_conduction_getSpecificHeat, &
thermal_conduction_getMassDensity, & thermal_conduction_getMassDensity, &
thermal_conduction_putTemperatureAndItsRate, & thermal_conduction_putTemperatureAndItsRate, &
@ -41,37 +41,34 @@ contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine thermal_conduction_init subroutine thermal_conduction_init
integer :: Ninstance,NofMyHomog,h
integer :: maxNinstance,NofMyHomog,h
write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_CONDUCTION_label//' init -+>>>'; flush(6) write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_CONDUCTION_label//' init -+>>>'; flush(6)
maxNinstance = count(thermal_type == THERMAL_conduction_ID) Ninstance = count(thermal_type == THERMAL_conduction_ID)
if (maxNinstance == 0) return allocate(param(Ninstance))
allocate(param(maxNinstance)) do h = 1, size(config_homogenization)
do h = 1, size(thermal_type)
if (thermal_type(h) /= THERMAL_conduction_ID) cycle if (thermal_type(h) /= THERMAL_conduction_ID) cycle
associate(prm => param(thermal_typeInstance(h)),config => config_homogenization(h)) associate(prm => param(thermal_typeInstance(h)),config => config_homogenization(h))
prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray)
NofMyHomog=count(material_homogenizationAt==h) NofMyHomog=count(material_homogenizationAt==h)
thermalState(h)%sizeState = 0 thermalState(h)%sizeState = 0
allocate(thermalState(h)%state0 (0,NofMyHomog)) allocate(thermalState(h)%state0 (0,NofMyHomog))
allocate(thermalState(h)%subState0(0,NofMyHomog)) allocate(thermalState(h)%subState0(0,NofMyHomog))
allocate(thermalState(h)%state (0,NofMyHomog)) allocate(thermalState(h)%state (0,NofMyHomog))
thermalMapping(h)%p => material_homogenizationMemberAt thermalMapping(h)%p => material_homogenizationMemberAt
deallocate(temperature (h)%p) deallocate(temperature (h)%p)
allocate (temperature (h)%p(NofMyHomog), source=thermal_initialT(h)) allocate (temperature (h)%p(NofMyHomog), source=thermal_initialT(h))
deallocate(temperatureRate(h)%p) deallocate(temperatureRate(h)%p)
allocate (temperatureRate(h)%p(NofMyHomog), source=0.0_pReal) allocate (temperatureRate(h)%p(NofMyHomog), source=0.0_pReal)
end associate end associate
enddo enddo
end subroutine thermal_conduction_init end subroutine thermal_conduction_init
@ -79,7 +76,7 @@ end subroutine thermal_conduction_init
!> @brief returns heat generation rate !> @brief returns heat generation rate
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine thermal_conduction_getSourceAndItsTangent(Tdot, dTdot_dT, T, ip, el) subroutine thermal_conduction_getSourceAndItsTangent(Tdot, dTdot_dT, T, ip, el)
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
el !< element number el !< element number
@ -97,74 +94,74 @@ subroutine thermal_conduction_getSourceAndItsTangent(Tdot, dTdot_dT, T, ip, el)
grain, & grain, &
source, & source, &
constituent constituent
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
offset = material_homogenizationMemberAt(ip,el) offset = material_homogenizationMemberAt(ip,el)
instance = thermal_typeInstance(homog) instance = thermal_typeInstance(homog)
Tdot = 0.0_pReal Tdot = 0.0_pReal
dTdot_dT = 0.0_pReal dTdot_dT = 0.0_pReal
do grain = 1, homogenization_Ngrains(homog) do grain = 1, homogenization_Ngrains(homog)
phase = material_phaseAt(grain,el) phase = material_phaseAt(grain,el)
constituent = material_phasememberAt(grain,ip,el) constituent = material_phasememberAt(grain,ip,el)
do source = 1, phase_Nsources(phase) do source = 1, phase_Nsources(phase)
select case(phase_source(source,phase)) select case(phase_source(source,phase))
case (SOURCE_thermal_dissipation_ID) case (SOURCE_thermal_dissipation_ID)
call source_thermal_dissipation_getRateAndItsTangent(my_Tdot, my_dTdot_dT, & call source_thermal_dissipation_getRateAndItsTangent(my_Tdot, my_dTdot_dT, &
crystallite_S(1:3,1:3,grain,ip,el), & crystallite_S(1:3,1:3,grain,ip,el), &
crystallite_Lp(1:3,1:3,grain,ip,el), & crystallite_Lp(1:3,1:3,grain,ip,el), &
phase) phase)
case (SOURCE_thermal_externalheat_ID) case (SOURCE_thermal_externalheat_ID)
call source_thermal_externalheat_getRateAndItsTangent(my_Tdot, my_dTdot_dT, & call source_thermal_externalheat_getRateAndItsTangent(my_Tdot, my_dTdot_dT, &
phase, constituent) phase, constituent)
case default case default
my_Tdot = 0.0_pReal my_Tdot = 0.0_pReal
my_dTdot_dT = 0.0_pReal my_dTdot_dT = 0.0_pReal
end select end select
Tdot = Tdot + my_Tdot Tdot = Tdot + my_Tdot
dTdot_dT = dTdot_dT + my_dTdot_dT dTdot_dT = dTdot_dT + my_dTdot_dT
enddo enddo
enddo enddo
Tdot = Tdot/real(homogenization_Ngrains(homog),pReal) Tdot = Tdot/real(homogenization_Ngrains(homog),pReal)
dTdot_dT = dTdot_dT/real(homogenization_Ngrains(homog),pReal) dTdot_dT = dTdot_dT/real(homogenization_Ngrains(homog),pReal)
end subroutine thermal_conduction_getSourceAndItsTangent end subroutine thermal_conduction_getSourceAndItsTangent
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns homogenized thermal conductivity in reference configuration !> @brief returns homogenized thermal conductivity in reference configuration
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function thermal_conduction_getConductivity33(ip,el) function thermal_conduction_getConductivity(ip,el)
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
el !< element number el !< element number
real(pReal), dimension(3,3) :: & real(pReal), dimension(3,3) :: &
thermal_conduction_getConductivity33 thermal_conduction_getConductivity
integer :: & integer :: &
grain grain
thermal_conduction_getConductivity33 = 0.0_pReal thermal_conduction_getConductivity = 0.0_pReal
do grain = 1, homogenization_Ngrains(material_homogenizationAt(el)) do grain = 1, homogenization_Ngrains(material_homogenizationAt(el))
thermal_conduction_getConductivity33 = thermal_conduction_getConductivity33 + & thermal_conduction_getConductivity = thermal_conduction_getConductivity + &
crystallite_push33ToRef(grain,ip,el,lattice_thermalConductivity33(:,:,material_phaseAt(grain,el))) crystallite_push33ToRef(grain,ip,el,lattice_thermalConductivity(:,:,material_phaseAt(grain,el)))
enddo enddo
thermal_conduction_getConductivity33 = thermal_conduction_getConductivity33 & thermal_conduction_getConductivity = thermal_conduction_getConductivity &
/ real(homogenization_Ngrains(material_homogenizationAt(el)),pReal) / real(homogenization_Ngrains(material_homogenizationAt(el)),pReal)
end function thermal_conduction_getConductivity33 end function thermal_conduction_getConductivity
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief returns homogenized specific heat capacity !> @brief returns homogenized specific heat capacity
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function thermal_conduction_getSpecificHeat(ip,el) function thermal_conduction_getSpecificHeat(ip,el)
integer, intent(in) :: & integer, intent(in) :: &
ip, & !< integration point number ip, & !< integration point number
el !< element number el !< element number
@ -172,17 +169,17 @@ function thermal_conduction_getSpecificHeat(ip,el)
thermal_conduction_getSpecificHeat thermal_conduction_getSpecificHeat
integer :: & integer :: &
grain grain
thermal_conduction_getSpecificHeat = 0.0_pReal thermal_conduction_getSpecificHeat = 0.0_pReal
do grain = 1, homogenization_Ngrains(material_homogenizationAt(el)) do grain = 1, homogenization_Ngrains(material_homogenizationAt(el))
thermal_conduction_getSpecificHeat = thermal_conduction_getSpecificHeat & thermal_conduction_getSpecificHeat = thermal_conduction_getSpecificHeat &
+ lattice_specificHeat(material_phaseAt(grain,el)) + lattice_specificHeat(material_phaseAt(grain,el))
enddo enddo
thermal_conduction_getSpecificHeat = thermal_conduction_getSpecificHeat & thermal_conduction_getSpecificHeat = thermal_conduction_getSpecificHeat &
/ real(homogenization_Ngrains(material_homogenizationAt(el)),pReal) / real(homogenization_Ngrains(material_homogenizationAt(el)),pReal)
end function thermal_conduction_getSpecificHeat end function thermal_conduction_getSpecificHeat
@ -198,18 +195,18 @@ function thermal_conduction_getMassDensity(ip,el)
thermal_conduction_getMassDensity thermal_conduction_getMassDensity
integer :: & integer :: &
grain grain
thermal_conduction_getMassDensity = 0.0_pReal thermal_conduction_getMassDensity = 0.0_pReal
do grain = 1, homogenization_Ngrains(material_homogenizationAt(el)) do grain = 1, homogenization_Ngrains(material_homogenizationAt(el))
thermal_conduction_getMassDensity = thermal_conduction_getMassDensity & thermal_conduction_getMassDensity = thermal_conduction_getMassDensity &
+ lattice_massDensity(material_phaseAt(grain,el)) + lattice_massDensity(material_phaseAt(grain,el))
enddo enddo
thermal_conduction_getMassDensity = thermal_conduction_getMassDensity & thermal_conduction_getMassDensity = thermal_conduction_getMassDensity &
/ real(homogenization_Ngrains(material_homogenizationAt(el)),pReal) / real(homogenization_Ngrains(material_homogenizationAt(el)),pReal)
end function thermal_conduction_getMassDensity end function thermal_conduction_getMassDensity
@ -226,15 +223,15 @@ subroutine thermal_conduction_putTemperatureAndItsRate(T,Tdot,ip,el)
Tdot Tdot
integer :: & integer :: &
homog, & homog, &
offset offset
homog = material_homogenizationAt(el) homog = material_homogenizationAt(el)
offset = thermalMapping(homog)%p(ip,el) offset = thermalMapping(homog)%p(ip,el)
temperature (homog)%p(offset) = T temperature (homog)%p(offset) = T
temperatureRate(homog)%p(offset) = Tdot temperatureRate(homog)%p(offset) = Tdot
end subroutine thermal_conduction_putTemperatureAndItsRate end subroutine thermal_conduction_putTemperatureAndItsRate
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief writes results to HDF5 output file !> @brief writes results to HDF5 output file
@ -245,7 +242,7 @@ subroutine thermal_conduction_results(homog,group)
character(len=*), intent(in) :: group character(len=*), intent(in) :: group
integer :: o integer :: o
associate(prm => param(damage_typeInstance(homog))) associate(prm => param(damage_typeInstance(homog)))
outputsLoop: do o = 1,size(prm%output) outputsLoop: do o = 1,size(prm%output)
select case(trim(prm%output(o))) select case(trim(prm%output(o)))

View File

@ -7,11 +7,8 @@ module thermal_isothermal
use material use material
implicit none implicit none
private public
public :: &
thermal_isothermal_init
contains contains
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------