major restructuring of multi field handling in DAMASK and added some example config files for multi field simulations. please report bugs
This commit is contained in:
parent
aed29e3b77
commit
8f4663985a
|
@ -45,7 +45,7 @@ contains
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief call (thread safe) all module initializations
|
!> @brief call (thread safe) all module initializations
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine CPFEM_initAll(temperature,el,ip)
|
subroutine CPFEM_initAll(temperature_inp,el,ip)
|
||||||
use prec, only: &
|
use prec, only: &
|
||||||
prec_init
|
prec_init
|
||||||
use numerics, only: &
|
use numerics, only: &
|
||||||
|
@ -79,7 +79,7 @@ subroutine CPFEM_initAll(temperature,el,ip)
|
||||||
implicit none
|
implicit none
|
||||||
integer(pInt), intent(in) :: el, & !< FE el number
|
integer(pInt), intent(in) :: el, & !< FE el number
|
||||||
ip !< FE integration point number
|
ip !< FE integration point number
|
||||||
real(pReal), intent(in) :: temperature !< temperature
|
real(pReal), intent(in) :: temperature_inp !< temperature
|
||||||
|
|
||||||
!$OMP CRITICAL (init)
|
!$OMP CRITICAL (init)
|
||||||
if (.not. CPFEM_init_done) then
|
if (.not. CPFEM_init_done) then
|
||||||
|
@ -97,10 +97,10 @@ subroutine CPFEM_initAll(temperature,el,ip)
|
||||||
call FE_init
|
call FE_init
|
||||||
call mesh_init(ip, el) ! pass on coordinates to alter calcMode of first ip
|
call mesh_init(ip, el) ! pass on coordinates to alter calcMode of first ip
|
||||||
call lattice_init
|
call lattice_init
|
||||||
call material_init(temperature)
|
call material_init
|
||||||
call constitutive_init(temperature)
|
call constitutive_init
|
||||||
call crystallite_init
|
call crystallite_init
|
||||||
call homogenization_init
|
call homogenization_init(temperature_inp)
|
||||||
call CPFEM_init
|
call CPFEM_init
|
||||||
#if defined(Marc4DAMASK) || defined(Abaqus)
|
#if defined(Marc4DAMASK) || defined(Abaqus)
|
||||||
call DAMASK_interface_init ! Spectral solver and FEM init is already done
|
call DAMASK_interface_init ! Spectral solver and FEM init is already done
|
||||||
|
@ -262,9 +262,9 @@ end subroutine CPFEM_init
|
||||||
!> @brief perform initialization at first call, update variables and call the actual material model
|
!> @brief perform initialization at first call, update variables and call the actual material model
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
#if defined(Marc4DAMASK) || defined(Abaqus)
|
#if defined(Marc4DAMASK) || defined(Abaqus)
|
||||||
subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature, dt, elFE, ip, cauchyStress, jacobian)
|
subroutine CPFEM_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyStress, jacobian)
|
||||||
#else
|
#else
|
||||||
subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip)
|
||||||
#endif
|
#endif
|
||||||
use numerics, only: &
|
use numerics, only: &
|
||||||
defgradTolerance, &
|
defgradTolerance, &
|
||||||
|
@ -316,13 +316,19 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
||||||
use material, only: &
|
use material, only: &
|
||||||
microstructure_elemhomo, &
|
microstructure_elemhomo, &
|
||||||
plasticState, &
|
plasticState, &
|
||||||
damageState, &
|
sourceState, &
|
||||||
homogState, &
|
homogState, &
|
||||||
thermalState, &
|
thermalState, &
|
||||||
vacancyState,&
|
damageState, &
|
||||||
|
vacancyfluxState, &
|
||||||
|
hydrogenfluxState, &
|
||||||
mappingConstitutive, &
|
mappingConstitutive, &
|
||||||
material_phase, &
|
material_phase, &
|
||||||
phase_plasticity, &
|
phase_plasticity, &
|
||||||
|
temperature, &
|
||||||
|
thermalMapping, &
|
||||||
|
phase_Nsources, &
|
||||||
|
material_homog, &
|
||||||
material_Nhomogenization
|
material_Nhomogenization
|
||||||
use crystallite, only: &
|
use crystallite, only: &
|
||||||
crystallite_partionedF,&
|
crystallite_partionedF,&
|
||||||
|
@ -349,8 +355,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
||||||
materialpoint_sizeResults, &
|
materialpoint_sizeResults, &
|
||||||
#endif
|
#endif
|
||||||
materialpoint_stressAndItsTangent, &
|
materialpoint_stressAndItsTangent, &
|
||||||
materialpoint_postResults, &
|
materialpoint_postResults
|
||||||
field_putFieldTemperature
|
|
||||||
use IO, only: &
|
use IO, only: &
|
||||||
IO_write_jobRealFile, &
|
IO_write_jobRealFile, &
|
||||||
IO_warning
|
IO_warning
|
||||||
|
@ -359,7 +364,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
||||||
implicit none
|
implicit none
|
||||||
integer(pInt), intent(in) :: elFE, & !< FE element number
|
integer(pInt), intent(in) :: elFE, & !< FE element number
|
||||||
ip !< integration point number
|
ip !< integration point number
|
||||||
real(pReal), intent(in) :: temperature !< temperature
|
real(pReal), intent(in) :: temperature_inp !< temperature
|
||||||
real(pReal), intent(in) :: dt !< time increment
|
real(pReal), intent(in) :: dt !< time increment
|
||||||
real(pReal), dimension (3,3), intent(in) :: ffn, & !< deformation gradient for t=t0
|
real(pReal), dimension (3,3), intent(in) :: ffn, & !< deformation gradient for t=t0
|
||||||
ffn1 !< deformation gradient for t=t1
|
ffn1 !< deformation gradient for t=t1
|
||||||
|
@ -381,7 +386,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
integer(pInt) elCP, & ! crystal plasticity element number
|
integer(pInt) elCP, & ! crystal plasticity element number
|
||||||
i, j, k, l, m, n, ph, homog
|
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
|
||||||
character(len=1024) :: rankStr
|
character(len=1024) :: rankStr
|
||||||
|
|
||||||
|
@ -427,10 +432,11 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
||||||
crystallite_dPdF0 = crystallite_dPdF ! crystallite stiffness
|
crystallite_dPdF0 = crystallite_dPdF ! crystallite stiffness
|
||||||
crystallite_Tstar0_v = crystallite_Tstar_v ! crystallite 2nd Piola Kirchhoff stress
|
crystallite_Tstar0_v = crystallite_Tstar_v ! crystallite 2nd Piola Kirchhoff stress
|
||||||
|
|
||||||
forall ( i = 1:size(plasticState)) plasticState(i)%state0= plasticState(i)%state ! copy state in this lenghty way because: A component cannot be an array if the encompassing structure is an array
|
forall ( i = 1:size(plasticState )) plasticState(i)%state0 = plasticState(i)%state ! copy state in this lenghty way because: A component cannot be an array if the encompassing structure is an array
|
||||||
forall ( i = 1:size(damageState)) damageState(i)%state0 = damageState(i)%state ! copy state in this lenghty way because: A component cannot be an array if the encompassing structure is an array
|
do i = 1, size(sourceState)
|
||||||
forall ( i = 1:size(thermalState)) thermalState(i)%state0= thermalState(i)%state ! copy state in this lenghty way because: A component cannot be an array if the encompassing structure is an array
|
do mySource = 1,phase_Nsources(i)
|
||||||
forall ( i = 1:size(vacancyState)) vacancyState(i)%state0= vacancyState(i)%state ! copy state in this lenghty way because: A component cannot be an array if the encompassing structure is an array
|
sourceState(i)%p(mySource)%state0 = sourceState(i)%p(mySource)%state ! copy state in this lenghty way because: A component cannot be an array if the encompassing structure is an array
|
||||||
|
enddo; enddo
|
||||||
if (iand(debug_level(debug_CPFEM), debug_levelBasic) /= 0_pInt) then
|
if (iand(debug_level(debug_CPFEM), debug_levelBasic) /= 0_pInt) then
|
||||||
write(6,'(a)') '<< CPFEM >> aging states'
|
write(6,'(a)') '<< CPFEM >> aging states'
|
||||||
if (debug_e <= mesh_NcpElems .and. debug_i <= mesh_maxNips) then
|
if (debug_e <= mesh_NcpElems .and. debug_i <= mesh_maxNips) then
|
||||||
|
@ -441,7 +447,11 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
do homog = 1_pInt, material_Nhomogenization
|
do homog = 1_pInt, material_Nhomogenization
|
||||||
homogState(homog)%state0 = homogState(homog)%state
|
homogState (homog)%state0 = homogState (homog)%state
|
||||||
|
thermalState (homog)%state0 = thermalState (homog)%state
|
||||||
|
damageState (homog)%state0 = damageState (homog)%state
|
||||||
|
vacancyfluxState (homog)%state0 = vacancyfluxState (homog)%state
|
||||||
|
hydrogenfluxState(homog)%state0 = hydrogenfluxState(homog)%state
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
|
||||||
|
@ -523,7 +533,8 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
||||||
|
|
||||||
if (.not. parallelExecution) then
|
if (.not. parallelExecution) then
|
||||||
#if defined(Marc4DAMASK) || defined(Abaqus)
|
#if defined(Marc4DAMASK) || defined(Abaqus)
|
||||||
call field_putFieldTemperature(ip,elCP,temperature)
|
temperature(material_homog(ip,elCP))%p(thermalMapping(material_homog(ip,elCP))%p(ip,elCP)) = &
|
||||||
|
temperature_inp
|
||||||
#endif
|
#endif
|
||||||
materialpoint_F0(1:3,1:3,ip,elCP) = ffn
|
materialpoint_F0(1:3,1:3,ip,elCP) = ffn
|
||||||
materialpoint_F(1:3,1:3,ip,elCP) = ffn1
|
materialpoint_F(1:3,1:3,ip,elCP) = ffn1
|
||||||
|
@ -536,7 +547,8 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
||||||
CPFEM_dcsde(1:6,1:6,ip,elCP) = CPFEM_odd_jacobian * math_identity2nd(6)
|
CPFEM_dcsde(1:6,1:6,ip,elCP) = CPFEM_odd_jacobian * math_identity2nd(6)
|
||||||
#endif
|
#endif
|
||||||
#if defined(Marc4DAMASK) || defined(Abaqus)
|
#if defined(Marc4DAMASK) || defined(Abaqus)
|
||||||
call field_putFieldTemperature(ip,elCP,temperature)
|
temperature(material_homog(ip,elCP))%p(thermalMapping(material_homog(ip,elCP))%p(ip,elCP)) = &
|
||||||
|
temperature_inp
|
||||||
#endif
|
#endif
|
||||||
materialpoint_F0(1:3,1:3,ip,elCP) = ffn
|
materialpoint_F0(1:3,1:3,ip,elCP) = ffn
|
||||||
materialpoint_F(1:3,1:3,ip,elCP) = ffn1
|
materialpoint_F(1:3,1:3,ip,elCP) = ffn1
|
||||||
|
|
|
@ -140,7 +140,7 @@ program DAMASK_spectral_Driver
|
||||||
external :: quit
|
external :: quit
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! init DAMASK (all modules)
|
! init DAMASK (all modules)
|
||||||
call CPFEM_initAll(temperature = 300.0_pReal, el = 1_pInt, ip = 1_pInt)
|
call CPFEM_initAll(temperature_inp = 300.0_pReal, el = 1_pInt, ip = 1_pInt)
|
||||||
mainProcess: if (worldrank == 0) then
|
mainProcess: if (worldrank == 0) then
|
||||||
write(6,'(/,a)') ' <<<+- DAMASK_spectral_driver init -+>>>'
|
write(6,'(/,a)') ' <<<+- DAMASK_spectral_driver init -+>>>'
|
||||||
write(6,'(a)') ' $Id$'
|
write(6,'(a)') ' $Id$'
|
||||||
|
|
|
@ -205,7 +205,7 @@ subroutine basicPETSc_init(temperature)
|
||||||
call Utilities_updateIPcoords(F)
|
call Utilities_updateIPcoords(F)
|
||||||
call Utilities_constitutiveResponse(F_lastInc, F, &
|
call Utilities_constitutiveResponse(F_lastInc, F, &
|
||||||
temperature, &
|
temperature, &
|
||||||
0.0_pReal, &
|
1.0_pReal, &
|
||||||
P, &
|
P, &
|
||||||
C_volAvg,C_minMaxAvg, & ! global average of stiffness and (min+max)/2
|
C_volAvg,C_minMaxAvg, & ! global average of stiffness and (min+max)/2
|
||||||
temp33_Real, &
|
temp33_Real, &
|
||||||
|
|
|
@ -395,10 +395,13 @@ subroutine utilities_FFTforward()
|
||||||
use numerics, only: &
|
use numerics, only: &
|
||||||
worldrank
|
worldrank
|
||||||
use mesh, only: &
|
use mesh, only: &
|
||||||
gridOffset, &
|
|
||||||
gridLocal
|
gridLocal
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
external :: &
|
||||||
|
MPI_Bcast, &
|
||||||
|
MPI_reduce
|
||||||
|
|
||||||
integer(pInt) :: row, column ! if debug FFTW, compare 3D array field of row and column
|
integer(pInt) :: row, column ! if debug FFTW, compare 3D array field of row and column
|
||||||
real(pReal), dimension(2) :: myRand, maxScalarField ! random numbers
|
real(pReal), dimension(2) :: myRand, maxScalarField ! random numbers
|
||||||
integer(pInt) :: i, j, k
|
integer(pInt) :: i, j, k
|
||||||
|
@ -433,7 +436,7 @@ subroutine utilities_FFTforward()
|
||||||
field_fourierMPI(row,column,1:grid1Red,1:gridLocal(2),1:gridLocal(3)))/&
|
field_fourierMPI(row,column,1:grid1Red,1:gridLocal(2),1:gridLocal(3)))/&
|
||||||
scalarField_fourierMPI(1:grid1Red,1:gridLocal(2),1:gridLocal(3))
|
scalarField_fourierMPI(1:grid1Red,1:gridLocal(2),1:gridLocal(3))
|
||||||
else where
|
else where
|
||||||
scalarField_realMPI = cmplx(0.0,0.0,pReal)
|
scalarField_fourierMPI = cmplx(0.0,0.0,pReal)
|
||||||
end where
|
end where
|
||||||
maxScalarField(1) = maxval(real (scalarField_fourierMPI(1:grid1Red,1:gridLocal(2), &
|
maxScalarField(1) = maxval(real (scalarField_fourierMPI(1:grid1Red,1:gridLocal(2), &
|
||||||
1:gridLocal(3))))
|
1:gridLocal(3))))
|
||||||
|
@ -451,7 +454,7 @@ subroutine utilities_FFTforward()
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! applying filter
|
! applying filter
|
||||||
do k = 1_pInt, gridLocal(3); do j = 1_pInt, gridLocal(2); do i = 1_pInt,grid1Red
|
do k = 1_pInt, gridLocal(3); do j = 1_pInt, gridLocal(2); do i = 1_pInt,grid1Red
|
||||||
field_fourierMPI(1:3,1:3,i,j,k) = utilities_getFilter(xi(1:3,i,j,k))* &
|
field_fourierMPI(1:3,1:3,i,j,k) = cmplx(utilities_getFilter(xi(1:3,i,j,k)),0.0,pReal)* &
|
||||||
field_fourierMPI(1:3,1:3,i,j,k)
|
field_fourierMPI(1:3,1:3,i,j,k)
|
||||||
enddo; enddo; enddo
|
enddo; enddo; enddo
|
||||||
|
|
||||||
|
@ -473,6 +476,10 @@ subroutine utilities_FFTbackward()
|
||||||
gridLocal
|
gridLocal
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
external :: &
|
||||||
|
MPI_Bcast, &
|
||||||
|
MPI_reduce
|
||||||
|
|
||||||
integer(pInt) :: row, column !< if debug FFTW, compare 3D array field of row and column
|
integer(pInt) :: row, column !< if debug FFTW, compare 3D array field of row and column
|
||||||
real(pReal), dimension(2) :: myRand
|
real(pReal), dimension(2) :: myRand
|
||||||
real(pReal) :: maxScalarField
|
real(pReal) :: maxScalarField
|
||||||
|
@ -506,7 +513,7 @@ subroutine utilities_FFTbackward()
|
||||||
- field_realMPI (row,column,1:gridLocal(1),1:gridLocal(2),1:gridLocal(3)))/ &
|
- field_realMPI (row,column,1:gridLocal(1),1:gridLocal(2),1:gridLocal(3)))/ &
|
||||||
scalarField_realMPI(1:gridLocal(1),1:gridLocal(2),1:gridLocal(3))
|
scalarField_realMPI(1:gridLocal(1),1:gridLocal(2),1:gridLocal(3))
|
||||||
else where
|
else where
|
||||||
scalarField_realMPI = cmplx(0.0,0.0,pReal)
|
scalarField_realMPI = 0.0_pReal
|
||||||
end where
|
end where
|
||||||
maxScalarField = maxval(real (scalarField_realMPI(1:gridLocal(1),1:gridLocal(2),1:gridLocal(3))))
|
maxScalarField = maxval(real (scalarField_realMPI(1:gridLocal(1),1:gridLocal(2),1:gridLocal(3))))
|
||||||
call MPI_reduce(MPI_IN_PLACE,maxScalarField,1,MPI_DOUBLE,MPI_MAX,0,PETSC_COMM_WORLD,ierr)
|
call MPI_reduce(MPI_IN_PLACE,maxScalarField,1,MPI_DOUBLE,MPI_MAX,0,PETSC_COMM_WORLD,ierr)
|
||||||
|
@ -627,6 +634,10 @@ real(pReal) function utilities_divergenceRMS()
|
||||||
gridGlobal
|
gridGlobal
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
external :: &
|
||||||
|
MPI_reduce, &
|
||||||
|
MPI_Allreduce
|
||||||
|
|
||||||
integer(pInt) :: i, j, k
|
integer(pInt) :: i, j, k
|
||||||
real(pReal) :: &
|
real(pReal) :: &
|
||||||
err_real_div_RMS, & !< RMS of divergence in real space
|
err_real_div_RMS, & !< RMS of divergence in real space
|
||||||
|
@ -714,6 +725,9 @@ real(pReal) function utilities_curlRMS()
|
||||||
gridGlobal
|
gridGlobal
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
external :: &
|
||||||
|
MPI_Allreduce
|
||||||
|
|
||||||
integer(pInt) :: i, j, k, l
|
integer(pInt) :: i, j, k, l
|
||||||
complex(pReal), dimension(3,3) :: curl_fourier
|
complex(pReal), dimension(3,3) :: curl_fourier
|
||||||
PetscErrorCode :: ierr
|
PetscErrorCode :: ierr
|
||||||
|
@ -898,10 +912,14 @@ subroutine utilities_constitutiveResponse(F_lastInc,F,temperature,timeinc,&
|
||||||
materialpoint_F, &
|
materialpoint_F, &
|
||||||
materialpoint_P, &
|
materialpoint_P, &
|
||||||
materialpoint_dPdF
|
materialpoint_dPdF
|
||||||
use thermal_isothermal, only: &
|
! use thermal_isothermal, only: &
|
||||||
thermal_isothermal_temperature
|
! thermal_isothermal_temperature
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
external :: &
|
||||||
|
MPI_reduce, &
|
||||||
|
MPI_Allreduce
|
||||||
|
|
||||||
real(pReal), intent(in) :: temperature !< temperature (no field)
|
real(pReal), intent(in) :: temperature !< temperature (no field)
|
||||||
real(pReal), intent(in), dimension(3,3,gridLocal(1),gridLocal(2),gridLocal(3)) :: &
|
real(pReal), intent(in), dimension(3,3,gridLocal(1),gridLocal(2),gridLocal(3)) :: &
|
||||||
F_lastInc, & !< target deformation gradient
|
F_lastInc, & !< target deformation gradient
|
||||||
|
@ -937,7 +955,7 @@ subroutine utilities_constitutiveResponse(F_lastInc,F,temperature,timeinc,&
|
||||||
|
|
||||||
call CPFEM_general(CPFEM_COLLECT,F_lastInc(1:3,1:3,1,1,1),F(1:3,1:3,1,1,1), &
|
call CPFEM_general(CPFEM_COLLECT,F_lastInc(1:3,1:3,1,1,1),F(1:3,1:3,1,1,1), &
|
||||||
temperature,timeinc,1_pInt,1_pInt)
|
temperature,timeinc,1_pInt,1_pInt)
|
||||||
thermal_isothermal_temperature(:) = temperature
|
! thermal_isothermal_temperature(:) = temperature
|
||||||
materialpoint_F = reshape(F,[3,3,1,product(gridLocal)])
|
materialpoint_F = reshape(F,[3,3,1,product(gridLocal)])
|
||||||
|
|
||||||
call debug_reset()
|
call debug_reset()
|
||||||
|
@ -1044,6 +1062,9 @@ function utilities_forwardField(timeinc,field_lastInc,rate,aim)
|
||||||
gridLocal
|
gridLocal
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
external :: &
|
||||||
|
MPI_Allreduce
|
||||||
|
|
||||||
real(pReal), intent(in) :: &
|
real(pReal), intent(in) :: &
|
||||||
timeinc !< timeinc of current step
|
timeinc !< timeinc of current step
|
||||||
real(pReal), intent(in), dimension(3,3,gridLocal(1),gridLocal(2),gridLocal(3)) :: &
|
real(pReal), intent(in), dimension(3,3,gridLocal(1),gridLocal(2),gridLocal(3)) :: &
|
||||||
|
@ -1143,6 +1164,8 @@ subroutine utilities_updateIPcoords(F)
|
||||||
geomSizeGlobal, &
|
geomSizeGlobal, &
|
||||||
mesh_ipCoordinates
|
mesh_ipCoordinates
|
||||||
implicit none
|
implicit none
|
||||||
|
external :: &
|
||||||
|
MPI_Bcast
|
||||||
|
|
||||||
real(pReal), dimension(3,3,gridLocal(1),gridLocal(2),gridLocal(3)), intent(in) :: F
|
real(pReal), dimension(3,3,gridLocal(1),gridLocal(2),gridLocal(3)), intent(in) :: F
|
||||||
integer(pInt) :: i, j, k, m
|
integer(pInt) :: i, j, k, m
|
||||||
|
|
204
code/Makefile
204
code/Makefile
|
@ -187,7 +187,8 @@ COMPILE_OPTIONS_gfortran +=-ffree-line-length-132\
|
||||||
-Wsuggest-attribute=pure\
|
-Wsuggest-attribute=pure\
|
||||||
-Wsuggest-attribute=noreturn\
|
-Wsuggest-attribute=noreturn\
|
||||||
-Wconversion-extra\
|
-Wconversion-extra\
|
||||||
-Wimplicit-procedure
|
-Wimplicit-procedure\
|
||||||
|
-Wno-unused-parameter
|
||||||
endif
|
endif
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
#COMPILE SWITCHES
|
#COMPILE SWITCHES
|
||||||
|
@ -305,22 +306,37 @@ PRECISION_gfortran :=-fdefault-real-8 -fdefault-double-8 -DFLOAT=8 -DINT=4
|
||||||
COMPILE =$(OPENMP_FLAG_$(F90)) $(COMPILE_OPTIONS_$(F90)) $(STANDARD_CHECK_$(F90)) $(OPTIMIZATION_$(OPTI)_$(F90)) $(INCLUDE_DIRS) $(PRECISION_$(F90))
|
COMPILE =$(OPENMP_FLAG_$(F90)) $(COMPILE_OPTIONS_$(F90)) $(STANDARD_CHECK_$(F90)) $(OPTIMIZATION_$(OPTI)_$(F90)) $(INCLUDE_DIRS) $(PRECISION_$(F90))
|
||||||
COMPILE_MAXOPTI =$(OPENMP_FLAG_$(F90)) $(COMPILE_OPTIONS_$(F90)) $(STANDARD_CHECK_$(F90)) $(OPTIMIZATION_$(MAXOPTI)_$(F90)) $(INCLUDE_DIRS) $(PRECISION_$(F90))
|
COMPILE_MAXOPTI =$(OPENMP_FLAG_$(F90)) $(COMPILE_OPTIONS_$(F90)) $(STANDARD_CHECK_$(F90)) $(OPTIMIZATION_$(MAXOPTI)_$(F90)) $(INCLUDE_DIRS) $(PRECISION_$(F90))
|
||||||
###################################################################################################
|
###################################################################################################
|
||||||
DAMAGE_FILES = \
|
SOURCE_FILES = \
|
||||||
damage_none.o damage_isoBrittle.o damage_isoDuctile.o damage_gurson.o damage_anisoBrittle.o damage_anisoDuctile.o damage_phaseField.o
|
source_thermal_dissipation.o \
|
||||||
|
source_damage_isoBrittle.o source_damage_isoDuctile.o source_damage_anisoBrittle.o source_damage_anisoDuctile.o \
|
||||||
|
source_vacancy_phenoplasticity.o source_vacancy_irradiation.o source_vacancy_thermalfluc.o
|
||||||
|
|
||||||
THERMAL_FILES = \
|
KINEMATICS_FILES = \
|
||||||
thermal_isothermal.o thermal_adiabatic.o
|
kinematics_cleavage_opening.o kinematics_slipplane_opening.o \
|
||||||
|
kinematics_thermal_expansion.o \
|
||||||
VACANCY_FILES = \
|
kinematics_vacancy_strain.o kinematics_hydrogen_strain.o
|
||||||
vacancy_constant.o vacancy_generation.o
|
|
||||||
|
|
||||||
PLASTIC_FILES = \
|
PLASTIC_FILES = \
|
||||||
plastic_dislotwin.o plastic_disloUCLA.o plastic_disloKMC.o plastic_j2.o plastic_phenopowerlaw.o \
|
plastic_dislotwin.o plastic_disloUCLA.o plastic_disloKMC.o plastic_j2.o plastic_phenopowerlaw.o \
|
||||||
plastic_titanmod.o plastic_nonlocal.o plastic_none.o
|
plastic_titanmod.o plastic_nonlocal.o plastic_none.o
|
||||||
|
|
||||||
|
THERMAL_FILES = \
|
||||||
|
thermal_isothermal.o thermal_adiabatic.o thermal_conduction.o
|
||||||
|
|
||||||
|
DAMAGE_FILES = \
|
||||||
|
damage_none.o damage_local.o damage_nonlocal.o
|
||||||
|
|
||||||
|
VACANCYFLUX_FILES = \
|
||||||
|
vacancyflux_isoconc.o vacancyflux_isochempot.o vacancyflux_cahnhilliard.o
|
||||||
|
|
||||||
|
POROSITY_FILES = \
|
||||||
|
porosity_none.o porosity_phasefield.o
|
||||||
|
|
||||||
|
HYDROGENFLUX_FILES = \
|
||||||
|
hydrogenflux_isoconc.o hydrogenflux_cahnhilliard.o
|
||||||
|
|
||||||
HOMOGENIZATION_FILES = \
|
HOMOGENIZATION_FILES = \
|
||||||
homogenization_RGC.o homogenization_isostrain.o homogenization_none.o homogenization.o
|
homogenization_RGC.o homogenization_isostrain.o homogenization_none.o
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
# Spectral Solver
|
# Spectral Solver
|
||||||
|
@ -332,12 +348,17 @@ DAMASK_spectral.exe: MESHNAME := mesh.f90
|
||||||
DAMASK_spectral.exe: INTERFACENAME := DAMASK_spectral_interface.f90
|
DAMASK_spectral.exe: INTERFACENAME := DAMASK_spectral_interface.f90
|
||||||
|
|
||||||
|
|
||||||
|
SPECTRAL_SOLVER_FILES = DAMASK_spectral_solverAL.o DAMASK_spectral_solverBasicPETSc.o DAMASK_spectral_solverPolarisation.o
|
||||||
|
|
||||||
SPECTRAL_FILES = prec.o DAMASK_interface.o IO.o libs.o numerics.o debug.o math.o \
|
SPECTRAL_FILES = prec.o DAMASK_interface.o IO.o libs.o numerics.o debug.o math.o \
|
||||||
FEsolving.o mesh.o material.o lattice.o constitutive.o \
|
FEsolving.o mesh.o material.o lattice.o \
|
||||||
$(DAMAGE_FILES) $(THERMAL_FILES) $(VACANCY_FILES) $(PLASTIC_FILES) \
|
$(SOURCE_FILES) $(KINEMATICS_FILES) $(PLASTIC_FILES) constitutive.o \
|
||||||
crystallite.o $(HOMOGENIZATION_FILES) CPFEM.o \
|
crystallite.o \
|
||||||
|
$(THERMAL_FILES) $(DAMAGE_FILES) $(VACANCYFLUX_FILES) $(HYDROGENFLUX_FILES) $(POROSITY_FILES) \
|
||||||
|
$(HOMOGENIZATION_FILES) homogenization.o \
|
||||||
|
CPFEM.o \
|
||||||
DAMASK_spectral_utilities.o \
|
DAMASK_spectral_utilities.o \
|
||||||
DAMASK_spectral_solverAL.o DAMASK_spectral_solverBasicPETSc.o DAMASK_spectral_solverPolarisation.o
|
$(SPECTRAL_SOLVER_FILES)
|
||||||
|
|
||||||
DAMASK_spectral.exe: DAMASK_spectral_driver.o
|
DAMASK_spectral.exe: DAMASK_spectral_driver.o
|
||||||
$(PREFIX) $(LINKERNAME) $(OPENMP_FLAG_$(F90)) $(LINK_OPTIONS_$(F90)) $(STANDARD_CHECK_$(F90)) $(OPTIMIZATION_$(MAXOPTI)_$(F90)) \
|
$(PREFIX) $(LINKERNAME) $(OPENMP_FLAG_$(F90)) $(LINK_OPTIONS_$(F90)) $(STANDARD_CHECK_$(F90)) $(OPTIMIZATION_$(MAXOPTI)_$(F90)) \
|
||||||
|
@ -346,9 +367,7 @@ DAMASK_spectral.exe: DAMASK_spectral_driver.o
|
||||||
|
|
||||||
|
|
||||||
DAMASK_spectral_driver.o: DAMASK_spectral_driver.f90 \
|
DAMASK_spectral_driver.o: DAMASK_spectral_driver.f90 \
|
||||||
DAMASK_spectral_solverAL.o \
|
$(SPECTRAL_SOLVER_FILES)
|
||||||
DAMASK_spectral_solverBasicPETSc.o \
|
|
||||||
DAMASK_spectral_solverPolarisation.o
|
|
||||||
$(PREFIX) $(COMPILERNAME) $(COMPILE_MAXOPTI) -c DAMASK_spectral_driver.f90 $(SUFFIX)
|
$(PREFIX) $(COMPILERNAME) $(COMPILE_MAXOPTI) -c DAMASK_spectral_driver.f90 $(SUFFIX)
|
||||||
|
|
||||||
DAMASK_spectral_solverAL.o: DAMASK_spectral_solverAL.f90 \
|
DAMASK_spectral_solverAL.o: DAMASK_spectral_solverAL.f90 \
|
||||||
|
@ -373,18 +392,23 @@ DAMASK_FEM.exe: MESHNAME := ../private/FEM/code/meshFEM.f90
|
||||||
DAMASK_FEM.exe: INTERFACENAME := ../private/FEM/code/DAMASK_FEM_interface.f90
|
DAMASK_FEM.exe: INTERFACENAME := ../private/FEM/code/DAMASK_FEM_interface.f90
|
||||||
DAMASK_FEM.exe: INCLUDE_DIRS += -I./
|
DAMASK_FEM.exe: INCLUDE_DIRS += -I./
|
||||||
|
|
||||||
|
FEM_SOLVER_FILES = FEM_mech.o FEM_thermal.o FEM_damage.o FEM_vacancyflux.o FEM_porosity.o FEM_hydrogenflux.o
|
||||||
|
|
||||||
FEM_FILES = prec.o DAMASK_interface.o FEZoo.o IO.o libs.o numerics.o debug.o math.o \
|
FEM_FILES = prec.o DAMASK_interface.o FEZoo.o IO.o libs.o numerics.o debug.o math.o \
|
||||||
FEsolving.o mesh.o material.o lattice.o \
|
FEsolving.o mesh.o material.o lattice.o \
|
||||||
$(DAMAGE_FILES) $(THERMAL_FILES) $(VACANCY_FILES) $(PLASTIC_FILES) \
|
$(SOURCE_FILES) $(KINEMATICS_FILES) $(PLASTIC_FILES) constitutive.o \
|
||||||
crystallite.o $(HOMOGENIZATION_FILES) CPFEM.o \
|
crystallite.o \
|
||||||
FEM_utilities.o FEM_mech.o FEM_thermal.o FEM_damage.o FEM_vacancyDiffusion.o
|
$(THERMAL_FILES) $(DAMAGE_FILES) $(VACANCYFLUX_FILES) $(HYDROGENFLUX_FILES) $(POROSITY_FILES) \
|
||||||
|
$(HOMOGENIZATION_FILES) homogenization.o \
|
||||||
|
CPFEM.o \
|
||||||
|
FEM_utilities.o $(FEM_SOLVER_FILES)
|
||||||
|
|
||||||
DAMASK_FEM.exe: DAMASK_FEM_driver.o
|
DAMASK_FEM.exe: DAMASK_FEM_driver.o
|
||||||
$(PREFIX) $(LINKERNAME) $(LINK_OPTIONS_$(F90)) $(STANDARD_CHECK_$(F90)) $(OPTIMIZATION_$(MAXOPTI)_$(F90)) \
|
$(PREFIX) $(LINKERNAME) $(OPENMP_FLAG_$(F90)) $(LINK_OPTIONS_$(F90)) $(STANDARD_CHECK_$(F90)) $(OPTIMIZATION_$(MAXOPTI)_$(F90)) \
|
||||||
-o DAMASK_FEM.exe DAMASK_FEM_driver.o \
|
-o DAMASK_FEM.exe DAMASK_FEM_driver.o \
|
||||||
$(FEM_FILES) $(LIBRARIES) $(SUFFIX)
|
$(FEM_FILES) $(LIBRARIES) $(SUFFIX)
|
||||||
|
|
||||||
DAMASK_FEM_driver.o: DAMASK_FEM_driver.f90 FEM_mech.o FEM_thermal.o FEM_damage.o FEM_vacancyDiffusion.o
|
DAMASK_FEM_driver.o: DAMASK_FEM_driver.f90 $(FEM_SOLVER_FILES)
|
||||||
$(PREFIX) $(COMPILERNAME) $(COMPILE_MAXOPTI) -c ../private/FEM/code/DAMASK_FEM_driver.f90 $(SUFFIX)
|
$(PREFIX) $(COMPILERNAME) $(COMPILE_MAXOPTI) -c ../private/FEM/code/DAMASK_FEM_driver.f90 $(SUFFIX)
|
||||||
|
|
||||||
FEM_mech.o: FEM_mech.f90 \
|
FEM_mech.o: FEM_mech.f90 \
|
||||||
|
@ -396,7 +420,13 @@ FEM_thermal.o: FEM_thermal.f90 \
|
||||||
FEM_damage.o: FEM_damage.f90 \
|
FEM_damage.o: FEM_damage.f90 \
|
||||||
FEM_utilities.o
|
FEM_utilities.o
|
||||||
|
|
||||||
FEM_vacancyDiffusion.o: FEM_vacancyDiffusion.f90 \
|
FEM_vacancyflux.o: FEM_vacancyflux.f90 \
|
||||||
|
FEM_utilities.o
|
||||||
|
|
||||||
|
FEM_porosity.o: FEM_porosity.f90 \
|
||||||
|
FEM_utilities.o
|
||||||
|
|
||||||
|
FEM_hydrogenflux.o: FEM_hydrogenflux.f90 \
|
||||||
FEM_utilities.o
|
FEM_utilities.o
|
||||||
|
|
||||||
FEM_utilities.o: FEM_utilities.f90 \
|
FEM_utilities.o: FEM_utilities.f90 \
|
||||||
|
@ -411,9 +441,54 @@ CPFEM.o: CPFEM.f90\
|
||||||
homogenization.o
|
homogenization.o
|
||||||
|
|
||||||
homogenization.o: homogenization.f90\
|
homogenization.o: homogenization.f90\
|
||||||
homogenization_none.o \
|
$(THERMAL_FILES) \
|
||||||
homogenization_RGC.o \
|
$(DAMAGE_FILES) \
|
||||||
homogenization_isostrain.o
|
$(VACANCYFLUX_FILES) \
|
||||||
|
$(POROSITY_FILES) \
|
||||||
|
$(HYDROGENFLUX_FILES) \
|
||||||
|
$(HOMOGENIZATION_FILES)
|
||||||
|
|
||||||
|
thermal_isothermal.o: thermal_isothermal.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
thermal_adiabatic.o: thermal_adiabatic.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
thermal_conduction.o: thermal_conduction.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
damage_none.o: damage_none.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
damage_local.o: damage_local.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
damage_nonlocal.o: damage_nonlocal.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
thermal_conduction.o: thermal_conduction.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
vacancyflux_isoconc.o: vacancyflux_isoconc.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
vacancyflux_isochempot.o: vacancyflux_isochempot.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
vacancyflux_cahnhilliard.o: vacancyflux_cahnhilliard.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
porosity_none.o: porosity_none.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
porosity_phasefield.o: porosity_phasefield.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
hydrogenflux_isoconc.o: hydrogenflux_isoconc.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
|
hydrogenflux_cahnhilliard.o: hydrogenflux_cahnhilliard.f90 \
|
||||||
|
crystallite.o
|
||||||
|
|
||||||
homogenization_RGC.o: homogenization_RGC.f90 \
|
homogenization_RGC.o: homogenization_RGC.f90 \
|
||||||
crystallite.o
|
crystallite.o
|
||||||
|
@ -428,10 +503,48 @@ crystallite.o: crystallite.f90 \
|
||||||
constitutive.o
|
constitutive.o
|
||||||
|
|
||||||
constitutive.o: constitutive.f90 \
|
constitutive.o: constitutive.f90 \
|
||||||
$(PLASTIC_FILES) \
|
$(SOURCE_FILES) \
|
||||||
$(DAMAGE_FILES) \
|
$(KINEMATICS_FILES) \
|
||||||
$(THERMAL_FILES) \
|
$(PLASTIC_FILES)
|
||||||
$(VACANCY_FILES)
|
|
||||||
|
source_thermal_dissipation.o: source_thermal_dissipation.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
source_damage_isoBrittle.o: source_damage_isoBrittle.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
source_damage_isoDuctile.o: source_damage_isoDuctile.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
source_damage_anisoBrittle.o: source_damage_anisoBrittle.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
source_damage_anisoDuctile.o: source_damage_anisoDuctile.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
source_vacancy_phenoplasticity.o: source_vacancy_phenoplasticity.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
source_vacancy_irradiation.o: source_vacancy_irradiation.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
source_vacancy_thermalfluc.o: source_vacancy_thermalfluc.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
kinematics_cleavage_opening.o: kinematics_cleavage_opening.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
kinematics_slipplane_opening.o: kinematics_slipplane_opening.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
kinematics_thermal_expansion.o: kinematics_thermal_expansion.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
kinematics_vacancy_strain.o: kinematics_vacancy_strain.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
|
kinematics_hydrogen_strain.o: kinematics_hydrogen_strain.f90 \
|
||||||
|
lattice.o
|
||||||
|
|
||||||
plastic_nonlocal.o: plastic_nonlocal.f90 \
|
plastic_nonlocal.o: plastic_nonlocal.f90 \
|
||||||
lattice.o
|
lattice.o
|
||||||
|
@ -457,39 +570,6 @@ plastic_j2.o: plastic_j2.f90 \
|
||||||
plastic_none.o: plastic_none.f90 \
|
plastic_none.o: plastic_none.f90 \
|
||||||
lattice.o
|
lattice.o
|
||||||
|
|
||||||
damage_none.o: damage_none.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
damage_isoBrittle.o: damage_isoBrittle.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
damage_isoDuctile.o: damage_isoDuctile.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
damage_anisoBrittle.o: damage_anisoBrittle.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
damage_anisoDuctile.o: damage_anisoDuctile.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
damage_phaseField.o: damage_phaseField.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
damage_gurson.o: damage_gurson.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
thermal_isothermal.o: thermal_isothermal.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
thermal_adiabatic.o: thermal_adiabatic.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
vacancy_constant.o: vacancy_constant.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
vacancy_generation.o: vacancy_generation.f90 \
|
|
||||||
lattice.o
|
|
||||||
|
|
||||||
lattice.o: lattice.f90 \
|
lattice.o: lattice.f90 \
|
||||||
material.o
|
material.o
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! $Id: libs.f90 3413 2014-08-24 22:07:53Z MPIE\m.diehl $
|
! $Id$
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @brief all DAMASK files without solver
|
!> @brief all DAMASK files without solver
|
||||||
|
@ -14,17 +14,19 @@
|
||||||
#include "mesh.f90"
|
#include "mesh.f90"
|
||||||
#include "material.f90"
|
#include "material.f90"
|
||||||
#include "lattice.f90"
|
#include "lattice.f90"
|
||||||
#include "damage_none.f90"
|
#include "source_thermal_dissipation.f90"
|
||||||
#include "damage_isoBrittle.f90"
|
#include "source_damage_isoBrittle.f90"
|
||||||
#include "damage_isoDuctile.f90"
|
#include "source_damage_isoDuctile.f90"
|
||||||
#include "damage_anisoBrittle.f90"
|
#include "source_damage_anisoBrittle.f90"
|
||||||
#include "damage_anisoDuctile.f90"
|
#include "source_damage_anisoDuctile.f90"
|
||||||
#include "damage_gurson.f90"
|
#include "source_vacancy_phenoplasticity.f90"
|
||||||
#include "damage_phaseField.f90"
|
#include "source_vacancy_irradiation.f90"
|
||||||
#include "thermal_isothermal.f90"
|
#include "source_vacancy_thermalfluc.f90"
|
||||||
#include "thermal_adiabatic.f90"
|
#include "kinematics_cleavage_opening.f90"
|
||||||
#include "vacancy_constant.f90"
|
#include "kinematics_slipplane_opening.f90"
|
||||||
#include "vacancy_generation.f90"
|
#include "kinematics_thermal_expansion.f90"
|
||||||
|
#include "kinematics_vacancy_strain.f90"
|
||||||
|
#include "kinematics_hydrogen_strain.f90"
|
||||||
#include "plastic_none.f90"
|
#include "plastic_none.f90"
|
||||||
#include "plastic_j2.f90"
|
#include "plastic_j2.f90"
|
||||||
#include "plastic_phenopowerlaw.f90"
|
#include "plastic_phenopowerlaw.f90"
|
||||||
|
@ -38,5 +40,18 @@
|
||||||
#include "homogenization_none.f90"
|
#include "homogenization_none.f90"
|
||||||
#include "homogenization_isostrain.f90"
|
#include "homogenization_isostrain.f90"
|
||||||
#include "homogenization_RGC.f90"
|
#include "homogenization_RGC.f90"
|
||||||
|
#include "thermal_isothermal.f90"
|
||||||
|
#include "thermal_adiabatic.f90"
|
||||||
|
#include "thermal_conduction.f90"
|
||||||
|
#include "damage_none.f90"
|
||||||
|
#include "damage_local.f90"
|
||||||
|
#include "damage_nonlocal.f90"
|
||||||
|
#include "vacancyflux_isoconc.f90"
|
||||||
|
#include "vacancyflux_isochempot.f90"
|
||||||
|
#include "vacancyflux_cahnhilliard.f90"
|
||||||
|
#include "porosity_none.f90"
|
||||||
|
#include "porosity_phasefield.f90"
|
||||||
|
#include "hydrogenflux_isoconc.f90"
|
||||||
|
#include "hydrogenflux_cahnhilliard.f90"
|
||||||
#include "homogenization.f90"
|
#include "homogenization.f90"
|
||||||
#include "CPFEM.f90"
|
#include "CPFEM.f90"
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
damage nonlocal
|
||||||
|
(output) damage
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
hydrogenflux cahnhilliard
|
||||||
|
(output) hydrogenconc
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
porosity phasefield
|
||||||
|
(output) porosity
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
thermal conduction
|
||||||
|
(output) temperature
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
vacancyflux cahnhilliard
|
||||||
|
(output) vacancyconc
|
|
@ -0,0 +1,9 @@
|
||||||
|
### $Id$ ###
|
||||||
|
[SX]
|
||||||
|
type isostrain
|
||||||
|
Ngrains 1
|
||||||
|
{./Homogenization_Damage_NonLocal.config}
|
||||||
|
{./Homogenization_Thermal_Conduction.config}
|
||||||
|
{./Homogenization_VacancyFlux_CahnHilliard.config}
|
||||||
|
{./Homogenization_Porosity_PhaseField.config}
|
||||||
|
{./Homogenization_HydrogenFlux_CahnHilliard.config}
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
(kinematics) vacancy_strain
|
||||||
|
vacancy_strain_coeff 0.006
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
(kinematics) thermal_expansion
|
||||||
|
thermal_expansion_coeff 0.00231
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
(kinematics) hydrogen_strain
|
||||||
|
hydrogen_strain_coeff 0.06
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
damage_diffusion11 1.0
|
||||||
|
damage_mobility 0.001
|
|
@ -0,0 +1,4 @@
|
||||||
|
### $Id$ ###
|
||||||
|
hydrogenflux_diffusion11 1.0
|
||||||
|
hydrogenflux_mobility11 1.0
|
||||||
|
hydrogenVolume 1e-28
|
|
@ -0,0 +1,62 @@
|
||||||
|
### $Id$ ###
|
||||||
|
[Aluminum]
|
||||||
|
elasticity hooke
|
||||||
|
plasticity phenopowerlaw
|
||||||
|
|
||||||
|
(output) resistance_slip
|
||||||
|
(output) shearrate_slip
|
||||||
|
(output) resolvedstress_slip
|
||||||
|
(output) accumulated_shear_slip
|
||||||
|
(output) totalshear
|
||||||
|
(output) resistance_twin
|
||||||
|
(output) shearrate_twin
|
||||||
|
(output) resolvedstress_twin
|
||||||
|
(output) accumulated_shear_twin
|
||||||
|
(output) totalvolfrac_twin
|
||||||
|
|
||||||
|
lattice_structure fcc
|
||||||
|
Nslip 12 # per family
|
||||||
|
Ntwin 0 # per family
|
||||||
|
|
||||||
|
c11 106.75e9
|
||||||
|
c12 60.41e9
|
||||||
|
c44 28.34e9
|
||||||
|
|
||||||
|
gdot0_slip 0.001
|
||||||
|
n_slip 20
|
||||||
|
tau0_slip 31e6 # per family
|
||||||
|
tausat_slip 63e6 # per family
|
||||||
|
a_slip 2.25
|
||||||
|
gdot0_twin 0.001
|
||||||
|
n_twin 20
|
||||||
|
tau0_twin 31e6 # per family
|
||||||
|
s_pr 0 # push-up factor for slip saturation due to twinning
|
||||||
|
twin_b 0
|
||||||
|
twin_c 0
|
||||||
|
twin_d 0
|
||||||
|
twin_e 0
|
||||||
|
h0_slipslip 75e6
|
||||||
|
h0_twinslip 0
|
||||||
|
h0_twintwin 0
|
||||||
|
interaction_slipslip 1 1 1.4 1.4 1.4 1.4
|
||||||
|
interaction_sliptwin 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||||
|
interaction_twinslip 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||||
|
interaction_twintwin 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
|
||||||
|
atol_resistance 1
|
||||||
|
|
||||||
|
(stiffness_degradation) damage
|
||||||
|
(stiffness_degradation) porosity
|
||||||
|
{./Phase_Damage.config}
|
||||||
|
{./Phase_Thermal.config}
|
||||||
|
{./Phase_Vacancy.config}
|
||||||
|
{./Phase_Porosity.config}
|
||||||
|
{./Phase_Hydrogen.config}
|
||||||
|
{./Source_Damage_IsoBrittle.config}
|
||||||
|
{./Source_Thermal_Dissipation.config}
|
||||||
|
{./Source_Vacancy_PhenoPlasticity.config}
|
||||||
|
{./Source_Vacancy_Irradiation.config}
|
||||||
|
{./Kinematics_Thermal_Expansion.config}
|
||||||
|
{./Kinematics_Vacancy_Strain.config}
|
||||||
|
{./Kinematics_Hydrogen_Strain.config}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
porosity_diffusion11 1.0
|
||||||
|
porosity_mobility 0.001
|
|
@ -0,0 +1,5 @@
|
||||||
|
### $Id$ ###
|
||||||
|
thermal_conductivity11 237.0
|
||||||
|
specific_heat 910.0
|
||||||
|
mass_density 2700.0
|
||||||
|
reference_temperature 300.0
|
|
@ -0,0 +1,6 @@
|
||||||
|
### $Id$ ###
|
||||||
|
vacancyflux_diffusion11 1.0
|
||||||
|
vacancyflux_mobility11 1.0
|
||||||
|
vacancyFormationEnergy 1e-19
|
||||||
|
voidSurfaceEnergy 1e+10
|
||||||
|
vacancyVolume 1e-28
|
|
@ -0,0 +1,5 @@
|
||||||
|
### $Id$ ###
|
||||||
|
(source) damage_isoBrittle
|
||||||
|
isobrittle_criticalStrainEnergy 1400000.0
|
||||||
|
isobrittle_atol 0.01
|
||||||
|
(output) isoBrittle_DrivingForce
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
(source) thermal_dissipation
|
||||||
|
dissipation_ColdWorkCoeff 0.95
|
|
@ -0,0 +1,4 @@
|
||||||
|
### $Id$ ###
|
||||||
|
(source) vacancy_irradiation
|
||||||
|
irradiation_cascadeprobability 0.00001
|
||||||
|
irradiation_cascadevolume 1000.0
|
|
@ -0,0 +1,3 @@
|
||||||
|
### $Id$ ###
|
||||||
|
(source) vacancy_phenoplasticity
|
||||||
|
phenoplasticity_ratecoeff 0.01
|
File diff suppressed because it is too large
Load Diff
1240
code/crystallite.f90
1240
code/crystallite.f90
File diff suppressed because it is too large
Load Diff
|
@ -1,635 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! $Id$
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Luv Sharma, Max-Planck-Institut fŸr Eisenforschung GmbH
|
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut fŸr Eisenforschung GmbH
|
|
||||||
!> @brief material subroutine incorporating anisotropic ductile damage
|
|
||||||
!> @details to be done
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module damage_anisoBrittle
|
|
||||||
use prec, only: &
|
|
||||||
pReal, &
|
|
||||||
pInt
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
private
|
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
|
||||||
damage_anisoBrittle_sizePostResults !< cumulative size of post results
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_anisoBrittle_sizePostResult !< size of each post result output
|
|
||||||
|
|
||||||
character(len=64), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_anisoBrittle_output !< name of each post result output
|
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, target, public :: &
|
|
||||||
damage_anisoBrittle_Noutput !< number of outputs per instance of this damage
|
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, private :: &
|
|
||||||
damage_anisoBrittle_totalNcleavage !< total number of cleavage systems
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_anisoBrittle_Ncleavage !< number of cleavage systems per family
|
|
||||||
|
|
||||||
real(pReal), dimension(:), allocatable, private :: &
|
|
||||||
damage_anisoBrittle_aTol_damage, &
|
|
||||||
damage_anisoBrittle_aTol_disp, &
|
|
||||||
damage_anisoBrittle_sdot_0, &
|
|
||||||
damage_anisoBrittle_N
|
|
||||||
|
|
||||||
real(pReal), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_anisoBrittle_critDisp, &
|
|
||||||
damage_anisoBrittle_critLoad
|
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: undefined_ID, &
|
|
||||||
local_damage_ID
|
|
||||||
end enum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11 ToDo
|
|
||||||
|
|
||||||
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_anisoBrittle_outputID !< ID of each post result output
|
|
||||||
|
|
||||||
|
|
||||||
public :: &
|
|
||||||
damage_anisoBrittle_init, &
|
|
||||||
damage_anisoBrittle_stateInit, &
|
|
||||||
damage_anisoBrittle_aTolState, &
|
|
||||||
damage_anisoBrittle_microstructure, &
|
|
||||||
damage_anisoBrittle_LdAndItsTangent, &
|
|
||||||
damage_anisoBrittle_getDamage, &
|
|
||||||
damage_anisoBrittle_putLocalDamage, &
|
|
||||||
damage_anisoBrittle_getLocalDamage, &
|
|
||||||
damage_anisoBrittle_getDamageDiffusion33, &
|
|
||||||
damage_anisoBrittle_postResults
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief module initialization
|
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoBrittle_init(fileUnit)
|
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
|
||||||
use debug, only: &
|
|
||||||
debug_level,&
|
|
||||||
debug_constitutive,&
|
|
||||||
debug_levelBasic
|
|
||||||
use IO, only: &
|
|
||||||
IO_read, &
|
|
||||||
IO_lc, &
|
|
||||||
IO_getTag, &
|
|
||||||
IO_isBlank, &
|
|
||||||
IO_stringPos, &
|
|
||||||
IO_stringValue, &
|
|
||||||
IO_floatValue, &
|
|
||||||
IO_intValue, &
|
|
||||||
IO_warning, &
|
|
||||||
IO_error, &
|
|
||||||
IO_timeStamp, &
|
|
||||||
IO_EOF
|
|
||||||
use material, only: &
|
|
||||||
phase_damage, &
|
|
||||||
phase_damageInstance, &
|
|
||||||
phase_Noutput, &
|
|
||||||
LOCAL_damage_anisoBrittle_label, &
|
|
||||||
LOCAL_damage_anisoBrittle_ID, &
|
|
||||||
material_phase, &
|
|
||||||
damageState, &
|
|
||||||
MATERIAL_partPhase
|
|
||||||
use numerics,only: &
|
|
||||||
worldrank, &
|
|
||||||
numerics_integrator
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_maxNcleavageFamily, &
|
|
||||||
lattice_NcleavageSystem
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: fileUnit
|
|
||||||
|
|
||||||
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
|
||||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
|
||||||
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,o
|
|
||||||
integer(pInt) :: sizeState, sizeDotState
|
|
||||||
integer(pInt) :: NofMyPhase
|
|
||||||
integer(pInt) :: Nchunks_CleavageFamilies = 0_pInt, j
|
|
||||||
character(len=65536) :: &
|
|
||||||
tag = '', &
|
|
||||||
line = ''
|
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
|
||||||
write(6,'(/,a)') ' <<<+- damage_'//LOCAL_damage_anisoBrittle_LABEL//' init -+>>>'
|
|
||||||
write(6,'(a)') ' $Id$'
|
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
|
||||||
#include "compilation_info.f90"
|
|
||||||
endif mainProcess
|
|
||||||
|
|
||||||
maxNinstance = int(count(phase_damage == LOCAL_damage_anisoBrittle_ID),pInt)
|
|
||||||
if (maxNinstance == 0_pInt) return
|
|
||||||
|
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
|
||||||
|
|
||||||
allocate(damage_anisoBrittle_sizePostResults(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_anisoBrittle_sizePostResult(maxval(phase_Noutput),maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_anisoBrittle_output(maxval(phase_Noutput),maxNinstance))
|
|
||||||
damage_anisoBrittle_output = ''
|
|
||||||
allocate(damage_anisoBrittle_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
|
||||||
allocate(damage_anisoBrittle_Noutput(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_anisoBrittle_critDisp(lattice_maxNcleavageFamily,maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_anisoBrittle_critLoad(lattice_maxNcleavageFamily,maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_anisoBrittle_Ncleavage(lattice_maxNcleavageFamily,maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_anisoBrittle_totalNcleavage(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_anisoBrittle_aTol_damage(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_anisoBrittle_aTol_disp(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_anisoBrittle_sdot_0(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_anisoBrittle_N(maxNinstance), source=0.0_pReal)
|
|
||||||
|
|
||||||
rewind(fileUnit)
|
|
||||||
phase = 0_pInt
|
|
||||||
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
if (IO_isBlank(line)) cycle ! skip empty lines
|
|
||||||
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
|
||||||
line = IO_read(fileUnit, .true.) ! reset IO_read
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
|
||||||
phase = phase + 1_pInt ! advance phase section counter
|
|
||||||
cycle ! skip to next line
|
|
||||||
endif
|
|
||||||
if (phase > 0_pInt ) then; if (phase_damage(phase) == LOCAL_damage_anisoBrittle_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
|
||||||
instance = phase_damageInstance(phase) ! which instance of my damage is present phase
|
|
||||||
positions = IO_stringPos(line,MAXNCHUNKS)
|
|
||||||
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
|
||||||
select case(tag)
|
|
||||||
case ('(output)')
|
|
||||||
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
|
||||||
case ('local_damage')
|
|
||||||
damage_anisoBrittle_Noutput(instance) = damage_anisoBrittle_Noutput(instance) + 1_pInt
|
|
||||||
damage_anisoBrittle_outputID(damage_anisoBrittle_Noutput(instance),instance) = local_damage_ID
|
|
||||||
damage_anisoBrittle_output(damage_anisoBrittle_Noutput(instance),instance) = &
|
|
||||||
IO_lc(IO_stringValue(line,positions,2_pInt))
|
|
||||||
end select
|
|
||||||
|
|
||||||
case ('atol_damage')
|
|
||||||
damage_anisoBrittle_aTol_damage(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('atol_disp')
|
|
||||||
damage_anisoBrittle_aTol_disp(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('sdot0')
|
|
||||||
damage_anisoBrittle_sdot_0(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('damageratesensitivity')
|
|
||||||
damage_anisoBrittle_N(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('ncleavage') !
|
|
||||||
Nchunks_CleavageFamilies = positions(1) - 1_pInt
|
|
||||||
do j = 1_pInt, Nchunks_CleavageFamilies
|
|
||||||
damage_anisoBrittle_Ncleavage(j,instance) = IO_intValue(line,positions,1_pInt+j)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
case ('criticaldisplacement')
|
|
||||||
do j = 1_pInt, Nchunks_CleavageFamilies
|
|
||||||
damage_anisoBrittle_critDisp(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
case ('criticalload')
|
|
||||||
do j = 1_pInt, Nchunks_CleavageFamilies
|
|
||||||
damage_anisoBrittle_critLoad(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
end select
|
|
||||||
endif; endif
|
|
||||||
enddo parsingFile
|
|
||||||
|
|
||||||
sanityChecks: do phase = 1_pInt, size(phase_damage)
|
|
||||||
myPhase: if (phase_damage(phase) == LOCAL_damage_anisoBrittle_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
! sanity checks
|
|
||||||
damage_anisoBrittle_Ncleavage(1:lattice_maxNcleavageFamily,instance) = &
|
|
||||||
min(lattice_NcleavageSystem(1:lattice_maxNcleavageFamily,phase),& ! limit active cleavage systems per family to min of available and requested
|
|
||||||
damage_anisoBrittle_Ncleavage(1:lattice_maxNcleavageFamily,instance))
|
|
||||||
damage_anisoBrittle_totalNcleavage(instance) = sum(damage_anisoBrittle_Ncleavage(:,instance)) ! how many cleavage systems altogether
|
|
||||||
if (damage_anisoBrittle_aTol_damage(instance) < 0.0_pReal) &
|
|
||||||
damage_anisoBrittle_aTol_damage(instance) = 1.0e-3_pReal ! default absolute tolerance 1e-3
|
|
||||||
if (damage_anisoBrittle_aTol_disp(instance) >= 1.0e-3_pReal) &
|
|
||||||
damage_anisoBrittle_aTol_disp(instance) = 1.0e-3_pReal ! default absolute tolerance 1e-3
|
|
||||||
if (damage_anisoBrittle_sdot_0(instance) <= 0.0_pReal) &
|
|
||||||
call IO_error(211_pInt,el=instance,ext_msg='sdot_0 ('//LOCAL_DAMAGE_anisoBrittle_LABEL//')')
|
|
||||||
if (any(damage_anisoBrittle_critDisp(1:Nchunks_CleavageFamilies,instance) < 0.0_pReal)) &
|
|
||||||
call IO_error(211_pInt,el=instance,ext_msg='critical_displacement ('//LOCAL_DAMAGE_anisoBrittle_LABEL//')')
|
|
||||||
if (any(damage_anisoBrittle_critLoad(1:Nchunks_CleavageFamilies,instance) < 0.0_pReal)) &
|
|
||||||
call IO_error(211_pInt,el=instance,ext_msg='critical_load ('//LOCAL_DAMAGE_anisoBrittle_LABEL//')')
|
|
||||||
if (damage_anisoBrittle_N(instance) <= 0.0_pReal) &
|
|
||||||
call IO_error(211_pInt,el=instance,ext_msg='rate_sensitivity_damage ('//LOCAL_DAMAGE_anisoBrittle_LABEL//')')
|
|
||||||
endif myPhase
|
|
||||||
enddo sanityChecks
|
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_damage)
|
|
||||||
if (phase_damage(phase) == LOCAL_damage_anisoBrittle_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! Determine size of postResults array
|
|
||||||
outputsLoop: do o = 1_pInt,damage_anisoBrittle_Noutput(instance)
|
|
||||||
select case(damage_anisoBrittle_outputID(o,instance))
|
|
||||||
case(local_damage_ID)
|
|
||||||
mySize = 1_pInt
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (mySize > 0_pInt) then ! any meaningful output found
|
|
||||||
damage_anisoBrittle_sizePostResult(o,instance) = mySize
|
|
||||||
damage_anisoBrittle_sizePostResults(instance) = damage_anisoBrittle_sizePostResults(instance) + mySize
|
|
||||||
endif
|
|
||||||
enddo outputsLoop
|
|
||||||
! Determine size of state array
|
|
||||||
sizeDotState = 0_pInt
|
|
||||||
sizeState = sizeDotState + &
|
|
||||||
1_pInt + & ! non-local damage
|
|
||||||
1_pInt ! opening on each damage system
|
|
||||||
|
|
||||||
damageState(phase)%sizeState = sizeState
|
|
||||||
damageState(phase)%sizeDotState = sizeDotState
|
|
||||||
damageState(phase)%sizePostResults = damage_anisoBrittle_sizePostResults(instance)
|
|
||||||
allocate(damageState(phase)%aTolState (sizeState), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
|
|
||||||
allocate(damageState(phase)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
|
||||||
allocate(damageState(phase)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
endif
|
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(damageState(phase)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
|
||||||
allocate(damageState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
|
||||||
|
|
||||||
call damage_anisoBrittle_stateInit(phase,instance)
|
|
||||||
call damage_anisoBrittle_aTolState(phase,instance)
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo initializeInstances
|
|
||||||
end subroutine damage_anisoBrittle_init
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoBrittle_stateInit(phase,instance)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
use math, only: &
|
|
||||||
math_I3
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: phase, instance !< number specifying the phase of the damage
|
|
||||||
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempState
|
|
||||||
|
|
||||||
tempState(1) = 1.0_pReal
|
|
||||||
tempState(2) = 1.0_pReal
|
|
||||||
|
|
||||||
damageState(phase)%state0 = spread(tempState,2,size(damageState(phase)%state(1,:)))
|
|
||||||
|
|
||||||
end subroutine damage_anisoBrittle_stateInit
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoBrittle_aTolState(phase,instance)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
phase, &
|
|
||||||
instance ! number specifying the current instance of the damage
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempTol
|
|
||||||
|
|
||||||
tempTol(1) = damage_anisoBrittle_aTol_damage(instance)
|
|
||||||
tempTol(2) = damage_anisoBrittle_aTol_disp (instance)
|
|
||||||
|
|
||||||
damageState(phase)%aTolState = tempTol
|
|
||||||
|
|
||||||
end subroutine damage_anisoBrittle_aTolState
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief calculates derived quantities from state
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoBrittle_microstructure(Tstar_v, subdt, ipc, ip, el)
|
|
||||||
use numerics, only: &
|
|
||||||
residualStiffness
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance, &
|
|
||||||
damageState
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_DamageMobility, &
|
|
||||||
lattice_Scleavage_v, &
|
|
||||||
lattice_maxNcleavageFamily, &
|
|
||||||
lattice_NcleavageSystem
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), intent(in), dimension(6) :: &
|
|
||||||
Tstar_v !< 2nd Piola Kirchhoff stress tensor (Mandel)
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
subdt
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, &
|
|
||||||
constituent, &
|
|
||||||
instance, &
|
|
||||||
f, i, index_myFamily
|
|
||||||
real(pReal) :: &
|
|
||||||
localDamage
|
|
||||||
real(pReal) :: &
|
|
||||||
traction_d, traction_t, traction_n, traction_crit
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
damageState(phase)%state(2,constituent) = damageState(phase)%subState0(2,constituent)
|
|
||||||
do f = 1_pInt,lattice_maxNcleavageFamily
|
|
||||||
index_myFamily = sum(lattice_NcleavageSystem(1:f-1_pInt,phase)) ! at which index starts my family
|
|
||||||
do i = 1_pInt,damage_anisoBrittle_Ncleavage(f,instance) ! process each (active) cleavage system in family
|
|
||||||
traction_d = dot_product(Tstar_v,lattice_Scleavage_v(1:6,1,index_myFamily+i,phase))
|
|
||||||
traction_t = dot_product(Tstar_v,lattice_Scleavage_v(1:6,2,index_myFamily+i,phase))
|
|
||||||
traction_n = dot_product(Tstar_v,lattice_Scleavage_v(1:6,3,index_myFamily+i,phase))
|
|
||||||
|
|
||||||
traction_crit = damage_anisoBrittle_critLoad(f,instance)* &
|
|
||||||
damage_anisoBrittle_getDamage(ipc, ip, el)
|
|
||||||
damageState(phase)%state(2,constituent) = &
|
|
||||||
damageState(phase)%state(2,constituent) + &
|
|
||||||
subdt*damage_anisoBrittle_sdot_0(instance)* &
|
|
||||||
((max(0.0_pReal, abs(traction_d) - traction_crit)/traction_crit)**damage_anisoBrittle_N(instance) + &
|
|
||||||
(max(0.0_pReal, abs(traction_t) - traction_crit)/traction_crit)**damage_anisoBrittle_N(instance) + &
|
|
||||||
(max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**damage_anisoBrittle_N(instance))/ &
|
|
||||||
damage_anisoBrittle_critDisp(f,instance)
|
|
||||||
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
localDamage = max(residualStiffness,1.0_pReal/damageState(phase)%state(2,constituent))
|
|
||||||
|
|
||||||
damageState(phase)%state(1,constituent) = &
|
|
||||||
localDamage + &
|
|
||||||
(damageState(phase)%subState0(1,constituent) - localDamage)* &
|
|
||||||
exp(-subdt/lattice_DamageMobility(phase))
|
|
||||||
|
|
||||||
end subroutine damage_anisoBrittle_microstructure
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief contains the constitutive equation for calculating the velocity gradient
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoBrittle_LdAndItsTangent(Ld, dLd_dTstar3333, Tstar_v, ipc, ip, el)
|
|
||||||
use prec, only: &
|
|
||||||
tol_math_check
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance
|
|
||||||
use math, only: &
|
|
||||||
math_Plain3333to99
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_Scleavage, &
|
|
||||||
lattice_Scleavage_v, &
|
|
||||||
lattice_maxNcleavageFamily, &
|
|
||||||
lattice_NcleavageSystem
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in), dimension(6) :: &
|
|
||||||
Tstar_v !< 2nd Piola-Kirchhoff stress
|
|
||||||
real(pReal), intent(out), dimension(3,3) :: &
|
|
||||||
Ld !< damage velocity gradient
|
|
||||||
real(pReal), intent(out), dimension(3,3,3,3) :: &
|
|
||||||
dLd_dTstar3333 !< derivative of Ld with respect to Tstar (4th-order tensor)
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, &
|
|
||||||
constituent, &
|
|
||||||
instance, &
|
|
||||||
f, i, index_myFamily, k, l, m, n
|
|
||||||
real(pReal) :: &
|
|
||||||
traction_d, traction_t, traction_n, traction_crit, &
|
|
||||||
udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
Ld = 0.0_pReal
|
|
||||||
dLd_dTstar3333 = 0.0_pReal
|
|
||||||
do f = 1_pInt,lattice_maxNcleavageFamily
|
|
||||||
index_myFamily = sum(lattice_NcleavageSystem(1:f-1_pInt,phase)) ! at which index starts my family
|
|
||||||
do i = 1_pInt,damage_anisoBrittle_Ncleavage(f,instance) ! process each (active) cleavage system in family
|
|
||||||
traction_d = dot_product(Tstar_v,lattice_Scleavage_v(1:6,1,index_myFamily+i,phase))
|
|
||||||
traction_t = dot_product(Tstar_v,lattice_Scleavage_v(1:6,2,index_myFamily+i,phase))
|
|
||||||
traction_n = dot_product(Tstar_v,lattice_Scleavage_v(1:6,3,index_myFamily+i,phase))
|
|
||||||
traction_crit = damage_anisoBrittle_critLoad(f,instance)* &
|
|
||||||
damage_anisoBrittle_getDamage(ipc, ip, el)
|
|
||||||
udotd = &
|
|
||||||
sign(1.0_pReal,traction_d)* &
|
|
||||||
damage_anisoBrittle_sdot_0(instance)* &
|
|
||||||
(max(0.0_pReal, abs(traction_d) - traction_crit)/traction_crit)**damage_anisoBrittle_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*damage_anisoBrittle_N(instance)/ &
|
|
||||||
max(0.0_pReal, abs(traction_d) - traction_crit)
|
|
||||||
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
|
||||||
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(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 = &
|
|
||||||
sign(1.0_pReal,traction_t)* &
|
|
||||||
damage_anisoBrittle_sdot_0(instance)* &
|
|
||||||
(max(0.0_pReal, abs(traction_t) - traction_crit)/traction_crit)**damage_anisoBrittle_N(instance)
|
|
||||||
if (abs(udott) > tol_math_check) then
|
|
||||||
Ld = Ld + udott*lattice_Scleavage(1:3,1:3,2,index_myFamily+i,phase)
|
|
||||||
dudott_dt = sign(1.0_pReal,traction_t)*udott*damage_anisoBrittle_N(instance)/ &
|
|
||||||
max(0.0_pReal, abs(traction_t) - traction_crit)
|
|
||||||
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
|
||||||
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(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 = &
|
|
||||||
sign(1.0_pReal,traction_n)* &
|
|
||||||
damage_anisoBrittle_sdot_0(instance)* &
|
|
||||||
(max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**damage_anisoBrittle_N(instance)
|
|
||||||
if (abs(udotn) > tol_math_check) then
|
|
||||||
Ld = Ld + udotn*lattice_Scleavage(1:3,1:3,3,index_myFamily+i,phase)
|
|
||||||
dudotn_dt = sign(1.0_pReal,traction_n)*udotn*damage_anisoBrittle_N(instance)/ &
|
|
||||||
max(0.0_pReal, abs(traction_n) - traction_crit)
|
|
||||||
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
|
||||||
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(k,l,m,n) + &
|
|
||||||
dudotn_dt*lattice_Scleavage(k,l,3,index_myFamily+i,phase)* &
|
|
||||||
lattice_Scleavage(m,n,3,index_myFamily+i,phase)
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
end subroutine damage_anisoBrittle_LdAndItsTangent
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_anisoBrittle_getDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
material_homog, &
|
|
||||||
mappingHomogenization, &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState, &
|
|
||||||
fieldDamage, &
|
|
||||||
field_damage_type, &
|
|
||||||
FIELD_DAMAGE_LOCAL_ID, &
|
|
||||||
FIELD_DAMAGE_NONLOCAL_ID
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: damage_anisoBrittle_getDamage
|
|
||||||
|
|
||||||
select case(field_damage_type(material_homog(ip,el)))
|
|
||||||
case default
|
|
||||||
damage_anisoBrittle_getDamage = damageState(mappingConstitutive(2,ipc,ip,el))% &
|
|
||||||
state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
case (FIELD_DAMAGE_NONLOCAL_ID)
|
|
||||||
damage_anisoBrittle_getDamage = fieldDamage(material_homog(ip,el))% &
|
|
||||||
field(1,mappingHomogenization(1,ip,el)) ! Taylor type
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
end function damage_anisoBrittle_getDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns damage value based on local damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoBrittle_putLocalDamage(ipc, ip, el, localDamage)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
localDamage
|
|
||||||
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el)) = &
|
|
||||||
localDamage
|
|
||||||
|
|
||||||
end subroutine damage_anisoBrittle_putLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns local damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_anisoBrittle_getLocalDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: &
|
|
||||||
damage_anisoBrittle_getLocalDamage
|
|
||||||
|
|
||||||
damage_anisoBrittle_getLocalDamage = &
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
end function damage_anisoBrittle_getLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns brittle damage diffusion tensor
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_anisoBrittle_getDamageDiffusion33(ipc, ip, el)
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_DamageDiffusion33
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), dimension(3,3) :: &
|
|
||||||
damage_anisoBrittle_getDamageDiffusion33
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
damage_anisoBrittle_getDamageDiffusion33 = &
|
|
||||||
lattice_DamageDiffusion33(1:3,1:3,phase)
|
|
||||||
|
|
||||||
end function damage_anisoBrittle_getDamageDiffusion33
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief return array of constitutive results
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function damage_anisoBrittle_postResults(ipc,ip,el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), dimension(damage_anisoBrittle_sizePostResults(phase_damageInstance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
|
||||||
damage_anisoBrittle_postResults
|
|
||||||
|
|
||||||
integer(pInt) :: &
|
|
||||||
instance, phase, constituent, o, c
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
c = 0_pInt
|
|
||||||
damage_anisoBrittle_postResults = 0.0_pReal
|
|
||||||
|
|
||||||
do o = 1_pInt,damage_anisoBrittle_Noutput(instance)
|
|
||||||
select case(damage_anisoBrittle_outputID(o,instance))
|
|
||||||
case (local_damage_ID)
|
|
||||||
damage_anisoBrittle_postResults(c+1_pInt) = &
|
|
||||||
damage_anisoBrittle_getLocalDamage(ipc, ip, el)
|
|
||||||
c = c + 1_pInt
|
|
||||||
|
|
||||||
end select
|
|
||||||
enddo
|
|
||||||
end function damage_anisoBrittle_postResults
|
|
||||||
|
|
||||||
end module damage_anisoBrittle
|
|
|
@ -1,608 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! $Id$
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Luv Sharma, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @brief material subroutine incorporating anisotropic ductile damage
|
|
||||||
!> @details to be done
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module damage_anisoDuctile
|
|
||||||
use prec, only: &
|
|
||||||
pReal, &
|
|
||||||
pInt
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
private
|
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
|
||||||
damage_anisoDuctile_sizePostResults !< cumulative size of post results
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_anisoDuctile_sizePostResult !< size of each post result output
|
|
||||||
|
|
||||||
character(len=64), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_anisoDuctile_output !< name of each post result output
|
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, target, public :: &
|
|
||||||
damage_anisoDuctile_Noutput !< number of outputs per instance of this damage
|
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, private :: &
|
|
||||||
damage_anisoDuctile_totalNslip !< total number of slip systems
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_anisoDuctile_Nslip !< number of slip systems per family
|
|
||||||
|
|
||||||
real(pReal), dimension(:), allocatable, private :: &
|
|
||||||
damage_anisoDuctile_aTol_damage
|
|
||||||
|
|
||||||
real(pReal), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_anisoDuctile_critPlasticStrain
|
|
||||||
|
|
||||||
real(pReal), dimension(:), allocatable, private :: &
|
|
||||||
damage_anisoDuctile_sdot_0, &
|
|
||||||
damage_anisoDuctile_N
|
|
||||||
|
|
||||||
real(pReal), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_anisoDuctile_critLoad
|
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: undefined_ID, &
|
|
||||||
local_damage_ID
|
|
||||||
end enum
|
|
||||||
|
|
||||||
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_anisoDuctile_outputID !< ID of each post result output
|
|
||||||
|
|
||||||
|
|
||||||
public :: &
|
|
||||||
damage_anisoDuctile_init, &
|
|
||||||
damage_anisoDuctile_stateInit, &
|
|
||||||
damage_anisoDuctile_aTolState, &
|
|
||||||
damage_anisoDuctile_microstructure, &
|
|
||||||
damage_anisoDuctile_LdAndItsTangent, &
|
|
||||||
damage_anisoDuctile_getDamage, &
|
|
||||||
damage_anisoDuctile_putLocalDamage, &
|
|
||||||
damage_anisoDuctile_getLocalDamage, &
|
|
||||||
damage_anisoDuctile_postResults
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief module initialization
|
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoDuctile_init(fileUnit)
|
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
|
||||||
use debug, only: &
|
|
||||||
debug_level,&
|
|
||||||
debug_constitutive,&
|
|
||||||
debug_levelBasic
|
|
||||||
use IO, only: &
|
|
||||||
IO_read, &
|
|
||||||
IO_lc, &
|
|
||||||
IO_getTag, &
|
|
||||||
IO_isBlank, &
|
|
||||||
IO_stringPos, &
|
|
||||||
IO_stringValue, &
|
|
||||||
IO_floatValue, &
|
|
||||||
IO_intValue, &
|
|
||||||
IO_warning, &
|
|
||||||
IO_error, &
|
|
||||||
IO_timeStamp, &
|
|
||||||
IO_EOF
|
|
||||||
use material, only: &
|
|
||||||
phase_damage, &
|
|
||||||
phase_damageInstance, &
|
|
||||||
phase_Noutput, &
|
|
||||||
LOCAL_damage_anisoDuctile_label, &
|
|
||||||
LOCAL_damage_anisoDuctile_ID, &
|
|
||||||
material_phase, &
|
|
||||||
damageState, &
|
|
||||||
MATERIAL_partPhase
|
|
||||||
use numerics,only: &
|
|
||||||
worldrank, &
|
|
||||||
numerics_integrator
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_maxNslipFamily, &
|
|
||||||
lattice_NslipSystem
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: fileUnit
|
|
||||||
|
|
||||||
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
|
||||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
|
||||||
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,o
|
|
||||||
integer(pInt) :: sizeState, sizeDotState
|
|
||||||
integer(pInt) :: NofMyPhase
|
|
||||||
integer(pInt) :: Nchunks_SlipFamilies = 0_pInt, j
|
|
||||||
character(len=65536) :: &
|
|
||||||
tag = '', &
|
|
||||||
line = ''
|
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
|
||||||
write(6,'(/,a)') ' <<<+- damage_'//LOCAL_damage_anisoDuctile_LABEL//' init -+>>>'
|
|
||||||
write(6,'(a)') ' $Id$'
|
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
|
||||||
#include "compilation_info.f90"
|
|
||||||
endif mainProcess
|
|
||||||
|
|
||||||
maxNinstance = int(count(phase_damage == LOCAL_damage_anisoDuctile_ID),pInt)
|
|
||||||
if (maxNinstance == 0_pInt) return
|
|
||||||
|
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
|
||||||
|
|
||||||
allocate(damage_anisoDuctile_sizePostResults(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_anisoDuctile_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
|
||||||
allocate(damage_anisoDuctile_output(maxval(phase_Noutput),maxNinstance))
|
|
||||||
damage_anisoDuctile_output = ''
|
|
||||||
allocate(damage_anisoDuctile_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
|
||||||
allocate(damage_anisoDuctile_Noutput(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_anisoDuctile_critLoad(lattice_maxNslipFamily,maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_anisoDuctile_critPlasticStrain(lattice_maxNslipFamily,maxNinstance),source=0.0_pReal)
|
|
||||||
allocate(damage_anisoDuctile_Nslip(lattice_maxNslipFamily,maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_anisoDuctile_totalNslip(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_anisoDuctile_N(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_anisoDuctile_sdot_0(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_anisoDuctile_aTol_damage(maxNinstance), source=0.0_pReal)
|
|
||||||
|
|
||||||
rewind(fileUnit)
|
|
||||||
phase = 0_pInt
|
|
||||||
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
if (IO_isBlank(line)) cycle ! skip empty lines
|
|
||||||
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
|
||||||
line = IO_read(fileUnit, .true.) ! reset IO_read
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
|
||||||
phase = phase + 1_pInt ! advance phase section counter
|
|
||||||
cycle ! skip to next line
|
|
||||||
endif
|
|
||||||
if (phase > 0_pInt ) then; if (phase_damage(phase) == LOCAL_damage_anisoDuctile_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
|
||||||
instance = phase_damageInstance(phase) ! which instance of my damage is present phase
|
|
||||||
positions = IO_stringPos(line,MAXNCHUNKS)
|
|
||||||
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
|
||||||
select case(tag)
|
|
||||||
case ('(output)')
|
|
||||||
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
|
||||||
case ('local_damage')
|
|
||||||
damage_anisoDuctile_Noutput(instance) = damage_anisoDuctile_Noutput(instance) + 1_pInt
|
|
||||||
damage_anisoDuctile_outputID(damage_anisoDuctile_Noutput(instance),instance) = local_damage_ID
|
|
||||||
damage_anisoDuctile_output(damage_anisoDuctile_Noutput(instance),instance) = &
|
|
||||||
IO_lc(IO_stringValue(line,positions,2_pInt))
|
|
||||||
end select
|
|
||||||
|
|
||||||
case ('atol_damage')
|
|
||||||
damage_anisoDuctile_aTol_damage(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('nslip') !
|
|
||||||
Nchunks_SlipFamilies = positions(1) - 1_pInt
|
|
||||||
do j = 1_pInt, Nchunks_SlipFamilies
|
|
||||||
damage_anisoDuctile_Nslip(j,instance) = IO_intValue(line,positions,1_pInt+j)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
case ('sdot0')
|
|
||||||
damage_anisoDuctile_sdot_0(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('criticalplasticstrain')
|
|
||||||
do j = 1_pInt, Nchunks_SlipFamilies
|
|
||||||
damage_anisoDuctile_critPlasticStrain(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
case ('damageratesensitivity')
|
|
||||||
damage_anisoDuctile_N(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('criticalload')
|
|
||||||
do j = 1_pInt, Nchunks_SlipFamilies
|
|
||||||
damage_anisoDuctile_critLoad(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
end select
|
|
||||||
endif; endif
|
|
||||||
enddo parsingFile
|
|
||||||
|
|
||||||
sanityChecks: do phase = 1_pInt, size(phase_damage)
|
|
||||||
myPhase: if (phase_damage(phase) == LOCAL_damage_anisoDuctile_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
! sanity checks
|
|
||||||
damage_anisoDuctile_Nslip(1:lattice_maxNslipFamily,instance) = &
|
|
||||||
min(lattice_NslipSystem(1:lattice_maxNslipFamily,phase),& ! limit active cleavage systems per family to min of available and requested
|
|
||||||
damage_anisoDuctile_Nslip(1:lattice_maxNslipFamily,instance))
|
|
||||||
damage_anisoDuctile_totalNslip(instance) = sum(damage_anisoDuctile_Nslip(:,instance))
|
|
||||||
if (damage_anisoDuctile_aTol_damage(instance) < 0.0_pReal) &
|
|
||||||
damage_anisoDuctile_aTol_damage(instance) = 1.0e-3_pReal ! default absolute tolerance 1e-3
|
|
||||||
if (damage_anisoDuctile_sdot_0(instance) <= 0.0_pReal) &
|
|
||||||
call IO_error(211_pInt,el=instance,ext_msg='sdot_0 ('//LOCAL_DAMAGE_anisoDuctile_LABEL//')')
|
|
||||||
if (any(damage_anisoDuctile_critPlasticStrain(:,instance) < 0.0_pReal)) &
|
|
||||||
call IO_error(211_pInt,el=instance,ext_msg='criticaPlasticStrain ('//LOCAL_DAMAGE_anisoDuctile_LABEL//')')
|
|
||||||
if (damage_anisoDuctile_N(instance) <= 0.0_pReal) &
|
|
||||||
call IO_error(211_pInt,el=instance,ext_msg='rate_sensitivity_damage ('//LOCAL_DAMAGE_anisoDuctile_LABEL//')')
|
|
||||||
endif myPhase
|
|
||||||
enddo sanityChecks
|
|
||||||
|
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_damage)
|
|
||||||
if (phase_damage(phase) == LOCAL_damage_anisoDuctile_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! Determine size of postResults array
|
|
||||||
outputsLoop: do o = 1_pInt,damage_anisoDuctile_Noutput(instance)
|
|
||||||
select case(damage_anisoDuctile_outputID(o,instance))
|
|
||||||
case(local_damage_ID)
|
|
||||||
mySize = 1_pInt
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (mySize > 0_pInt) then ! any meaningful output found
|
|
||||||
damage_anisoDuctile_sizePostResult(o,instance) = mySize
|
|
||||||
damage_anisoDuctile_sizePostResults(instance) = damage_anisoDuctile_sizePostResults(instance) + mySize
|
|
||||||
endif
|
|
||||||
enddo outputsLoop
|
|
||||||
! Determine size of state array
|
|
||||||
sizeDotState = 0_pInt
|
|
||||||
sizeState = sizeDotState + &
|
|
||||||
1_pInt + & ! time regularised damage
|
|
||||||
1_pInt ! damaged plasticity
|
|
||||||
damageState(phase)%sizeState = sizeState
|
|
||||||
damageState(phase)%sizeDotState = sizeDotState
|
|
||||||
damageState(phase)%sizePostResults = damage_anisoDuctile_sizePostResults(instance)
|
|
||||||
allocate(damageState(phase)%aTolState (sizeState), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
|
|
||||||
allocate(damageState(phase)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
|
||||||
allocate(damageState(phase)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
endif
|
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(damageState(phase)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
|
||||||
allocate(damageState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
|
||||||
call damage_anisoDuctile_stateInit(phase,instance)
|
|
||||||
call damage_anisoDuctile_aTolState(phase,instance)
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo initializeInstances
|
|
||||||
end subroutine damage_anisoDuctile_init
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoDuctile_stateInit(phase, instance)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
use math, only: &
|
|
||||||
math_I3
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: phase , instance !< number specifying the phase of the damage
|
|
||||||
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempState
|
|
||||||
|
|
||||||
tempState(1) = 1.0_pReal
|
|
||||||
tempState(2) = 0.0_pReal
|
|
||||||
|
|
||||||
damageState(phase)%state0 = spread(tempState,2,size(damageState(phase)%state(1,:)))
|
|
||||||
|
|
||||||
end subroutine damage_anisoDuctile_stateInit
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoDuctile_aTolState(phase,instance)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
phase, &
|
|
||||||
instance ! number specifying the current instance of the damage
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempTol
|
|
||||||
|
|
||||||
tempTol = damage_anisoDuctile_aTol_damage(instance)
|
|
||||||
damageState(phase)%aTolState = tempTol
|
|
||||||
|
|
||||||
end subroutine damage_anisoDuctile_aTolState
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief calculates derived quantities from state
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoDuctile_microstructure(subdt, ipc, ip, el)
|
|
||||||
use numerics, only: &
|
|
||||||
residualStiffness
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance, &
|
|
||||||
plasticState, &
|
|
||||||
damageState
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_maxNslipFamily, &
|
|
||||||
lattice_DamageMobility
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
subdt
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, &
|
|
||||||
constituent, &
|
|
||||||
instance, &
|
|
||||||
index, f, i
|
|
||||||
real(pReal) :: &
|
|
||||||
localDamage
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
index = 1_pInt
|
|
||||||
damageState(phase)%state(2,constituent) = damageState(phase)%subState0(2,constituent)
|
|
||||||
do f = 1_pInt,lattice_maxNslipFamily
|
|
||||||
do i = 1_pInt,damage_anisoDuctile_Nslip(f,instance) ! process each (active) slip system in family
|
|
||||||
damageState(phase)%state(2,constituent) = &
|
|
||||||
damageState(phase)%state(2,constituent) + &
|
|
||||||
subdt* &
|
|
||||||
plasticState(phase)%slipRate(index,constituent)/ &
|
|
||||||
(damage_anisoDuctile_getDamage(ipc, ip, el)**damage_anisoDuctile_N(instance))/ &
|
|
||||||
damage_anisoDuctile_critPlasticStrain(f,instance)
|
|
||||||
|
|
||||||
index = index + 1_pInt
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
localDamage = &
|
|
||||||
max(residualStiffness,min(1.0_pReal,1.0_pReal/damageState(phase)%state(2,constituent)))
|
|
||||||
|
|
||||||
damageState(phase)%state(1,constituent) = &
|
|
||||||
localDamage + &
|
|
||||||
(damageState(phase)%subState0(1,constituent) - localDamage)* &
|
|
||||||
exp(-subdt/lattice_DamageMobility(phase))
|
|
||||||
|
|
||||||
end subroutine damage_anisoDuctile_microstructure
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief contains the constitutive equation for calculating the velocity gradient
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoDuctile_LdAndItsTangent(Ld, dLd_dTstar3333, Tstar_v, ipc, ip, el)
|
|
||||||
use prec, only: &
|
|
||||||
tol_math_check
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_maxNslipFamily, &
|
|
||||||
lattice_NslipSystem, &
|
|
||||||
lattice_sd, &
|
|
||||||
lattice_st, &
|
|
||||||
lattice_sn
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance
|
|
||||||
use math, only: &
|
|
||||||
math_Plain3333to99, &
|
|
||||||
math_I3, &
|
|
||||||
math_identity4th, &
|
|
||||||
math_symmetric33, &
|
|
||||||
math_Mandel33to6, &
|
|
||||||
math_tensorproduct, &
|
|
||||||
math_det33, &
|
|
||||||
math_mul33x33
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in), dimension(6) :: &
|
|
||||||
Tstar_v !< 2nd Piola-Kirchhoff stress
|
|
||||||
real(pReal), intent(out), dimension(3,3) :: &
|
|
||||||
Ld !< damage velocity gradient
|
|
||||||
real(pReal), intent(out), dimension(3,3,3,3) :: &
|
|
||||||
dLd_dTstar3333 !< 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
|
|
||||||
real(pReal), dimension(6) :: &
|
|
||||||
projection_d_v, projection_t_v, projection_n_v !< projection modes 3x3 vector
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, &
|
|
||||||
constituent, &
|
|
||||||
instance, &
|
|
||||||
f, i, index_myFamily, k, l, m, n
|
|
||||||
real(pReal) :: &
|
|
||||||
traction_d, traction_t, traction_n, traction_crit, &
|
|
||||||
udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
Ld = 0.0_pReal
|
|
||||||
dLd_dTstar3333 = 0.0_pReal
|
|
||||||
do f = 1_pInt,lattice_maxNslipFamily
|
|
||||||
index_myFamily = sum(lattice_NslipSystem(1:f-1_pInt,phase)) ! at which index starts my family
|
|
||||||
do i = 1_pInt,damage_anisoDuctile_Nslip(f,instance) ! process each (active) slip system in family
|
|
||||||
projection_d = math_tensorproduct(lattice_sd(1:3,index_myFamily+i,phase),&
|
|
||||||
lattice_sn(1:3,index_myFamily+i,phase))
|
|
||||||
projection_t = math_tensorproduct(lattice_st(1:3,index_myFamily+i,phase),&
|
|
||||||
lattice_sn(1:3,index_myFamily+i,phase))
|
|
||||||
projection_n = math_tensorproduct(lattice_sn(1:3,index_myFamily+i,phase),&
|
|
||||||
lattice_sn(1:3,index_myFamily+i,phase))
|
|
||||||
|
|
||||||
projection_d_v(1:6) = math_Mandel33to6(math_symmetric33(projection_d(1:3,1:3)))
|
|
||||||
projection_t_v(1:6) = math_Mandel33to6(math_symmetric33(projection_t(1:3,1:3)))
|
|
||||||
projection_n_v(1:6) = math_Mandel33to6(math_symmetric33(projection_n(1:3,1:3)))
|
|
||||||
|
|
||||||
traction_d = dot_product(Tstar_v,projection_d_v(1:6))
|
|
||||||
traction_t = dot_product(Tstar_v,projection_t_v(1:6))
|
|
||||||
traction_n = dot_product(Tstar_v,projection_n_v(1:6))
|
|
||||||
|
|
||||||
traction_crit = damage_anisoDuctile_critLoad(f,instance)* &
|
|
||||||
damage_anisoDuctile_getDamage(ipc, ip, el) ! degrading critical load carrying capacity by damage
|
|
||||||
|
|
||||||
udotd = &
|
|
||||||
sign(1.0_pReal,traction_d)* &
|
|
||||||
damage_anisoDuctile_sdot_0(instance)* &
|
|
||||||
(abs(traction_d)/traction_crit - &
|
|
||||||
abs(traction_d)/damage_anisoDuctile_critLoad(f,instance))**damage_anisoDuctile_N(instance)
|
|
||||||
if (abs(udotd) > tol_math_check) then
|
|
||||||
Ld = Ld + udotd*projection_d
|
|
||||||
dudotd_dt = udotd*damage_anisoDuctile_N(instance)/traction_d
|
|
||||||
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
|
||||||
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(k,l,m,n) + &
|
|
||||||
dudotd_dt*projection_d(k,l)*projection_d(m,n)
|
|
||||||
endif
|
|
||||||
|
|
||||||
udott = &
|
|
||||||
sign(1.0_pReal,traction_t)* &
|
|
||||||
damage_anisoDuctile_sdot_0(instance)* &
|
|
||||||
(abs(traction_t)/traction_crit - &
|
|
||||||
abs(traction_t)/damage_anisoDuctile_critLoad(f,instance))**damage_anisoDuctile_N(instance)
|
|
||||||
if (abs(udott) > tol_math_check) then
|
|
||||||
Ld = Ld + udott*projection_t
|
|
||||||
dudott_dt = udott*damage_anisoDuctile_N(instance)/traction_t
|
|
||||||
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
|
||||||
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(k,l,m,n) + &
|
|
||||||
dudott_dt*projection_t(k,l)*projection_t(m,n)
|
|
||||||
endif
|
|
||||||
udotn = &
|
|
||||||
damage_anisoDuctile_sdot_0(instance)* &
|
|
||||||
(max(0.0_pReal,traction_n)/traction_crit - &
|
|
||||||
max(0.0_pReal,traction_n)/damage_anisoDuctile_critLoad(f,instance))**damage_anisoDuctile_N(instance)
|
|
||||||
if (abs(udotn) > tol_math_check) then
|
|
||||||
Ld = Ld + udotn*projection_n
|
|
||||||
dudotn_dt = udotn*damage_anisoDuctile_N(instance)/traction_n
|
|
||||||
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
|
||||||
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(k,l,m,n) + &
|
|
||||||
dudotn_dt*projection_n(k,l)*projection_n(m,n)
|
|
||||||
endif
|
|
||||||
enddo
|
|
||||||
enddo
|
|
||||||
|
|
||||||
end subroutine damage_anisoDuctile_LdAndItsTangent
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_anisoDuctile_getDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
material_homog, &
|
|
||||||
mappingHomogenization, &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState, &
|
|
||||||
fieldDamage, &
|
|
||||||
field_damage_type, &
|
|
||||||
FIELD_DAMAGE_LOCAL_ID, &
|
|
||||||
FIELD_DAMAGE_NONLOCAL_ID
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: damage_anisoDuctile_getDamage
|
|
||||||
|
|
||||||
select case(field_damage_type(material_homog(ip,el)))
|
|
||||||
case default
|
|
||||||
damage_anisoDuctile_getDamage = damageState(mappingConstitutive(2,ipc,ip,el))% &
|
|
||||||
state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
case (FIELD_DAMAGE_NONLOCAL_ID)
|
|
||||||
damage_anisoDuctile_getDamage = fieldDamage(material_homog(ip,el))% &
|
|
||||||
field(1,mappingHomogenization(1,ip,el)) ! Taylor type
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
end function damage_anisoDuctile_getDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns damage value based on local damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_anisoDuctile_putLocalDamage(ipc, ip, el, localDamage)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
localDamage
|
|
||||||
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el)) = &
|
|
||||||
localDamage
|
|
||||||
|
|
||||||
end subroutine damage_anisoDuctile_putLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns local damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_anisoDuctile_getLocalDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: &
|
|
||||||
damage_anisoDuctile_getLocalDamage
|
|
||||||
|
|
||||||
damage_anisoDuctile_getLocalDamage = &
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
end function damage_anisoDuctile_getLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief return array of constitutive results
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function damage_anisoDuctile_postResults(ipc,ip,el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), dimension(damage_anisoDuctile_sizePostResults(phase_damageInstance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
|
||||||
damage_anisoDuctile_postResults
|
|
||||||
|
|
||||||
integer(pInt) :: &
|
|
||||||
instance, phase, constituent, o, c
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
c = 0_pInt
|
|
||||||
damage_anisoDuctile_postResults = 0.0_pReal
|
|
||||||
|
|
||||||
do o = 1_pInt,damage_anisoDuctile_Noutput(instance)
|
|
||||||
select case(damage_anisoDuctile_outputID(o,instance))
|
|
||||||
case (local_damage_ID)
|
|
||||||
damage_anisoDuctile_postResults(c+1_pInt) = &
|
|
||||||
damage_anisoDuctile_getLocalDamage(ipc, ip, el)
|
|
||||||
c = c + 1_pInt
|
|
||||||
|
|
||||||
end select
|
|
||||||
enddo
|
|
||||||
end function damage_anisoDuctile_postResults
|
|
||||||
|
|
||||||
end module damage_anisoDuctile
|
|
|
@ -1,503 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! $Id$
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Luv Sharma, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @brief material subroutine incoprorating gurson damage
|
|
||||||
!> @details to be done
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module damage_gurson
|
|
||||||
use prec, only: &
|
|
||||||
pReal, &
|
|
||||||
pInt
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
private
|
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
|
||||||
damage_gurson_sizePostResults !< cumulative size of post results
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_gurson_sizePostResult !< size of each post result output
|
|
||||||
|
|
||||||
character(len=64), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_gurson_output !< name of each post result output
|
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, target, public :: &
|
|
||||||
damage_gurson_Noutput !< number of outputs per instance of this damage
|
|
||||||
|
|
||||||
real(pReal), dimension(:), allocatable, private :: &
|
|
||||||
damage_gurson_aTol, &
|
|
||||||
damage_gurson_coeff_torsion, &
|
|
||||||
damage_gurson_coeff_ten_comp, &
|
|
||||||
damage_gurson_coeff_triaxiality, &
|
|
||||||
damage_gurson_fracture_tough, &
|
|
||||||
damage_gurson_lengthscale, &
|
|
||||||
damage_gurson_crit_void_fraction
|
|
||||||
|
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: undefined_ID, &
|
|
||||||
local_damage_ID
|
|
||||||
end enum !!!!! ToDo
|
|
||||||
|
|
||||||
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_gurson_outputID !< ID of each post result output
|
|
||||||
|
|
||||||
|
|
||||||
public :: &
|
|
||||||
damage_gurson_init, &
|
|
||||||
damage_gurson_stateInit, &
|
|
||||||
damage_gurson_aTolState, &
|
|
||||||
damage_gurson_dotState, &
|
|
||||||
damage_gurson_microstructure, &
|
|
||||||
damage_gurson_getDamage, &
|
|
||||||
damage_gurson_getSlipDamage, &
|
|
||||||
damage_gurson_putLocalDamage, &
|
|
||||||
damage_gurson_getLocalDamage, &
|
|
||||||
damage_gurson_postResults
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief module initialization
|
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_gurson_init(fileUnit)
|
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
|
||||||
use debug, only: &
|
|
||||||
debug_level,&
|
|
||||||
debug_constitutive,&
|
|
||||||
debug_levelBasic
|
|
||||||
use IO, only: &
|
|
||||||
IO_read, &
|
|
||||||
IO_lc, &
|
|
||||||
IO_getTag, &
|
|
||||||
IO_isBlank, &
|
|
||||||
IO_stringPos, &
|
|
||||||
IO_stringValue, &
|
|
||||||
IO_floatValue, &
|
|
||||||
IO_intValue, &
|
|
||||||
IO_warning, &
|
|
||||||
IO_error, &
|
|
||||||
IO_timeStamp, &
|
|
||||||
IO_EOF
|
|
||||||
use material, only: &
|
|
||||||
phase_damage, &
|
|
||||||
phase_damageInstance, &
|
|
||||||
phase_Noutput, &
|
|
||||||
LOCAL_DAMAGE_gurson_label, &
|
|
||||||
LOCAL_DAMAGE_gurson_ID, &
|
|
||||||
material_phase, &
|
|
||||||
damageState, &
|
|
||||||
MATERIAL_partPhase
|
|
||||||
use numerics,only: &
|
|
||||||
worldrank, &
|
|
||||||
numerics_integrator
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: fileUnit
|
|
||||||
|
|
||||||
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
|
||||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
|
||||||
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,o
|
|
||||||
integer(pInt) :: sizeState, sizeDotState
|
|
||||||
integer(pInt) :: NofMyPhase
|
|
||||||
character(len=65536) :: &
|
|
||||||
tag = '', &
|
|
||||||
line = ''
|
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
|
||||||
write(6,'(/,a)') ' <<<+- damage_'//LOCAL_DAMAGE_gurson_LABEL//' init -+>>>'
|
|
||||||
write(6,'(a)') ' $Id$'
|
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
|
||||||
#include "compilation_info.f90"
|
|
||||||
endif mainProcess
|
|
||||||
|
|
||||||
maxNinstance = int(count(phase_damage == LOCAL_DAMAGE_gurson_ID),pInt)
|
|
||||||
if (maxNinstance == 0_pInt) return
|
|
||||||
|
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
|
||||||
|
|
||||||
allocate(damage_gurson_sizePostResults(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_gurson_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
|
||||||
allocate(damage_gurson_output(maxval(phase_Noutput),maxNinstance))
|
|
||||||
damage_gurson_output = ''
|
|
||||||
allocate(damage_gurson_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
|
||||||
allocate(damage_gurson_Noutput(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_gurson_coeff_torsion(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_gurson_coeff_ten_comp(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_gurson_coeff_triaxiality(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_gurson_fracture_tough(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_gurson_lengthscale(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_gurson_crit_void_fraction(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_gurson_aTol(maxNinstance), source=0.0_pReal)
|
|
||||||
|
|
||||||
rewind(fileUnit)
|
|
||||||
phase = 0_pInt
|
|
||||||
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
if (IO_isBlank(line)) cycle ! skip empty lines
|
|
||||||
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
|
||||||
line = IO_read(fileUnit, .true.) ! reset IO_read
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
|
||||||
phase = phase + 1_pInt ! advance phase section counter
|
|
||||||
cycle ! skip to next line
|
|
||||||
endif
|
|
||||||
if (phase > 0_pInt ) then; if (phase_damage(phase) == LOCAL_DAMAGE_gurson_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
|
||||||
instance = phase_damageInstance(phase) ! which instance of my damage is present phase
|
|
||||||
positions = IO_stringPos(line,MAXNCHUNKS)
|
|
||||||
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
|
||||||
select case(tag)
|
|
||||||
case ('(output)')
|
|
||||||
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
|
||||||
case ('local_damage')
|
|
||||||
damage_gurson_Noutput(instance) = damage_gurson_Noutput(instance) + 1_pInt
|
|
||||||
damage_gurson_outputID(damage_gurson_Noutput(instance),instance) = local_damage_ID
|
|
||||||
damage_gurson_output(damage_gurson_Noutput(instance),instance) = &
|
|
||||||
IO_lc(IO_stringValue(line,positions,2_pInt))
|
|
||||||
end select
|
|
||||||
! input parameters
|
|
||||||
case ('coeff_torsion')
|
|
||||||
damage_gurson_coeff_torsion(instance) = IO_floatValue(line,positions,2_pInt) !> coefficent of torsional stress component
|
|
||||||
|
|
||||||
case ('coeff_tension_comp')
|
|
||||||
damage_gurson_coeff_ten_comp(instance) = IO_floatValue(line,positions,2_pInt) !> coefficent of tensile or compressive stress component
|
|
||||||
|
|
||||||
case ('coeff_triaxiality')
|
|
||||||
damage_gurson_coeff_triaxiality(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('fracture_toughness')
|
|
||||||
damage_gurson_fracture_tough(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('lengthscale')
|
|
||||||
damage_gurson_lengthscale(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('critical_voidFraction')
|
|
||||||
damage_gurson_crit_void_fraction(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('atol_damage')
|
|
||||||
damage_gurson_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
end select
|
|
||||||
endif; endif
|
|
||||||
enddo parsingFile
|
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_damage)
|
|
||||||
if (phase_damage(phase) == LOCAL_DAMAGE_gurson_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! Determine size of postResults array
|
|
||||||
outputsLoop: do o = 1_pInt,damage_gurson_Noutput(instance)
|
|
||||||
select case(damage_gurson_outputID(o,instance))
|
|
||||||
case(local_damage_ID)
|
|
||||||
mySize = 1_pInt
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (mySize > 0_pInt) then ! any meaningful output found
|
|
||||||
damage_gurson_sizePostResult(o,instance) = mySize
|
|
||||||
damage_gurson_sizePostResults(instance) = damage_gurson_sizePostResults(instance) + mySize
|
|
||||||
endif
|
|
||||||
enddo outputsLoop
|
|
||||||
! Determine size of state array
|
|
||||||
sizeDotState = 3_pInt
|
|
||||||
sizeState = 4_pInt
|
|
||||||
|
|
||||||
damageState(phase)%sizeState = sizeState
|
|
||||||
damageState(phase)%sizeDotState = sizeDotState
|
|
||||||
damageState(phase)%sizePostResults = damage_gurson_sizePostResults(instance)
|
|
||||||
allocate(damageState(phase)%aTolState (sizeState), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
|
|
||||||
allocate(damageState(phase)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
|
||||||
allocate(damageState(phase)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
endif
|
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(damageState(phase)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
|
||||||
allocate(damageState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
|
||||||
|
|
||||||
call damage_gurson_stateInit(phase)
|
|
||||||
call damage_gurson_aTolState(phase,instance)
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo initializeInstances
|
|
||||||
end subroutine damage_gurson_init
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant NEW state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_gurson_stateInit(phase)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: phase !< number specifying the phase of the damage
|
|
||||||
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempState
|
|
||||||
|
|
||||||
tempState(1) = 1.0_pReal
|
|
||||||
tempState(2) = 1.0_pReal
|
|
||||||
tempState(3) = 1.0_pReal
|
|
||||||
tempState(4) = 1.0_pReal
|
|
||||||
|
|
||||||
damageState(phase)%state = spread(tempState,2,size(damageState(phase)%state(1,:)))
|
|
||||||
damageState(phase)%state0 = damageState(phase)%state
|
|
||||||
damageState(phase)%partionedState0 = damageState(phase)%state
|
|
||||||
end subroutine damage_gurson_stateInit
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_gurson_aTolState(phase,instance)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
phase, &
|
|
||||||
instance ! number specifying the current instance of the damage
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempTol
|
|
||||||
|
|
||||||
tempTol = damage_gurson_aTol(instance)
|
|
||||||
damageState(phase)%aTolState = tempTol
|
|
||||||
|
|
||||||
end subroutine damage_gurson_aTolState
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief calculates derived quantities from state
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_gurson_dotState(Tstar_v, Lp, ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
use math, only: &
|
|
||||||
math_equivStrain33, &
|
|
||||||
math_norm33, &
|
|
||||||
math_j3_33, &
|
|
||||||
math_trace33, &
|
|
||||||
math_I3, &
|
|
||||||
math_Mandel6to33
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_DamageMobility
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
real(pReal), intent(in), dimension(6) :: &
|
|
||||||
Tstar_v !< 2nd Piola Kirchhoff stress tensor (Mandel)
|
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
|
||||||
Lp
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent
|
|
||||||
real(pReal) :: &
|
|
||||||
i1, j2, j3
|
|
||||||
real(pReal) , dimension(3,3) :: &
|
|
||||||
Tstar_dev
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
Tstar_dev = math_Mandel6to33(Tstar_v) - math_trace33(math_Mandel6to33(Tstar_v))/3.0_pReal*math_I3
|
|
||||||
i1 = sum(Tstar_v(1:3))
|
|
||||||
j2 = 0.5_pReal*(math_norm33(Tstar_dev))**2.0_pReal
|
|
||||||
j3 = math_j3_33(math_Mandel6to33(Tstar_v))
|
|
||||||
|
|
||||||
damageState(phase)%dotState(1,constituent) = &
|
|
||||||
(1.0_pReal/lattice_DamageMobility(phase))* &
|
|
||||||
(damageState(phase)%state(4,constituent) - &
|
|
||||||
damageState(phase)%state(1,constituent))
|
|
||||||
|
|
||||||
|
|
||||||
damageState(phase)%dotState(2,constituent) = & !> void nucleation rate
|
|
||||||
math_norm33(Lp)*sqrt(damage_gurson_lengthscale(phase))/damage_gurson_fracture_tough(phase)* &
|
|
||||||
damageState(phase)%state(2,constituent) * ( &
|
|
||||||
damage_gurson_coeff_torsion(phase) * ((4_pReal/27_pReal) - (j3**(2)/j2**(3))) + &
|
|
||||||
damage_gurson_coeff_ten_comp(phase) * (j3/j2**(1.5_pReal)) + &
|
|
||||||
damage_gurson_coeff_triaxiality(phase) * abs(i1/sqrt(j2))) !> to be coupled with vacancy generation
|
|
||||||
|
|
||||||
damageState(phase)%dotState(3,constituent) = &
|
|
||||||
( damageState(phase)%state(4,constituent)) * math_trace33(Lp) !> void growth rate
|
|
||||||
|
|
||||||
|
|
||||||
end subroutine damage_gurson_dotState
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief calculates derived quantities from state
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_gurson_microstructure(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
use math, only: &
|
|
||||||
math_Mandel6to33, &
|
|
||||||
math_mul33x33, &
|
|
||||||
math_norm33
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal) :: &
|
|
||||||
voidFraction
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
voidFraction = damageState(phase)%state(2,constituent) + damageState(phase)%state(3,constituent)
|
|
||||||
|
|
||||||
if(voidFraction < damage_gurson_crit_void_fraction(phase)) then
|
|
||||||
damageState(phase)%state(4,constituent) = 1.0_pReal - voidFraction ! damage parameter is 1 when no void present
|
|
||||||
else
|
|
||||||
damageState(phase)%state(4,constituent) = 1.0_pReal - damage_gurson_crit_void_fraction(phase) + &
|
|
||||||
5.0_pReal * (voidFraction - damage_gurson_crit_void_fraction(phase)) ! this accelerated void increase models the effect of void coalescence
|
|
||||||
endif
|
|
||||||
|
|
||||||
end subroutine damage_gurson_microstructure
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function damage_gurson_getDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
material_homog, &
|
|
||||||
mappingHomogenization, &
|
|
||||||
fieldDamage, &
|
|
||||||
field_damage_type, &
|
|
||||||
FIELD_DAMAGE_LOCAL_ID, &
|
|
||||||
FIELD_DAMAGE_NONLOCAL_ID
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: damage_gurson_getDamage
|
|
||||||
|
|
||||||
select case(field_damage_type(material_homog(ip,el)))
|
|
||||||
case (FIELD_DAMAGE_LOCAL_ID)
|
|
||||||
damage_gurson_getDamage = damage_gurson_getLocalDamage(ipc, ip, el)
|
|
||||||
|
|
||||||
case (FIELD_DAMAGE_NONLOCAL_ID)
|
|
||||||
damage_gurson_getDamage = fieldDamage(material_homog(ip,el))% &
|
|
||||||
field(1,mappingHomogenization(1,ip,el)) ! Taylor type
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
end function damage_gurson_getDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns slip damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function damage_gurson_getSlipDamage(Tstar_v, ipc, ip, el)
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), dimension(6), intent(in) :: &
|
|
||||||
Tstar_v !< 2nd Piola Kirchhoff stress tensor in Mandel notation
|
|
||||||
real(pReal) :: damage_gurson_getSlipDamage, porosity
|
|
||||||
|
|
||||||
porosity = damage_gurson_getDamage(ipc, ip, el)
|
|
||||||
damage_gurson_getSlipDamage = porosity*porosity ! Gurson yield function should go here
|
|
||||||
|
|
||||||
end function damage_gurson_getSlipDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief puts local damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_gurson_putLocalDamage(ipc, ip, el, localDamage)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: localDamage
|
|
||||||
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el)) = &
|
|
||||||
localDamage
|
|
||||||
|
|
||||||
end subroutine damage_gurson_putLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns local damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function damage_gurson_getLocalDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: damage_gurson_getLocalDamage
|
|
||||||
|
|
||||||
damage_gurson_getLocalDamage = &
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
end function damage_gurson_getLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief return array of constitutive results
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function damage_gurson_postResults(ipc,ip,el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance,&
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), dimension(damage_gurson_sizePostResults(phase_damageInstance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
|
||||||
damage_gurson_postResults
|
|
||||||
|
|
||||||
integer(pInt) :: &
|
|
||||||
instance, phase, constituent, o, c
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
c = 0_pInt
|
|
||||||
damage_gurson_postResults = 0.0_pReal
|
|
||||||
|
|
||||||
do o = 1_pInt,damage_gurson_Noutput(instance)
|
|
||||||
select case(damage_gurson_outputID(o,instance))
|
|
||||||
case (local_damage_ID)
|
|
||||||
damage_gurson_postResults(c+1_pInt) = damageState(phase)%state(1,constituent)
|
|
||||||
c = c + 1
|
|
||||||
|
|
||||||
end select
|
|
||||||
enddo
|
|
||||||
end function damage_gurson_postResults
|
|
||||||
|
|
||||||
end module damage_gurson
|
|
|
@ -1,484 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! $Id$
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @author Luv Sharma, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @brief material subroutine incoprorating isotropic brittle damage
|
|
||||||
!> @details to be done
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module damage_isoBrittle
|
|
||||||
use prec, only: &
|
|
||||||
pReal, &
|
|
||||||
pInt
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
private
|
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
|
||||||
damage_isoBrittle_sizePostResults !< cumulative size of post results
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_isoBrittle_sizePostResult !< size of each post result output
|
|
||||||
|
|
||||||
character(len=64), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_isoBrittle_output !< name of each post result output
|
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, target, public :: &
|
|
||||||
damage_isoBrittle_Noutput !< number of outputs per instance of this damage
|
|
||||||
|
|
||||||
real(pReal), dimension(:), allocatable, private :: &
|
|
||||||
damage_isoBrittle_aTol, &
|
|
||||||
damage_isoBrittle_critStrainEnergy
|
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: undefined_ID, &
|
|
||||||
local_damage_ID
|
|
||||||
end enum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11 ToDo
|
|
||||||
|
|
||||||
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_isoBrittle_outputID !< ID of each post result output
|
|
||||||
|
|
||||||
|
|
||||||
public :: &
|
|
||||||
damage_isoBrittle_init, &
|
|
||||||
damage_isoBrittle_stateInit, &
|
|
||||||
damage_isoBrittle_aTolState, &
|
|
||||||
damage_isoBrittle_microstructure, &
|
|
||||||
damage_isoBrittle_getDamage, &
|
|
||||||
damage_isoBrittle_putLocalDamage, &
|
|
||||||
damage_isoBrittle_getLocalDamage, &
|
|
||||||
damage_isoBrittle_getDamageDiffusion33, &
|
|
||||||
damage_isoBrittle_getDamagedC66, &
|
|
||||||
damage_isoBrittle_postResults
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief module initialization
|
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_isoBrittle_init(fileUnit)
|
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
|
||||||
use debug, only: &
|
|
||||||
debug_level,&
|
|
||||||
debug_constitutive,&
|
|
||||||
debug_levelBasic
|
|
||||||
use IO, only: &
|
|
||||||
IO_read, &
|
|
||||||
IO_lc, &
|
|
||||||
IO_getTag, &
|
|
||||||
IO_isBlank, &
|
|
||||||
IO_stringPos, &
|
|
||||||
IO_stringValue, &
|
|
||||||
IO_floatValue, &
|
|
||||||
IO_intValue, &
|
|
||||||
IO_warning, &
|
|
||||||
IO_error, &
|
|
||||||
IO_timeStamp, &
|
|
||||||
IO_EOF
|
|
||||||
use material, only: &
|
|
||||||
phase_damage, &
|
|
||||||
phase_damageInstance, &
|
|
||||||
phase_Noutput, &
|
|
||||||
LOCAL_damage_isoBrittle_label, &
|
|
||||||
LOCAL_damage_isoBrittle_ID, &
|
|
||||||
material_phase, &
|
|
||||||
damageState, &
|
|
||||||
MATERIAL_partPhase
|
|
||||||
use numerics,only: &
|
|
||||||
worldrank, &
|
|
||||||
numerics_integrator
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: fileUnit
|
|
||||||
|
|
||||||
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
|
||||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
|
||||||
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,o
|
|
||||||
integer(pInt) :: sizeState, sizeDotState
|
|
||||||
integer(pInt) :: NofMyPhase
|
|
||||||
character(len=65536) :: &
|
|
||||||
tag = '', &
|
|
||||||
line = ''
|
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
|
||||||
write(6,'(/,a)') ' <<<+- damage_'//LOCAL_damage_isoBrittle_label//' init -+>>>'
|
|
||||||
write(6,'(a)') ' $Id$'
|
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
|
||||||
#include "compilation_info.f90"
|
|
||||||
endif mainProcess
|
|
||||||
|
|
||||||
maxNinstance = int(count(phase_damage == LOCAL_damage_isoBrittle_ID),pInt)
|
|
||||||
if (maxNinstance == 0_pInt) return
|
|
||||||
|
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
|
||||||
|
|
||||||
allocate(damage_isoBrittle_sizePostResults(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_isoBrittle_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
|
||||||
allocate(damage_isoBrittle_output(maxval(phase_Noutput),maxNinstance))
|
|
||||||
damage_isoBrittle_output = ''
|
|
||||||
allocate(damage_isoBrittle_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
|
||||||
allocate(damage_isoBrittle_Noutput(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_isoBrittle_critStrainEnergy(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_isoBrittle_aTol(maxNinstance), source=0.0_pReal)
|
|
||||||
|
|
||||||
rewind(fileUnit)
|
|
||||||
phase = 0_pInt
|
|
||||||
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
if (IO_isBlank(line)) cycle ! skip empty lines
|
|
||||||
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
|
||||||
line = IO_read(fileUnit, .true.) ! reset IO_read
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
|
||||||
phase = phase + 1_pInt ! advance phase section counter
|
|
||||||
cycle ! skip to next line
|
|
||||||
endif
|
|
||||||
if (phase > 0_pInt ) then; if (phase_damage(phase) == LOCAL_damage_isoBrittle_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
|
||||||
instance = phase_damageInstance(phase) ! which instance of my damage is present phase
|
|
||||||
positions = IO_stringPos(line,MAXNCHUNKS)
|
|
||||||
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
|
||||||
select case(tag)
|
|
||||||
case ('(output)')
|
|
||||||
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
|
||||||
case ('local_damage')
|
|
||||||
damage_isoBrittle_Noutput(instance) = damage_isoBrittle_Noutput(instance) + 1_pInt
|
|
||||||
damage_isoBrittle_outputID(damage_isoBrittle_Noutput(instance),instance) = local_damage_ID
|
|
||||||
damage_isoBrittle_output(damage_isoBrittle_Noutput(instance),instance) = &
|
|
||||||
IO_lc(IO_stringValue(line,positions,2_pInt))
|
|
||||||
end select
|
|
||||||
|
|
||||||
case ('criticalstrainenergy')
|
|
||||||
damage_isoBrittle_critStrainEnergy(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('atol_damage')
|
|
||||||
damage_isoBrittle_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
end select
|
|
||||||
endif; endif
|
|
||||||
enddo parsingFile
|
|
||||||
|
|
||||||
|
|
||||||
sanityChecks: do phase = 1_pInt, size(phase_damage)
|
|
||||||
myPhase: if (phase_damage(phase) == LOCAL_damage_isoBrittle_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
! sanity checks
|
|
||||||
if (damage_isoBrittle_aTol(instance) < 0.0_pReal) &
|
|
||||||
damage_isoBrittle_aTol(instance) = 1.0e-3_pReal ! default absolute tolerance 1e-3
|
|
||||||
if (damage_isoBrittle_critStrainEnergy(instance) <= 0.0_pReal) &
|
|
||||||
call IO_error(211_pInt,el=instance,ext_msg='criticalStrainEnergy ('//LOCAL_DAMAGE_isoBrittle_LABEL//')')
|
|
||||||
endif myPhase
|
|
||||||
enddo sanityChecks
|
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_damage)
|
|
||||||
if (phase_damage(phase) == LOCAL_damage_isoBrittle_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! Determine size of postResults array
|
|
||||||
outputsLoop: do o = 1_pInt,damage_isoBrittle_Noutput(instance)
|
|
||||||
select case(damage_isoBrittle_outputID(o,instance))
|
|
||||||
case(local_damage_ID)
|
|
||||||
mySize = 1_pInt
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (mySize > 0_pInt) then ! any meaningful output found
|
|
||||||
damage_isoBrittle_sizePostResult(o,instance) = mySize
|
|
||||||
damage_isoBrittle_sizePostResults(instance) = damage_isoBrittle_sizePostResults(instance) + mySize
|
|
||||||
endif
|
|
||||||
enddo outputsLoop
|
|
||||||
! Determine size of state array
|
|
||||||
sizeDotState = 0_pInt
|
|
||||||
sizeState = 2_pInt
|
|
||||||
|
|
||||||
damageState(phase)%sizeState = sizeState
|
|
||||||
damageState(phase)%sizeDotState = sizeDotState
|
|
||||||
damageState(phase)%sizePostResults = damage_isoBrittle_sizePostResults(instance)
|
|
||||||
allocate(damageState(phase)%aTolState (sizeState), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
|
|
||||||
allocate(damageState(phase)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
|
||||||
allocate(damageState(phase)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
endif
|
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(damageState(phase)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
|
||||||
allocate(damageState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
|
||||||
|
|
||||||
call damage_isoBrittle_stateInit(phase)
|
|
||||||
call damage_isoBrittle_aTolState(phase,instance)
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo initializeInstances
|
|
||||||
end subroutine damage_isoBrittle_init
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant NEW state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_isoBrittle_stateInit(phase)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: phase !< number specifying the phase of the damage
|
|
||||||
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempState
|
|
||||||
|
|
||||||
tempState = 1.0_pReal
|
|
||||||
damageState(phase)%state = spread(tempState,2,size(damageState(phase)%state(1,:)))
|
|
||||||
damageState(phase)%state0 = damageState(phase)%state
|
|
||||||
damageState(phase)%partionedState0 = damageState(phase)%state
|
|
||||||
end subroutine damage_isoBrittle_stateInit
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_isoBrittle_aTolState(phase,instance)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
phase, &
|
|
||||||
instance ! number specifying the current instance of the damage
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempTol
|
|
||||||
|
|
||||||
tempTol = damage_isoBrittle_aTol(instance)
|
|
||||||
damageState(phase)%aTolState = tempTol
|
|
||||||
end subroutine damage_isoBrittle_aTolState
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief calculates derived quantities from state
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_isoBrittle_microstructure(C, Fe, subdt, ipc, ip, el)
|
|
||||||
use numerics, only: &
|
|
||||||
residualStiffness
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance, &
|
|
||||||
damageState
|
|
||||||
use math, only : &
|
|
||||||
math_mul33x33, &
|
|
||||||
math_mul66x6, &
|
|
||||||
math_Mandel33to6, &
|
|
||||||
math_transpose33, &
|
|
||||||
math_I3
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_DamageMobility
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
|
||||||
Fe
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
subdt
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent, instance
|
|
||||||
real(pReal) :: &
|
|
||||||
strain(6), &
|
|
||||||
stress(6), &
|
|
||||||
C(6,6)
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
strain = 0.5_pReal*math_Mandel33to6(math_mul33x33(math_transpose33(Fe),Fe)-math_I3)
|
|
||||||
stress = math_mul66x6(C,strain)
|
|
||||||
|
|
||||||
damageState(phase)%state(2,constituent) = &
|
|
||||||
max(residualStiffness, &
|
|
||||||
min(damageState(phase)%state0(2,constituent), &
|
|
||||||
damage_isoBrittle_critStrainEnergy(instance)/(2.0_pReal*sum(abs(stress*strain))))) !< residualStiffness < damage < damage0
|
|
||||||
|
|
||||||
damageState(phase)%state(1,constituent) = &
|
|
||||||
damageState(phase)%state(2,constituent) + &
|
|
||||||
(damageState(phase)%subState0(1,constituent) - damageState(phase)%state(2,constituent))* &
|
|
||||||
exp(-subdt/lattice_DamageMobility(phase))
|
|
||||||
|
|
||||||
end subroutine damage_isoBrittle_microstructure
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_isoBrittle_getDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
material_homog, &
|
|
||||||
mappingHomogenization, &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState, &
|
|
||||||
fieldDamage, &
|
|
||||||
field_damage_type, &
|
|
||||||
FIELD_DAMAGE_NONLOCAL_ID
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: damage_isoBrittle_getDamage
|
|
||||||
|
|
||||||
select case(field_damage_type(material_homog(ip,el)))
|
|
||||||
case (FIELD_DAMAGE_NONLOCAL_ID)
|
|
||||||
damage_isoBrittle_getDamage = fieldDamage(material_homog(ip,el))% &
|
|
||||||
field(1,mappingHomogenization(1,ip,el)) ! Taylor type
|
|
||||||
|
|
||||||
case default
|
|
||||||
damage_isoBrittle_getDamage = damageState(mappingConstitutive(2,ipc,ip,el))% &
|
|
||||||
state0(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
end function damage_isoBrittle_getDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns temperature based on local damage model state layout
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_isoBrittle_putLocalDamage(ipc, ip, el, localDamage)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: localDamage
|
|
||||||
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el)) = &
|
|
||||||
localDamage
|
|
||||||
|
|
||||||
end subroutine damage_isoBrittle_putLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns local damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_isoBrittle_getLocalDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: damage_isoBrittle_getLocalDamage
|
|
||||||
|
|
||||||
damage_isoBrittle_getLocalDamage = &
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
end function damage_isoBrittle_getLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns brittle damage diffusion tensor
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_isoBrittle_getDamageDiffusion33(ipc, ip, el)
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_DamageDiffusion33
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), dimension(3,3) :: &
|
|
||||||
damage_isoBrittle_getDamageDiffusion33
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
damage_isoBrittle_getDamageDiffusion33 = &
|
|
||||||
lattice_DamageDiffusion33(1:3,1:3,phase)
|
|
||||||
|
|
||||||
end function damage_isoBrittle_getDamageDiffusion33
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns brittle damaged stiffness tensor
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_isoBrittle_getDamagedC66(C, ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in), dimension(6,6) :: &
|
|
||||||
C
|
|
||||||
real(pReal), dimension(6,6) :: &
|
|
||||||
damage_isoBrittle_getDamagedC66
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent
|
|
||||||
real(pReal) :: &
|
|
||||||
damage
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
damage = damage_isoBrittle_getDamage(ipc, ip, el)
|
|
||||||
damage_isoBrittle_getDamagedC66 = &
|
|
||||||
damage*damage*C
|
|
||||||
|
|
||||||
end function damage_isoBrittle_getDamagedC66
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief return array of constitutive results
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function damage_isoBrittle_postResults(ipc,ip,el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState, &
|
|
||||||
phase_damageInstance
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), dimension(damage_isoBrittle_sizePostResults(phase_damageInstance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
|
||||||
damage_isoBrittle_postResults
|
|
||||||
|
|
||||||
integer(pInt) :: &
|
|
||||||
instance, phase, constituent, o, c
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
c = 0_pInt
|
|
||||||
damage_isoBrittle_postResults = 0.0_pReal
|
|
||||||
|
|
||||||
do o = 1_pInt,damage_isoBrittle_Noutput(instance)
|
|
||||||
select case(damage_isoBrittle_outputID(o,instance))
|
|
||||||
case (local_damage_ID)
|
|
||||||
damage_isoBrittle_postResults(c+1_pInt) = damageState(phase)%state(1,constituent)
|
|
||||||
c = c + 1
|
|
||||||
|
|
||||||
end select
|
|
||||||
enddo
|
|
||||||
end function damage_isoBrittle_postResults
|
|
||||||
|
|
||||||
end module damage_isoBrittle
|
|
|
@ -1,457 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! $Id$
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Luv Sharma, Max-Planck-Institut fŸr Eisenforschung GmbH
|
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut fŸr Eisenforschung GmbH
|
|
||||||
!> @brief material subroutine incoprorating isotropic ductile damage
|
|
||||||
!> @details to be done
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module damage_isoDuctile
|
|
||||||
use prec, only: &
|
|
||||||
pReal, &
|
|
||||||
pInt
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
private
|
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
|
||||||
damage_isoDuctile_sizePostResults !< cumulative size of post results
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_isoDuctile_sizePostResult !< size of each post result output
|
|
||||||
|
|
||||||
character(len=64), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_isoDuctile_output !< name of each post result output
|
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, target, public :: &
|
|
||||||
damage_isoDuctile_Noutput !< number of outputs per instance of this damage
|
|
||||||
|
|
||||||
real(pReal), dimension(:), allocatable, private :: &
|
|
||||||
damage_isoDuctile_aTol, &
|
|
||||||
damage_isoDuctile_critPlasticStrain, &
|
|
||||||
damage_isoDuctile_N
|
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: undefined_ID, &
|
|
||||||
local_damage_ID
|
|
||||||
end enum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11 ToDo
|
|
||||||
|
|
||||||
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_isoDuctile_outputID !< ID of each post result output
|
|
||||||
|
|
||||||
|
|
||||||
public :: &
|
|
||||||
damage_isoDuctile_init, &
|
|
||||||
damage_isoDuctile_stateInit, &
|
|
||||||
damage_isoDuctile_aTolState, &
|
|
||||||
damage_isoDuctile_microstructure, &
|
|
||||||
damage_isoDuctile_getDamage, &
|
|
||||||
damage_isoDuctile_putLocalDamage, &
|
|
||||||
damage_isoDuctile_getLocalDamage, &
|
|
||||||
damage_isoDuctile_getDamagedC66, &
|
|
||||||
damage_isoDuctile_postResults
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief module initialization
|
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_isoDuctile_init(fileUnit)
|
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
|
||||||
use debug, only: &
|
|
||||||
debug_level,&
|
|
||||||
debug_constitutive,&
|
|
||||||
debug_levelBasic
|
|
||||||
use IO, only: &
|
|
||||||
IO_read, &
|
|
||||||
IO_lc, &
|
|
||||||
IO_getTag, &
|
|
||||||
IO_isBlank, &
|
|
||||||
IO_stringPos, &
|
|
||||||
IO_stringValue, &
|
|
||||||
IO_floatValue, &
|
|
||||||
IO_intValue, &
|
|
||||||
IO_warning, &
|
|
||||||
IO_error, &
|
|
||||||
IO_timeStamp, &
|
|
||||||
IO_EOF
|
|
||||||
use material, only: &
|
|
||||||
phase_damage, &
|
|
||||||
phase_damageInstance, &
|
|
||||||
phase_Noutput, &
|
|
||||||
LOCAL_damage_isoDuctile_label, &
|
|
||||||
LOCAL_damage_isoDuctile_ID, &
|
|
||||||
material_phase, &
|
|
||||||
damageState, &
|
|
||||||
MATERIAL_partPhase
|
|
||||||
use numerics,only: &
|
|
||||||
worldrank, &
|
|
||||||
numerics_integrator
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: fileUnit
|
|
||||||
|
|
||||||
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
|
||||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
|
||||||
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,o
|
|
||||||
integer(pInt) :: sizeState, sizeDotState
|
|
||||||
integer(pInt) :: NofMyPhase
|
|
||||||
character(len=65536) :: &
|
|
||||||
tag = '', &
|
|
||||||
line = ''
|
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
|
||||||
write(6,'(/,a)') ' <<<+- damage_'//LOCAL_damage_isoDuctile_LABEL//' init -+>>>'
|
|
||||||
write(6,'(a)') ' $Id$'
|
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
|
||||||
#include "compilation_info.f90"
|
|
||||||
endif mainProcess
|
|
||||||
|
|
||||||
maxNinstance = int(count(phase_damage == LOCAL_damage_isoDuctile_ID),pInt)
|
|
||||||
if (maxNinstance == 0_pInt) return
|
|
||||||
|
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
|
||||||
|
|
||||||
allocate(damage_isoDuctile_sizePostResults(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_isoDuctile_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
|
||||||
allocate(damage_isoDuctile_output(maxval(phase_Noutput),maxNinstance))
|
|
||||||
damage_isoDuctile_output = ''
|
|
||||||
allocate(damage_isoDuctile_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
|
||||||
allocate(damage_isoDuctile_Noutput(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_isoDuctile_critPlasticStrain(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_isoDuctile_N(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_isoDuctile_aTol(maxNinstance), source=0.0_pReal)
|
|
||||||
|
|
||||||
rewind(fileUnit)
|
|
||||||
phase = 0_pInt
|
|
||||||
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
if (IO_isBlank(line)) cycle ! skip empty lines
|
|
||||||
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
|
||||||
line = IO_read(fileUnit, .true.) ! reset IO_read
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
|
||||||
phase = phase + 1_pInt ! advance phase section counter
|
|
||||||
cycle ! skip to next line
|
|
||||||
endif
|
|
||||||
if (phase > 0_pInt ) then; if (phase_damage(phase) == LOCAL_damage_isoDuctile_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
|
||||||
instance = phase_damageInstance(phase) ! which instance of my damage is present phase
|
|
||||||
positions = IO_stringPos(line,MAXNCHUNKS)
|
|
||||||
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
|
||||||
select case(tag)
|
|
||||||
case ('(output)')
|
|
||||||
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
|
||||||
case ('local_damage')
|
|
||||||
damage_isoDuctile_Noutput(instance) = damage_isoDuctile_Noutput(instance) + 1_pInt
|
|
||||||
damage_isoDuctile_outputID(damage_isoDuctile_Noutput(instance),instance) = local_damage_ID
|
|
||||||
damage_isoDuctile_output(damage_isoDuctile_Noutput(instance),instance) = &
|
|
||||||
IO_lc(IO_stringValue(line,positions,2_pInt))
|
|
||||||
end select
|
|
||||||
|
|
||||||
case ('criticalplasticstrain')
|
|
||||||
damage_isoDuctile_critPlasticStrain(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('damageratesensitivity')
|
|
||||||
damage_isoDuctile_N(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('atol_damage')
|
|
||||||
damage_isoDuctile_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
end select
|
|
||||||
endif; endif
|
|
||||||
enddo parsingFile
|
|
||||||
|
|
||||||
sanityChecks: do phase = 1_pInt, size(phase_damage)
|
|
||||||
myPhase: if (phase_damage(phase) == LOCAL_damage_isoDuctile_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
! sanity checks
|
|
||||||
if (damage_isoDuctile_aTol(instance) < 0.0_pReal) &
|
|
||||||
damage_isoDuctile_aTol(instance) = 1.0e-3_pReal ! default absolute tolerance 1e-3
|
|
||||||
if (damage_isoDuctile_critPlasticStrain(instance) <= 0.0_pReal) &
|
|
||||||
call IO_error(211_pInt,el=instance,ext_msg='critical_plastic_strain ('//LOCAL_DAMAGE_isoDuctile_LABEL//')')
|
|
||||||
endif myPhase
|
|
||||||
enddo sanityChecks
|
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_damage)
|
|
||||||
if (phase_damage(phase) == LOCAL_damage_isoDuctile_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! Determine size of postResults array
|
|
||||||
outputsLoop: do o = 1_pInt,damage_isoDuctile_Noutput(instance)
|
|
||||||
select case(damage_isoDuctile_outputID(o,instance))
|
|
||||||
case(local_damage_ID)
|
|
||||||
mySize = 1_pInt
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (mySize > 0_pInt) then ! any meaningful output found
|
|
||||||
damage_isoDuctile_sizePostResult(o,instance) = mySize
|
|
||||||
damage_isoDuctile_sizePostResults(instance) = damage_isoDuctile_sizePostResults(instance) + mySize
|
|
||||||
endif
|
|
||||||
enddo outputsLoop
|
|
||||||
! Determine size of state array
|
|
||||||
sizeDotState = 0_pInt
|
|
||||||
sizeState = 2_pInt
|
|
||||||
|
|
||||||
damageState(phase)%sizeState = sizeState
|
|
||||||
damageState(phase)%sizeDotState = sizeDotState
|
|
||||||
damageState(phase)%sizePostResults = damage_isoDuctile_sizePostResults(instance)
|
|
||||||
allocate(damageState(phase)%aTolState (sizeState), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
|
|
||||||
allocate(damageState(phase)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
|
||||||
allocate(damageState(phase)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
endif
|
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(damageState(phase)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
|
||||||
allocate(damageState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
|
||||||
|
|
||||||
call damage_isoDuctile_stateInit(phase)
|
|
||||||
call damage_isoDuctile_aTolState(phase,instance)
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo initializeInstances
|
|
||||||
end subroutine damage_isoDuctile_init
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_isoDuctile_stateInit(phase)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: phase !< number specifying the phase of the damage
|
|
||||||
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempState
|
|
||||||
|
|
||||||
tempState(1) = 1.0_pReal
|
|
||||||
tempState(2) = 0.0_pReal
|
|
||||||
|
|
||||||
damageState(phase)%state0 = spread(tempState,2,size(damageState(phase)%state(1,:)))
|
|
||||||
|
|
||||||
end subroutine damage_isoDuctile_stateInit
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_isoDuctile_aTolState(phase,instance)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
phase, &
|
|
||||||
instance ! number specifying the current instance of the damage
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempTol
|
|
||||||
|
|
||||||
tempTol = damage_isoDuctile_aTol(instance)
|
|
||||||
damageState(phase)%aTolState = tempTol
|
|
||||||
|
|
||||||
end subroutine damage_isoDuctile_aTolState
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief calculates derived quantities from state
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_isoDuctile_microstructure(subdt,ipc, ip, el)
|
|
||||||
use numerics, only: &
|
|
||||||
residualStiffness
|
|
||||||
use material, only: &
|
|
||||||
phase_damageInstance, &
|
|
||||||
mappingConstitutive, &
|
|
||||||
plasticState, &
|
|
||||||
damageState
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_DamageMobility
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
subdt
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent, instance
|
|
||||||
real(pReal) :: &
|
|
||||||
localDamage
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
damageState(phase)%state(2,constituent) = &
|
|
||||||
damageState(phase)%subState0(2,constituent) + &
|
|
||||||
subdt* &
|
|
||||||
sum(plasticState(phase)%slipRate(:,constituent))/ &
|
|
||||||
(damage_isoDuctile_getDamage(ipc, ip, el)**damage_isoDuctile_N(instance))/ &
|
|
||||||
damage_isoDuctile_critPlasticStrain(instance)
|
|
||||||
|
|
||||||
localDamage = &
|
|
||||||
max(residualStiffness,min(1.0_pReal, 1.0_pReal/damageState(phase)%state(2,constituent)))
|
|
||||||
|
|
||||||
damageState(phase)%state(1,constituent) = &
|
|
||||||
localDamage + &
|
|
||||||
(damageState(phase)%subState0(1,constituent) - localDamage)* &
|
|
||||||
exp(-subdt/lattice_DamageMobility(phase))
|
|
||||||
|
|
||||||
end subroutine damage_isoDuctile_microstructure
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_isoDuctile_getDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
material_homog, &
|
|
||||||
mappingHomogenization, &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState, &
|
|
||||||
fieldDamage, &
|
|
||||||
field_damage_type, &
|
|
||||||
FIELD_DAMAGE_LOCAL_ID, &
|
|
||||||
FIELD_DAMAGE_NONLOCAL_ID
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: damage_isoDuctile_getDamage
|
|
||||||
|
|
||||||
select case(field_damage_type(material_homog(ip,el)))
|
|
||||||
case default
|
|
||||||
damage_isoDuctile_getDamage = damageState(mappingConstitutive(2,ipc,ip,el))% &
|
|
||||||
state0(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
case (FIELD_DAMAGE_NONLOCAL_ID)
|
|
||||||
damage_isoDuctile_getDamage = fieldDamage(material_homog(ip,el))% &
|
|
||||||
field(1,mappingHomogenization(1,ip,el)) ! Taylor type
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
end function damage_isoDuctile_getDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief puts local damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_isoDuctile_putLocalDamage(ipc, ip, el, localDamage)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: localDamage
|
|
||||||
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el)) = &
|
|
||||||
localDamage
|
|
||||||
|
|
||||||
end subroutine damage_isoDuctile_putLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns local damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_isoDuctile_getLocalDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: damage_isoDuctile_getLocalDamage
|
|
||||||
|
|
||||||
damage_isoDuctile_getLocalDamage = &
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
end function damage_isoDuctile_getLocalDamage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns ductile damaged stiffness tensor
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_isoDuctile_getDamagedC66(C, ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in), dimension(6,6) :: &
|
|
||||||
C
|
|
||||||
real(pReal), dimension(6,6) :: &
|
|
||||||
damage_isoDuctile_getDamagedC66
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent
|
|
||||||
real(pReal) :: &
|
|
||||||
damage
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
damage = damage_isoDuctile_getDamage(ipc, ip, el)
|
|
||||||
damage_isoDuctile_getDamagedC66 = &
|
|
||||||
damage*damage*C
|
|
||||||
|
|
||||||
end function damage_isoDuctile_getDamagedC66
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief return array of constitutive results
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function damage_isoDuctile_postResults(ipc,ip,el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance,&
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), dimension(damage_isoDuctile_sizePostResults(phase_damageInstance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
|
||||||
damage_isoDuctile_postResults
|
|
||||||
|
|
||||||
integer(pInt) :: &
|
|
||||||
instance, phase, constituent, o, c
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
c = 0_pInt
|
|
||||||
damage_isoDuctile_postResults = 0.0_pReal
|
|
||||||
|
|
||||||
do o = 1_pInt,damage_isoDuctile_Noutput(instance)
|
|
||||||
select case(damage_isoDuctile_outputID(o,instance))
|
|
||||||
case (local_damage_ID)
|
|
||||||
damage_isoDuctile_postResults(c+1_pInt) = damageState(phase)%state(1,constituent)
|
|
||||||
c = c + 1
|
|
||||||
|
|
||||||
end select
|
|
||||||
enddo
|
|
||||||
end function damage_isoDuctile_postResults
|
|
||||||
|
|
||||||
end module damage_isoDuctile
|
|
|
@ -0,0 +1,327 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for locally evolving damage field
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module damage_local
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
damage_local_sizePostResults !< cumulative size of post results
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
damage_local_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
damage_local_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
damage_local_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
damage_ID
|
||||||
|
end enum
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
damage_local_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
damage_local_init, &
|
||||||
|
damage_local_updateState, &
|
||||||
|
damage_local_postResults
|
||||||
|
private :: &
|
||||||
|
damage_local_getSourceAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief allocates all neccessary fields, reads information from material configuration file
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine damage_local_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
damage_type, &
|
||||||
|
damage_typeInstance, &
|
||||||
|
homogenization_Noutput, &
|
||||||
|
DAMAGE_local_label, &
|
||||||
|
DAMAGE_local_ID, &
|
||||||
|
material_homog, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
damageState, &
|
||||||
|
damageMapping, &
|
||||||
|
damage, &
|
||||||
|
material_partHomogenization
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,homog,instance,o
|
||||||
|
integer(pInt) :: sizeState
|
||||||
|
integer(pInt) :: NofMyHomog
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- damage_'//DAMAGE_local_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(damage_type == DAMAGE_local_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
allocate(damage_local_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(damage_local_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(damage_local_output (maxval(homogenization_Noutput),maxNinstance))
|
||||||
|
damage_local_output = ''
|
||||||
|
allocate(damage_local_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID)
|
||||||
|
allocate(damage_local_Noutput (maxNinstance), source=0_pInt)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
homog = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partHomogenization)! wind forward to <homogenization>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
|
homog = homog + 1_pInt ! advance homog section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (homog > 0_pInt ) then; if (damage_type(homog) == DAMAGE_local_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = damage_typeInstance(homog) ! which instance of my damage is present homog
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('damage')
|
||||||
|
damage_local_Noutput(instance) = damage_local_Noutput(instance) + 1_pInt
|
||||||
|
damage_local_outputID(damage_local_Noutput(instance),instance) = damage_ID
|
||||||
|
damage_local_output(damage_local_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
initializeInstances: do homog = 1_pInt, size(damage_type)
|
||||||
|
|
||||||
|
myhomog: if (damage_type(homog) == DAMAGE_local_ID) then
|
||||||
|
NofMyHomog = count(material_homog == homog)
|
||||||
|
instance = damage_typeInstance(homog)
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,damage_local_Noutput(instance)
|
||||||
|
select case(damage_local_outputID(o,instance))
|
||||||
|
case(damage_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
damage_local_sizePostResult(o,instance) = mySize
|
||||||
|
damage_local_sizePostResults(instance) = damage_local_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
|
||||||
|
! allocate state arrays
|
||||||
|
sizeState = 1_pInt
|
||||||
|
damageState(homog)%sizeState = sizeState
|
||||||
|
damageState(homog)%sizePostResults = damage_local_sizePostResults(instance)
|
||||||
|
allocate(damageState(homog)%state0 (sizeState,NofMyHomog))
|
||||||
|
allocate(damageState(homog)%subState0(sizeState,NofMyHomog))
|
||||||
|
allocate(damageState(homog)%state (sizeState,NofMyHomog))
|
||||||
|
|
||||||
|
nullify(damageMapping(homog)%p)
|
||||||
|
damageMapping(homog)%p => mappingHomogenization(1,:,:)
|
||||||
|
deallocate(damage(homog)%p)
|
||||||
|
damage(homog)%p => damageState(homog)%state(1,:)
|
||||||
|
|
||||||
|
endif myhomog
|
||||||
|
enddo initializeInstances
|
||||||
|
|
||||||
|
|
||||||
|
end subroutine damage_local_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates local change in damage field
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function damage_local_updateState(subdt, ip, el)
|
||||||
|
use numerics, only: &
|
||||||
|
err_damage_tolAbs, &
|
||||||
|
err_damage_tolRel
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
damageState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
subdt
|
||||||
|
logical, dimension(2) :: &
|
||||||
|
damage_local_updateState
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
offset
|
||||||
|
real(pReal) :: &
|
||||||
|
phi, phiDot, dPhiDot_dPhi
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = mappingHomogenization(1,ip,el)
|
||||||
|
phi = damageState(homog)%subState0(1,offset)
|
||||||
|
call damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el)
|
||||||
|
phi = phi + subdt*phiDot
|
||||||
|
|
||||||
|
damage_local_updateState = [ abs(phi - damageState(homog)%state(1,offset)) &
|
||||||
|
<= err_damage_tolAbs &
|
||||||
|
.or. abs(phi - damageState(homog)%state(1,offset)) &
|
||||||
|
<= err_damage_tolRel*abs(damageState(homog)%state(1,offset)), &
|
||||||
|
.true.]
|
||||||
|
|
||||||
|
damageState(homog)%state(1,offset) = phi
|
||||||
|
|
||||||
|
end function damage_local_updateState
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates homogenized local damage driving forces
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine damage_local_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
mappingConstitutive, &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
SOURCE_damage_isoBrittle_ID, &
|
||||||
|
SOURCE_damage_isoDuctile_ID, &
|
||||||
|
SOURCE_damage_anisoBrittle_ID, &
|
||||||
|
SOURCE_damage_anisoDuctile_ID
|
||||||
|
use source_damage_isoBrittle, only: &
|
||||||
|
source_damage_isobrittle_getRateAndItsTangent
|
||||||
|
use source_damage_isoDuctile, only: &
|
||||||
|
source_damage_isoductile_getRateAndItsTangent
|
||||||
|
use source_damage_anisoBrittle, only: &
|
||||||
|
source_damage_anisobrittle_getRateAndItsTangent
|
||||||
|
use source_damage_anisoDuctile, only: &
|
||||||
|
source_damage_anisoductile_getRateAndItsTangent
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
grain, &
|
||||||
|
source
|
||||||
|
real(pReal) :: &
|
||||||
|
phiDot, dPhiDot_dPhi, localphiDot, dLocalphiDot_dPhi
|
||||||
|
|
||||||
|
phiDot = 0.0_pReal
|
||||||
|
dPhiDot_dPhi = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
phase = mappingConstitutive(2,grain,ip,el)
|
||||||
|
do source = 1, phase_Nsources(phase)
|
||||||
|
select case(phase_source(source,phase))
|
||||||
|
case (SOURCE_damage_isoBrittle_ID)
|
||||||
|
call source_damage_isobrittle_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, grain, ip, el)
|
||||||
|
|
||||||
|
case (SOURCE_damage_isoDuctile_ID)
|
||||||
|
call source_damage_isoductile_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, grain, ip, el)
|
||||||
|
|
||||||
|
case (SOURCE_damage_anisoBrittle_ID)
|
||||||
|
call source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, grain, ip, el)
|
||||||
|
|
||||||
|
case (SOURCE_damage_anisoDuctile_ID)
|
||||||
|
call source_damage_anisoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, grain, ip, el)
|
||||||
|
|
||||||
|
case default
|
||||||
|
localphiDot = 0.0_pReal
|
||||||
|
dLocalphiDot_dPhi = 0.0_pReal
|
||||||
|
|
||||||
|
end select
|
||||||
|
phiDot = phiDot + localphiDot
|
||||||
|
dPhiDot_dPhi = dPhiDot_dPhi + dLocalphiDot_dPhi
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
phiDot = phiDot/homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
dPhiDot_dPhi = dPhiDot_dPhi/homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
|
||||||
|
end subroutine damage_local_getSourceAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of damage results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function damage_local_postResults(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
damage_typeInstance, &
|
||||||
|
damageMapping, &
|
||||||
|
damage
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(damage_local_sizePostResults(damage_typeInstance(mappingHomogenization(2,ip,el)))) :: &
|
||||||
|
damage_local_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, homog, offset, o, c
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = damageMapping(homog)%p(ip,el)
|
||||||
|
instance = damage_typeInstance(homog)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
damage_local_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,damage_local_Noutput(instance)
|
||||||
|
select case(damage_local_outputID(o,instance))
|
||||||
|
|
||||||
|
case (damage_ID)
|
||||||
|
damage_local_postResults(c+1_pInt) = damage(homog)%p(offset)
|
||||||
|
c = c + 1
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function damage_local_postResults
|
||||||
|
|
||||||
|
end module damage_local
|
|
@ -1,100 +1,61 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! $Id$
|
! $Id$
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
!> @brief material subroutine for constant damage field
|
||||||
!> @brief material subroutine for purely elastic material
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module damage_none
|
module damage_none
|
||||||
use prec, only: &
|
|
||||||
pInt
|
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
|
||||||
damage_none_sizePostResults
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_none_sizePostResult !< size of each post result output
|
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
damage_none_init
|
damage_none_init
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief module initialization
|
!> @brief allocates all neccessary fields, reads information from material configuration file
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine damage_none_init
|
subroutine damage_none_init()
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
use debug, only: &
|
use prec, only: &
|
||||||
debug_level, &
|
pReal, &
|
||||||
debug_constitutive, &
|
pInt
|
||||||
debug_levelBasic
|
|
||||||
use IO, only: &
|
use IO, only: &
|
||||||
IO_timeStamp
|
IO_timeStamp
|
||||||
|
use material
|
||||||
use numerics, only: &
|
use numerics, only: &
|
||||||
worldrank, &
|
worldrank
|
||||||
numerics_integrator
|
|
||||||
use material, only: &
|
|
||||||
phase_damage, &
|
|
||||||
LOCAL_DAMAGE_NONE_label, &
|
|
||||||
LOCAL_DAMAGE_NONE_ID, &
|
|
||||||
material_phase, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
integer(pInt) :: &
|
integer(pInt) :: &
|
||||||
maxNinstance, &
|
homog, &
|
||||||
phase, &
|
NofMyHomog
|
||||||
NofMyPhase, &
|
|
||||||
sizeState, &
|
|
||||||
sizeDotState
|
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
mainProcess: if (worldrank == 0) then
|
||||||
write(6,'(/,a)') ' <<<+- damage_'//LOCAL_DAMAGE_NONE_label//' init -+>>>'
|
write(6,'(/,a)') ' <<<+- damage_'//DAMAGE_none_label//' init -+>>>'
|
||||||
write(6,'(a)') ' $Id$'
|
write(6,'(a)') ' $Id$'
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
#include "compilation_info.f90"
|
#include "compilation_info.f90"
|
||||||
endif mainProcess
|
endif mainProcess
|
||||||
|
|
||||||
maxNinstance = int(count(phase_damage == LOCAL_DAMAGE_NONE_ID),pInt)
|
initializeInstances: do homog = 1_pInt, material_Nhomogenization
|
||||||
if (maxNinstance == 0_pInt) return
|
|
||||||
|
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
myhomog: if (damage_type(homog) == DAMAGE_none_ID) then
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
NofMyHomog = count(material_homog == homog)
|
||||||
|
damageState(homog)%sizeState = 0_pInt
|
||||||
|
damageState(homog)%sizePostResults = 0_pInt
|
||||||
|
allocate(damageState(homog)%state0 (0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(damageState(homog)%subState0(0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(damageState(homog)%state (0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_damage)
|
deallocate(damage(homog)%p)
|
||||||
NofMyPhase=count(material_phase==phase)
|
allocate (damage(homog)%p(1), source=1.0_pReal)
|
||||||
if (phase_damage(phase) == LOCAL_DAMAGE_none_ID) then
|
|
||||||
sizeState = 0_pInt
|
endif myhomog
|
||||||
damageState(phase)%sizeState = sizeState
|
|
||||||
sizeDotState = sizeState
|
|
||||||
damageState(phase)%sizeDotState = sizeDotState
|
|
||||||
damageState(phase)%sizePostResults = 0_pInt
|
|
||||||
allocate(damageState(phase)%state0 (sizeState,NofMyPhase))
|
|
||||||
allocate(damageState(phase)%partionedState0(sizeState,NofMyPhase))
|
|
||||||
allocate(damageState(phase)%subState0 (sizeState,NofMyPhase))
|
|
||||||
allocate(damageState(phase)%state (sizeState,NofMyPhase))
|
|
||||||
allocate(damageState(phase)%state_backup (sizeState,NofMyPhase))
|
|
||||||
allocate(damageState(phase)%aTolState (NofMyPhase))
|
|
||||||
allocate(damageState(phase)%dotState (sizeDotState,NofMyPhase))
|
|
||||||
allocate(damageState(phase)%dotState_backup(sizeDotState,NofMyPhase))
|
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
|
||||||
allocate(damageState(phase)%previousDotState (sizeDotState,NofMyPhase))
|
|
||||||
allocate(damageState(phase)%previousDotState2 (sizeDotState,NofMyPhase))
|
|
||||||
endif
|
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(damageState(phase)%RK4dotState (sizeDotState,NofMyPhase))
|
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
|
||||||
allocate(damageState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase))
|
|
||||||
endif
|
|
||||||
enddo initializeInstances
|
enddo initializeInstances
|
||||||
|
|
||||||
allocate(damage_none_sizePostResults(maxNinstance), source=0_pInt)
|
|
||||||
|
|
||||||
end subroutine damage_none_init
|
end subroutine damage_none_init
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,378 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for non-locally evolving damage field
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module damage_nonlocal
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
damage_nonlocal_sizePostResults !< cumulative size of post results
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
damage_nonlocal_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
damage_nonlocal_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
damage_nonlocal_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
damage_ID
|
||||||
|
end enum
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
damage_nonlocal_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
damage_nonlocal_init, &
|
||||||
|
damage_nonlocal_getSourceAndItsTangent, &
|
||||||
|
damage_nonlocal_getDiffusion33, &
|
||||||
|
damage_nonlocal_getMobility, &
|
||||||
|
damage_nonlocal_putNonLocalDamage, &
|
||||||
|
damage_nonlocal_postResults
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine damage_nonlocal_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
damage_type, &
|
||||||
|
damage_typeInstance, &
|
||||||
|
homogenization_Noutput, &
|
||||||
|
DAMAGE_nonlocal_label, &
|
||||||
|
DAMAGE_nonlocal_ID, &
|
||||||
|
material_homog, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
damageState, &
|
||||||
|
damageMapping, &
|
||||||
|
damage, &
|
||||||
|
material_partHomogenization
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,section,instance,o
|
||||||
|
integer(pInt) :: sizeState
|
||||||
|
integer(pInt) :: NofMyHomog
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- damage_'//DAMAGE_nonlocal_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(damage_type == DAMAGE_nonlocal_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
allocate(damage_nonlocal_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(damage_nonlocal_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(damage_nonlocal_output (maxval(homogenization_Noutput),maxNinstance))
|
||||||
|
damage_nonlocal_output = ''
|
||||||
|
allocate(damage_nonlocal_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID)
|
||||||
|
allocate(damage_nonlocal_Noutput (maxNinstance), source=0_pInt)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
section = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partHomogenization)! wind forward to <homogenization>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
|
section = section + 1_pInt ! advance homog section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (section > 0_pInt ) then; if (damage_type(section) == DAMAGE_nonlocal_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = damage_typeInstance(section) ! which instance of my damage is present homog
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('damage')
|
||||||
|
damage_nonlocal_Noutput(instance) = damage_nonlocal_Noutput(instance) + 1_pInt
|
||||||
|
damage_nonlocal_outputID(damage_nonlocal_Noutput(instance),instance) = damage_ID
|
||||||
|
damage_nonlocal_output(damage_nonlocal_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
initializeInstances: do section = 1_pInt, size(damage_type)
|
||||||
|
if (damage_type(section) == DAMAGE_nonlocal_ID) then
|
||||||
|
NofMyHomog=count(material_homog==section)
|
||||||
|
instance = damage_typeInstance(section)
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,damage_nonlocal_Noutput(instance)
|
||||||
|
select case(damage_nonlocal_outputID(o,instance))
|
||||||
|
case(damage_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
damage_nonlocal_sizePostResult(o,instance) = mySize
|
||||||
|
damage_nonlocal_sizePostResults(instance) = damage_nonlocal_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
|
||||||
|
! allocate state arrays
|
||||||
|
sizeState = 0_pInt
|
||||||
|
damageState(section)%sizeState = sizeState
|
||||||
|
damageState(section)%sizePostResults = damage_nonlocal_sizePostResults(instance)
|
||||||
|
allocate(damageState(section)%state0 (sizeState,NofMyHomog))
|
||||||
|
allocate(damageState(section)%subState0(sizeState,NofMyHomog))
|
||||||
|
allocate(damageState(section)%state (sizeState,NofMyHomog))
|
||||||
|
|
||||||
|
nullify(damageMapping(section)%p)
|
||||||
|
damageMapping(section)%p => mappingHomogenization(1,:,:)
|
||||||
|
deallocate(damage(section)%p)
|
||||||
|
allocate(damage(section)%p(NofMyHomog), source=1.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine damage_nonlocal_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates homogenized damage driving forces
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine damage_nonlocal_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
mappingConstitutive, &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
SOURCE_damage_isoBrittle_ID, &
|
||||||
|
SOURCE_damage_isoDuctile_ID, &
|
||||||
|
SOURCE_damage_anisoBrittle_ID, &
|
||||||
|
SOURCE_damage_anisoDuctile_ID
|
||||||
|
use source_damage_isoBrittle, only: &
|
||||||
|
source_damage_isobrittle_getRateAndItsTangent
|
||||||
|
use source_damage_isoDuctile, only: &
|
||||||
|
source_damage_isoductile_getRateAndItsTangent
|
||||||
|
use source_damage_anisoBrittle, only: &
|
||||||
|
source_damage_anisobrittle_getRateAndItsTangent
|
||||||
|
use source_damage_anisoDuctile, only: &
|
||||||
|
source_damage_anisoductile_getRateAndItsTangent
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
grain, &
|
||||||
|
source
|
||||||
|
real(pReal) :: &
|
||||||
|
phiDot, dPhiDot_dPhi, localphiDot, dLocalphiDot_dPhi
|
||||||
|
|
||||||
|
phiDot = 0.0_pReal
|
||||||
|
dPhiDot_dPhi = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
phase = mappingConstitutive(2,grain,ip,el)
|
||||||
|
do source = 1_pInt, phase_Nsources(phase)
|
||||||
|
select case(phase_source(source,phase))
|
||||||
|
case (SOURCE_damage_isoBrittle_ID)
|
||||||
|
call source_damage_isobrittle_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, grain, ip, el)
|
||||||
|
|
||||||
|
case (SOURCE_damage_isoDuctile_ID)
|
||||||
|
call source_damage_isoductile_getRateAndItsTangent (localphiDot, dLocalphiDot_dPhi, phi, grain, ip, el)
|
||||||
|
|
||||||
|
case (SOURCE_damage_anisoBrittle_ID)
|
||||||
|
call source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, grain, ip, el)
|
||||||
|
|
||||||
|
case (SOURCE_damage_anisoDuctile_ID)
|
||||||
|
call source_damage_anisoductile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, grain, ip, el)
|
||||||
|
|
||||||
|
case default
|
||||||
|
localphiDot = 0.0_pReal
|
||||||
|
dLocalphiDot_dPhi = 0.0_pReal
|
||||||
|
|
||||||
|
end select
|
||||||
|
phiDot = phiDot + localphiDot
|
||||||
|
dPhiDot_dPhi = dPhiDot_dPhi + dLocalphiDot_dPhi
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
phiDot = phiDot/homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
dPhiDot_dPhi = dPhiDot_dPhi/homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
|
||||||
|
end subroutine damage_nonlocal_getSourceAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized non local damage diffusion tensor in reference configuration
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function damage_nonlocal_getDiffusion33(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_DamageDiffusion33
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_phase, &
|
||||||
|
mappingHomogenization
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), dimension(3,3) :: &
|
||||||
|
damage_nonlocal_getDiffusion33
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
grain
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
damage_nonlocal_getDiffusion33 = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(homog)
|
||||||
|
damage_nonlocal_getDiffusion33 = damage_nonlocal_getDiffusion33 + &
|
||||||
|
crystallite_push33ToRef(grain,ip,el,lattice_DamageDiffusion33(1:3,1:3,material_phase(grain,ip,el)))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
damage_nonlocal_getDiffusion33 = &
|
||||||
|
damage_nonlocal_getDiffusion33/ &
|
||||||
|
homogenization_Ngrains(homog)
|
||||||
|
|
||||||
|
end function damage_nonlocal_getDiffusion33
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief Returns homogenized nonlocal damage mobility
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
real(pReal) function damage_nonlocal_getMobility(ip,el)
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_damageMobility
|
||||||
|
use material, only: &
|
||||||
|
material_phase, &
|
||||||
|
homogenization_Ngrains
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
integer(pInt) :: &
|
||||||
|
ipc
|
||||||
|
|
||||||
|
damage_nonlocal_getMobility = 0.0_pReal
|
||||||
|
|
||||||
|
do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
damage_nonlocal_getMobility = damage_nonlocal_getMobility + lattice_DamageMobility(material_phase(ipc,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
damage_nonlocal_getMobility = damage_nonlocal_getMobility /homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function damage_nonlocal_getMobility
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief updated nonlocal damage field with solution from damage phase field PDE
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine damage_nonlocal_putNonLocalDamage(phi,ip,el)
|
||||||
|
use material, only: &
|
||||||
|
material_homog, &
|
||||||
|
damageMapping, &
|
||||||
|
damage
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
offset
|
||||||
|
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
offset = damageMapping(homog)%p(ip,el)
|
||||||
|
damage(homog)%p(offset) = phi
|
||||||
|
|
||||||
|
end subroutine damage_nonlocal_putNonLocalDamage
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of damage results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function damage_nonlocal_postResults(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
damage_typeInstance, &
|
||||||
|
damage
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(damage_nonlocal_sizePostResults(damage_typeInstance(mappingHomogenization(2,ip,el)))) :: &
|
||||||
|
damage_nonlocal_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, homog, offset, o, c
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = mappingHomogenization(1,ip,el)
|
||||||
|
instance = damage_typeInstance(homog)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
damage_nonlocal_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,damage_nonlocal_Noutput(instance)
|
||||||
|
select case(damage_nonlocal_outputID(o,instance))
|
||||||
|
|
||||||
|
case (damage_ID)
|
||||||
|
damage_nonlocal_postResults(c+1_pInt) = damage(homog)%p(offset)
|
||||||
|
c = c + 1
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function damage_nonlocal_postResults
|
||||||
|
|
||||||
|
end module damage_nonlocal
|
|
@ -1,510 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! $Id$
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @author Luv Sharma, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @brief material subroutine incoprorating isotropic brittle damage
|
|
||||||
!> @details to be done
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module damage_phaseField
|
|
||||||
use prec, only: &
|
|
||||||
pReal, &
|
|
||||||
pInt
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
private
|
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
|
||||||
damage_phaseField_sizePostResults !< cumulative size of post results
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_phaseField_sizePostResult !< size of each post result output
|
|
||||||
|
|
||||||
character(len=64), dimension(:,:), allocatable, target, public :: &
|
|
||||||
damage_phaseField_output !< name of each post result output
|
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, target, public :: &
|
|
||||||
damage_phaseField_Noutput !< number of outputs per instance of this damage
|
|
||||||
|
|
||||||
real(pReal), dimension(:), allocatable, private :: &
|
|
||||||
damage_phaseField_aTol, &
|
|
||||||
damage_phaseField_surfaceEnergy, &
|
|
||||||
damage_phaseField_vacancyFormationEnergy, &
|
|
||||||
damage_phaseField_atomicVol, &
|
|
||||||
damage_phaseField_specificVacancyFormationEnergy
|
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: undefined_ID, &
|
|
||||||
local_damage_ID
|
|
||||||
end enum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11 ToDo
|
|
||||||
|
|
||||||
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
|
||||||
damage_phaseField_outputID !< ID of each post result output
|
|
||||||
|
|
||||||
|
|
||||||
public :: &
|
|
||||||
damage_phaseField_init, &
|
|
||||||
damage_phaseField_stateInit, &
|
|
||||||
damage_phaseField_aTolState, &
|
|
||||||
damage_phaseField_microstructure, &
|
|
||||||
damage_phaseField_getDamage, &
|
|
||||||
damage_phaseField_putLocalDamage, &
|
|
||||||
damage_phaseField_getLocalDamage, &
|
|
||||||
damage_phaseField_getDamageDiffusion33, &
|
|
||||||
damage_phaseField_getDamagedC66, &
|
|
||||||
damage_phaseField_postResults
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief module initialization
|
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_phaseField_init(fileUnit)
|
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
|
||||||
use debug, only: &
|
|
||||||
debug_level,&
|
|
||||||
debug_constitutive,&
|
|
||||||
debug_levelBasic
|
|
||||||
use IO, only: &
|
|
||||||
IO_read, &
|
|
||||||
IO_lc, &
|
|
||||||
IO_getTag, &
|
|
||||||
IO_isBlank, &
|
|
||||||
IO_stringPos, &
|
|
||||||
IO_stringValue, &
|
|
||||||
IO_floatValue, &
|
|
||||||
IO_intValue, &
|
|
||||||
IO_warning, &
|
|
||||||
IO_error, &
|
|
||||||
IO_timeStamp, &
|
|
||||||
IO_EOF
|
|
||||||
use material, only: &
|
|
||||||
phase_damage, &
|
|
||||||
phase_damageInstance, &
|
|
||||||
phase_Noutput, &
|
|
||||||
LOCAL_damage_phaseField_label, &
|
|
||||||
LOCAL_damage_phaseField_ID, &
|
|
||||||
material_phase, &
|
|
||||||
damageState, &
|
|
||||||
MATERIAL_partPhase
|
|
||||||
use numerics,only: &
|
|
||||||
worldrank, &
|
|
||||||
numerics_integrator
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: fileUnit
|
|
||||||
|
|
||||||
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
|
||||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
|
||||||
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,o
|
|
||||||
integer(pInt) :: sizeState, sizeDotState
|
|
||||||
integer(pInt) :: NofMyPhase
|
|
||||||
character(len=65536) :: &
|
|
||||||
tag = '', &
|
|
||||||
line = ''
|
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
|
||||||
write(6,'(/,a)') ' <<<+- damage_'//LOCAL_damage_phaseField_label//' init -+>>>'
|
|
||||||
write(6,'(a)') ' $Id$'
|
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
|
||||||
#include "compilation_info.f90"
|
|
||||||
endif mainProcess
|
|
||||||
|
|
||||||
maxNinstance = int(count(phase_damage == LOCAL_damage_phaseField_ID),pInt)
|
|
||||||
if (maxNinstance == 0_pInt) return
|
|
||||||
|
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
|
||||||
|
|
||||||
allocate(damage_phaseField_sizePostResults(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_phaseField_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
|
||||||
allocate(damage_phaseField_output(maxval(phase_Noutput),maxNinstance))
|
|
||||||
damage_phaseField_output = ''
|
|
||||||
allocate(damage_phaseField_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
|
||||||
allocate(damage_phaseField_Noutput(maxNinstance), source=0_pInt)
|
|
||||||
allocate(damage_phaseField_surfaceEnergy(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_phaseField_vacancyFormationEnergy(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_phaseField_atomicVol(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_phaseField_specificVacancyFormationEnergy(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(damage_phaseField_aTol(maxNinstance), source=0.0_pReal)
|
|
||||||
|
|
||||||
rewind(fileUnit)
|
|
||||||
phase = 0_pInt
|
|
||||||
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
if (IO_isBlank(line)) cycle ! skip empty lines
|
|
||||||
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
|
||||||
line = IO_read(fileUnit, .true.) ! reset IO_read
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
|
||||||
phase = phase + 1_pInt ! advance phase section counter
|
|
||||||
cycle ! skip to next line
|
|
||||||
endif
|
|
||||||
if (phase > 0_pInt ) then; if (phase_damage(phase) == LOCAL_damage_phaseField_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
|
||||||
instance = phase_damageInstance(phase) ! which instance of my damage is present phase
|
|
||||||
positions = IO_stringPos(line,MAXNCHUNKS)
|
|
||||||
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
|
||||||
select case(tag)
|
|
||||||
case ('(output)')
|
|
||||||
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
|
||||||
case ('local_damage')
|
|
||||||
damage_phaseField_Noutput(instance) = damage_phaseField_Noutput(instance) + 1_pInt
|
|
||||||
damage_phaseField_outputID(damage_phaseField_Noutput(instance),instance) = local_damage_ID
|
|
||||||
damage_phaseField_output(damage_phaseField_Noutput(instance),instance) = &
|
|
||||||
IO_lc(IO_stringValue(line,positions,2_pInt))
|
|
||||||
end select
|
|
||||||
|
|
||||||
case ('surfaceenergy')
|
|
||||||
damage_phaseField_surfaceEnergy(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('vacancyformationenergy')
|
|
||||||
damage_phaseField_vacancyFormationEnergy(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('atomicvolume')
|
|
||||||
damage_phaseField_atomicVol(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('atol_damage')
|
|
||||||
damage_phaseField_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
end select
|
|
||||||
endif; endif
|
|
||||||
enddo parsingFile
|
|
||||||
|
|
||||||
|
|
||||||
sanityChecks: do phase = 1_pInt, size(phase_damage)
|
|
||||||
myPhase: if (phase_damage(phase) == LOCAL_damage_phaseField_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
! sanity checks
|
|
||||||
if (damage_phaseField_aTol(instance) < 0.0_pReal) &
|
|
||||||
damage_phaseField_aTol(instance) = 1.0e-3_pReal ! default absolute tolerance 1e-3
|
|
||||||
if (damage_phaseField_surfaceEnergy(instance) <= 0.0_pReal) &
|
|
||||||
call IO_error(211_pInt,el=instance,ext_msg='surfaceEnergy ('//LOCAL_damage_phaseField_LABEL//')')
|
|
||||||
endif myPhase
|
|
||||||
enddo sanityChecks
|
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_damage)
|
|
||||||
if (phase_damage(phase) == LOCAL_damage_phaseField_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! pre-calculating derived material parameters
|
|
||||||
damage_phaseField_specificVacancyFormationEnergy(instance) = &
|
|
||||||
damage_phaseField_vacancyFormationEnergy(instance)/damage_phaseField_atomicVol(instance)
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! Determine size of postResults array
|
|
||||||
outputsLoop: do o = 1_pInt,damage_phaseField_Noutput(instance)
|
|
||||||
select case(damage_phaseField_outputID(o,instance))
|
|
||||||
case(local_damage_ID)
|
|
||||||
mySize = 1_pInt
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (mySize > 0_pInt) then ! any meaningful output found
|
|
||||||
damage_phaseField_sizePostResult(o,instance) = mySize
|
|
||||||
damage_phaseField_sizePostResults(instance) = damage_phaseField_sizePostResults(instance) + mySize
|
|
||||||
endif
|
|
||||||
enddo outputsLoop
|
|
||||||
|
|
||||||
! Determine size of state array
|
|
||||||
sizeDotState = 0_pInt
|
|
||||||
sizeState = 2_pInt
|
|
||||||
|
|
||||||
damageState(phase)%sizeState = sizeState
|
|
||||||
damageState(phase)%sizeDotState = sizeDotState
|
|
||||||
damageState(phase)%sizePostResults = damage_phaseField_sizePostResults(instance)
|
|
||||||
allocate(damageState(phase)%aTolState (sizeState), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
|
|
||||||
allocate(damageState(phase)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
|
||||||
allocate(damageState(phase)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(damageState(phase)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
endif
|
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(damageState(phase)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
|
||||||
allocate(damageState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
|
||||||
|
|
||||||
call damage_phaseField_stateInit(phase)
|
|
||||||
call damage_phaseField_aTolState(phase,instance)
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo initializeInstances
|
|
||||||
end subroutine damage_phaseField_init
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant NEW state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_phaseField_stateInit(phase)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: phase !< number specifying the phase of the damage
|
|
||||||
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempState
|
|
||||||
|
|
||||||
tempState = 1.0_pReal
|
|
||||||
damageState(phase)%state = spread(tempState,2,size(damageState(phase)%state(1,:)))
|
|
||||||
damageState(phase)%state0 = damageState(phase)%state
|
|
||||||
damageState(phase)%partionedState0 = damageState(phase)%state
|
|
||||||
end subroutine damage_phaseField_stateInit
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_phaseField_aTolState(phase,instance)
|
|
||||||
use material, only: &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
phase, &
|
|
||||||
instance ! number specifying the current instance of the damage
|
|
||||||
real(pReal), dimension(damageState(phase)%sizeState) :: tempTol
|
|
||||||
|
|
||||||
tempTol = damage_phaseField_aTol(instance)
|
|
||||||
damageState(phase)%aTolState = tempTol
|
|
||||||
end subroutine damage_phaseField_aTolState
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief calculates derived quantities from state
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_phaseField_microstructure(C, Fe, Cv, subdt, ipc, ip, el)
|
|
||||||
use numerics, only: &
|
|
||||||
residualStiffness
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance, &
|
|
||||||
damageState
|
|
||||||
use math, only : &
|
|
||||||
math_mul33x33, &
|
|
||||||
math_mul66x6, &
|
|
||||||
math_Mandel33to6, &
|
|
||||||
math_transpose33, &
|
|
||||||
math_I3
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_DamageMobility
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
|
||||||
Fe
|
|
||||||
real(pReal), intent(in), dimension(6,6) :: &
|
|
||||||
C
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
Cv
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
subdt
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent, instance
|
|
||||||
real(pReal) :: &
|
|
||||||
strain(6), &
|
|
||||||
stress(6), &
|
|
||||||
drivingForce
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
strain = 0.5_pReal*math_Mandel33to6(math_mul33x33(math_transpose33(Fe),Fe)-math_I3)
|
|
||||||
stress = math_mul66x6(C,strain)
|
|
||||||
|
|
||||||
drivingForce = (1.0_pReal - Cv)*(1.0_pReal - Cv) + &
|
|
||||||
(Cv*damage_phaseField_specificVacancyFormationEnergy(instance) + &
|
|
||||||
sum(abs(stress*strain)))/damage_phaseField_surfaceEnergy(instance)
|
|
||||||
damageState(phase)%state(2,constituent) = &
|
|
||||||
max(residualStiffness,(1.0_pReal - Cv)*(1.0_pReal - Cv)/drivingForce)
|
|
||||||
|
|
||||||
damageState(phase)%state(1,constituent) = &
|
|
||||||
damageState(phase)%state(2,constituent) + &
|
|
||||||
(damageState(phase)%subState0(1,constituent) - damageState(phase)%state(2,constituent))* &
|
|
||||||
exp(-2.0_pReal*subdt*drivingForce/lattice_DamageMobility(phase))
|
|
||||||
|
|
||||||
end subroutine damage_phaseField_microstructure
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_phaseField_getDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
material_homog, &
|
|
||||||
mappingHomogenization, &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState, &
|
|
||||||
fieldDamage, &
|
|
||||||
field_damage_type, &
|
|
||||||
FIELD_DAMAGE_LOCAL_ID, &
|
|
||||||
FIELD_DAMAGE_NONLOCAL_ID
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: damage_phaseField_getDamage
|
|
||||||
|
|
||||||
select case(field_damage_type(material_homog(ip,el)))
|
|
||||||
case default
|
|
||||||
damage_phaseField_getDamage = damageState(mappingConstitutive(2,ipc,ip,el))% &
|
|
||||||
state0(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
case (FIELD_DAMAGE_NONLOCAL_ID)
|
|
||||||
damage_phaseField_getDamage = fieldDamage(material_homog(ip,el))% &
|
|
||||||
field(1,mappingHomogenization(1,ip,el)) ! Taylor type
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
end function damage_phaseField_getDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns temperature based on local damage model state layout
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine damage_phaseField_putLocalDamage(ipc, ip, el, localDamage)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: localDamage
|
|
||||||
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el)) = &
|
|
||||||
localDamage
|
|
||||||
|
|
||||||
end subroutine damage_phaseField_putLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns local damage
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_phaseField_getLocalDamage(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: damage_phaseField_getLocalDamage
|
|
||||||
|
|
||||||
damage_phaseField_getLocalDamage = &
|
|
||||||
damageState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
end function damage_phaseField_getLocalDamage
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns brittle damage diffusion tensor
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_phaseField_getDamageDiffusion33(ipc, ip, el)
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_DamageDiffusion33
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), dimension(3,3) :: &
|
|
||||||
damage_phaseField_getDamageDiffusion33
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
damage_phaseField_getDamageDiffusion33 = &
|
|
||||||
lattice_DamageDiffusion33(1:3,1:3,phase)
|
|
||||||
|
|
||||||
end function damage_phaseField_getDamageDiffusion33
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns brittle damaged stiffness tensor
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function damage_phaseField_getDamagedC66(C, ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in), dimension(6,6) :: &
|
|
||||||
C
|
|
||||||
real(pReal), dimension(6,6) :: &
|
|
||||||
damage_phaseField_getDamagedC66
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent
|
|
||||||
real(pReal) :: &
|
|
||||||
damage
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
damage = damage_phaseField_getDamage(ipc, ip, el)
|
|
||||||
|
|
||||||
damage_phaseField_getDamagedC66 = &
|
|
||||||
damage*damage*C
|
|
||||||
|
|
||||||
end function damage_phaseField_getDamagedC66
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief return array of constitutive results
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function damage_phaseField_postResults(ipc,ip,el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_damageInstance,&
|
|
||||||
damageState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), dimension(damage_phaseField_sizePostResults(phase_damageInstance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
|
||||||
damage_phaseField_postResults
|
|
||||||
|
|
||||||
integer(pInt) :: &
|
|
||||||
instance, phase, constituent, o, c
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_damageInstance(phase)
|
|
||||||
|
|
||||||
c = 0_pInt
|
|
||||||
damage_phaseField_postResults = 0.0_pReal
|
|
||||||
|
|
||||||
do o = 1_pInt,damage_phaseField_Noutput(instance)
|
|
||||||
select case(damage_phaseField_outputID(o,instance))
|
|
||||||
case (local_damage_ID)
|
|
||||||
damage_phaseField_postResults(c+1_pInt) = damageState(phase)%state(2,constituent)
|
|
||||||
c = c + 1
|
|
||||||
|
|
||||||
end select
|
|
||||||
enddo
|
|
||||||
end function damage_phaseField_postResults
|
|
||||||
|
|
||||||
end module damage_phaseField
|
|
File diff suppressed because it is too large
Load Diff
|
@ -336,7 +336,6 @@ subroutine homogenization_RGC_partitionDeformation(F,avgF,ip,el)
|
||||||
use material, only: &
|
use material, only: &
|
||||||
homogenization_maxNgrains, &
|
homogenization_maxNgrains, &
|
||||||
homogenization_Ngrains,&
|
homogenization_Ngrains,&
|
||||||
mappingHomogenization, &
|
|
||||||
homogenization_typeInstance
|
homogenization_typeInstance
|
||||||
use FEsolving, only: &
|
use FEsolving, only: &
|
||||||
theInc,&
|
theInc,&
|
||||||
|
@ -903,7 +902,6 @@ subroutine homogenization_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,
|
||||||
use mesh, only: mesh_element
|
use mesh, only: mesh_element
|
||||||
use material, only: &
|
use material, only: &
|
||||||
homogenization_maxNgrains, &
|
homogenization_maxNgrains, &
|
||||||
mappingHomogenization, &
|
|
||||||
homogenization_Ngrains, &
|
homogenization_Ngrains, &
|
||||||
homogenization_typeInstance
|
homogenization_typeInstance
|
||||||
use math, only: math_Plain3333to99
|
use math, only: math_Plain3333to99
|
||||||
|
|
|
@ -0,0 +1,544 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for conservative transport of solute hydrogen
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module hydrogenflux_cahnhilliard
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
hydrogenflux_cahnhilliard_sizePostResults !< cumulative size of post results
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
hydrogenflux_cahnhilliard_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
hydrogenflux_cahnhilliard_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
hydrogenflux_cahnhilliard_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
hydrogenflux_cahnhilliard_formationEnergyCoeff, &
|
||||||
|
hydrogenflux_cahnhilliard_kBCoeff
|
||||||
|
|
||||||
|
real(pReal), parameter, private :: &
|
||||||
|
kB = 1.3806488e-23_pReal !< Boltzmann constant in J/Kelvin
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
hydrogenConc_ID
|
||||||
|
end enum
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
hydrogenflux_cahnhilliard_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
hydrogenflux_cahnhilliard_init, &
|
||||||
|
hydrogenflux_cahnhilliard_getMobility33, &
|
||||||
|
hydrogenflux_cahnhilliard_getDiffusion33, &
|
||||||
|
hydrogenflux_cahnhilliard_getFormationEnergy, &
|
||||||
|
hydrogenflux_cahnhilliard_KinematicChemPotAndItsTangent, &
|
||||||
|
hydrogenflux_cahnhilliard_getChemPotAndItsTangent, &
|
||||||
|
hydrogenflux_cahnhilliard_putHydrogenConcAndItsRate, &
|
||||||
|
hydrogenflux_cahnhilliard_postResults
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine hydrogenflux_cahnhilliard_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_hydrogenVol
|
||||||
|
use material, only: &
|
||||||
|
hydrogenflux_type, &
|
||||||
|
hydrogenflux_typeInstance, &
|
||||||
|
homogenization_Noutput, &
|
||||||
|
HYDROGENFLUX_cahnhilliard_label, &
|
||||||
|
HYDROGENFLUX_cahnhilliard_ID, &
|
||||||
|
material_homog, &
|
||||||
|
material_Nphase, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
hydrogenfluxState, &
|
||||||
|
hydrogenfluxMapping, &
|
||||||
|
hydrogenConc, &
|
||||||
|
hydrogenConcRate, &
|
||||||
|
material_partHomogenization, &
|
||||||
|
material_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,section,instance,o
|
||||||
|
integer(pInt) :: sizeState
|
||||||
|
integer(pInt) :: NofMyHomog
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- hydrogenflux_'//HYDROGENFLUX_cahnhilliard_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(hydrogenflux_type == HYDROGENFLUX_cahnhilliard_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
allocate(hydrogenflux_cahnhilliard_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(hydrogenflux_cahnhilliard_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(hydrogenflux_cahnhilliard_output (maxval(homogenization_Noutput),maxNinstance))
|
||||||
|
hydrogenflux_cahnhilliard_output = ''
|
||||||
|
allocate(hydrogenflux_cahnhilliard_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID)
|
||||||
|
allocate(hydrogenflux_cahnhilliard_Noutput (maxNinstance), source=0_pInt)
|
||||||
|
|
||||||
|
allocate(hydrogenflux_cahnhilliard_kBCoeff (material_Nphase), source=0.0_pReal)
|
||||||
|
allocate(hydrogenflux_cahnhilliard_formationEnergyCoeff(material_Nphase), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
section = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partHomogenization)! wind forward to <homogenization>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingHomog: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
|
section = section + 1_pInt ! advance homog section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (section > 0_pInt ) then; if (hydrogenflux_type(section) == HYDROGENFLUX_cahnhilliard_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = hydrogenflux_typeInstance(section) ! which instance of my hydrogenflux is present homog
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('hydrogenconc')
|
||||||
|
hydrogenflux_cahnhilliard_Noutput(instance) = hydrogenflux_cahnhilliard_Noutput(instance) + 1_pInt
|
||||||
|
hydrogenflux_cahnhilliard_outputID(hydrogenflux_cahnhilliard_Noutput(instance),instance) = hydrogenConc_ID
|
||||||
|
hydrogenflux_cahnhilliard_output(hydrogenflux_cahnhilliard_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingHomog
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
section = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partPhase) ! wind forward to <homogenization>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingPhase: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
|
section = section + 1_pInt ! advance homog section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (section > 0_pInt ) then; if (hydrogenflux_type(section) == HYDROGENFLUX_cahnhilliard_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('hydrogenformationenergy')
|
||||||
|
hydrogenflux_cahnhilliard_formationEnergyCoeff(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingPhase
|
||||||
|
|
||||||
|
initializeInstances: do section = 1_pInt, size(hydrogenflux_type)
|
||||||
|
if (hydrogenflux_type(section) == HYDROGENFLUX_cahnhilliard_ID) then
|
||||||
|
NofMyHomog=count(material_homog==section)
|
||||||
|
instance = hydrogenflux_typeInstance(section)
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,hydrogenflux_cahnhilliard_Noutput(instance)
|
||||||
|
select case(hydrogenflux_cahnhilliard_outputID(o,instance))
|
||||||
|
case(hydrogenConc_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
hydrogenflux_cahnhilliard_sizePostResult(o,instance) = mySize
|
||||||
|
hydrogenflux_cahnhilliard_sizePostResults(instance) = hydrogenflux_cahnhilliard_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
|
||||||
|
! allocate state arrays
|
||||||
|
sizeState = 0_pInt
|
||||||
|
hydrogenfluxState(section)%sizeState = sizeState
|
||||||
|
hydrogenfluxState(section)%sizePostResults = hydrogenflux_cahnhilliard_sizePostResults(instance)
|
||||||
|
allocate(hydrogenfluxState(section)%state0 (sizeState,NofMyHomog))
|
||||||
|
allocate(hydrogenfluxState(section)%subState0(sizeState,NofMyHomog))
|
||||||
|
allocate(hydrogenfluxState(section)%state (sizeState,NofMyHomog))
|
||||||
|
|
||||||
|
nullify(hydrogenfluxMapping(section)%p)
|
||||||
|
hydrogenfluxMapping(section)%p => mappingHomogenization(1,:,:)
|
||||||
|
deallocate(hydrogenConc (section)%p)
|
||||||
|
deallocate(hydrogenConcRate(section)%p)
|
||||||
|
allocate (hydrogenConc (section)%p(NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate (hydrogenConcRate(section)%p(NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
|
||||||
|
initializeParams: do section = 1_pInt, material_Nphase
|
||||||
|
hydrogenflux_cahnhilliard_kBCoeff(section) = &
|
||||||
|
kB/ &
|
||||||
|
hydrogenflux_cahnhilliard_formationEnergyCoeff(section)
|
||||||
|
hydrogenflux_cahnhilliard_formationEnergyCoeff(section) = &
|
||||||
|
hydrogenflux_cahnhilliard_formationEnergyCoeff(section)/ &
|
||||||
|
lattice_hydrogenVol(section)
|
||||||
|
enddo initializeParams
|
||||||
|
|
||||||
|
end subroutine hydrogenflux_cahnhilliard_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized solute mobility tensor in reference configuration
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function hydrogenflux_cahnhilliard_getMobility33(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_hydrogenfluxMobility33
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), dimension(3,3) :: &
|
||||||
|
hydrogenflux_cahnhilliard_getMobility33
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain
|
||||||
|
|
||||||
|
hydrogenflux_cahnhilliard_getMobility33 = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
hydrogenflux_cahnhilliard_getMobility33 = hydrogenflux_cahnhilliard_getMobility33 + &
|
||||||
|
crystallite_push33ToRef(grain,ip,el,lattice_hydrogenfluxMobility33(:,:,material_phase(grain,ip,el)))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
hydrogenflux_cahnhilliard_getMobility33 = &
|
||||||
|
hydrogenflux_cahnhilliard_getMobility33/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function hydrogenflux_cahnhilliard_getMobility33
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized solute nonlocal diffusion tensor in reference configuration
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function hydrogenflux_cahnhilliard_getDiffusion33(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_hydrogenfluxDiffusion33
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), dimension(3,3) :: &
|
||||||
|
hydrogenflux_cahnhilliard_getDiffusion33
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain
|
||||||
|
|
||||||
|
hydrogenflux_cahnhilliard_getDiffusion33 = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
hydrogenflux_cahnhilliard_getDiffusion33 = hydrogenflux_cahnhilliard_getDiffusion33 + &
|
||||||
|
crystallite_push33ToRef(grain,ip,el,lattice_hydrogenfluxDiffusion33(:,:,material_phase(grain,ip,el)))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
hydrogenflux_cahnhilliard_getDiffusion33 = &
|
||||||
|
hydrogenflux_cahnhilliard_getDiffusion33/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function hydrogenflux_cahnhilliard_getDiffusion33
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized solution energy
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function hydrogenflux_cahnhilliard_getFormationEnergy(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal) :: &
|
||||||
|
hydrogenflux_cahnhilliard_getFormationEnergy
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain
|
||||||
|
|
||||||
|
hydrogenflux_cahnhilliard_getFormationEnergy = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
hydrogenflux_cahnhilliard_getFormationEnergy = hydrogenflux_cahnhilliard_getFormationEnergy + &
|
||||||
|
hydrogenflux_cahnhilliard_formationEnergyCoeff(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
hydrogenflux_cahnhilliard_getFormationEnergy = &
|
||||||
|
hydrogenflux_cahnhilliard_getFormationEnergy/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function hydrogenflux_cahnhilliard_getFormationEnergy
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized hydrogen entropy coefficient
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function hydrogenflux_cahnhilliard_getEntropicCoeff(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_homog, &
|
||||||
|
material_phase, &
|
||||||
|
temperature, &
|
||||||
|
thermalMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal) :: &
|
||||||
|
hydrogenflux_cahnhilliard_getEntropicCoeff
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain
|
||||||
|
|
||||||
|
hydrogenflux_cahnhilliard_getEntropicCoeff = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(material_homog(ip,el))
|
||||||
|
hydrogenflux_cahnhilliard_getEntropicCoeff = hydrogenflux_cahnhilliard_getEntropicCoeff + &
|
||||||
|
hydrogenflux_cahnhilliard_kBCoeff(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
hydrogenflux_cahnhilliard_getEntropicCoeff = &
|
||||||
|
hydrogenflux_cahnhilliard_getEntropicCoeff* &
|
||||||
|
temperature(material_homog(ip,el))%p(thermalMapping(material_homog(ip,el))%p(ip,el))/ &
|
||||||
|
homogenization_Ngrains(material_homog(ip,el))
|
||||||
|
|
||||||
|
end function hydrogenflux_cahnhilliard_getEntropicCoeff
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized kinematic contribution to chemical potential
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine hydrogenflux_cahnhilliard_KinematicChemPotAndItsTangent(KPot, dKPot_dCh, Ch, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_homog, &
|
||||||
|
phase_kinematics, &
|
||||||
|
phase_Nkinematics, &
|
||||||
|
material_phase, &
|
||||||
|
KINEMATICS_hydrogen_strain_ID
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_Tstar_v, &
|
||||||
|
crystallite_Fi0, &
|
||||||
|
crystallite_Fi
|
||||||
|
use kinematics_hydrogen_strain, only: &
|
||||||
|
kinematics_hydrogen_strain_ChemPotAndItsTangent
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
Ch
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
KPot, dKPot_dCh
|
||||||
|
real(pReal) :: &
|
||||||
|
my_KPot, my_dKPot_dCh
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain, kinematics
|
||||||
|
|
||||||
|
KPot = 0.0_pReal
|
||||||
|
dKPot_dCh = 0.0_pReal
|
||||||
|
do grain = 1_pInt,homogenization_Ngrains(material_homog(ip,el))
|
||||||
|
do kinematics = 1_pInt, phase_Nkinematics(material_phase(grain,ip,el))
|
||||||
|
select case (phase_kinematics(kinematics,material_phase(grain,ip,el)))
|
||||||
|
case (KINEMATICS_hydrogen_strain_ID)
|
||||||
|
call kinematics_hydrogen_strain_ChemPotAndItsTangent(my_KPot, my_dKPot_dCh, &
|
||||||
|
crystallite_Tstar_v(1:6,grain,ip,el), &
|
||||||
|
crystallite_Fi0(1:3,1:3,grain,ip,el), &
|
||||||
|
crystallite_Fi (1:3,1:3,grain,ip,el), &
|
||||||
|
grain,ip, el)
|
||||||
|
|
||||||
|
case default
|
||||||
|
my_KPot = 0.0_pReal
|
||||||
|
my_dKPot_dCh = 0.0_pReal
|
||||||
|
|
||||||
|
end select
|
||||||
|
KPot = KPot + my_KPot/hydrogenflux_cahnhilliard_formationEnergyCoeff(material_phase(grain,ip,el))
|
||||||
|
dKPot_dCh = dKPot_dCh + my_dKPot_dCh/hydrogenflux_cahnhilliard_formationEnergyCoeff(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
KPot = KPot/homogenization_Ngrains(material_homog(ip,el))
|
||||||
|
dKPot_dCh = dKPot_dCh/homogenization_Ngrains(material_homog(ip,el))
|
||||||
|
|
||||||
|
end subroutine hydrogenflux_cahnhilliard_KinematicChemPotAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized chemical potential
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine hydrogenflux_cahnhilliard_getChemPotAndItsTangent(ChemPot,dChemPot_dCh,Ch,ip,el)
|
||||||
|
use numerics, only: &
|
||||||
|
hydrogenBoundPenalty, &
|
||||||
|
hydrogenPolyOrder
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
Ch
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
ChemPot, &
|
||||||
|
dChemPot_dCh
|
||||||
|
real(pReal) :: &
|
||||||
|
kBT, KPot, dKPot_dCh
|
||||||
|
integer(pInt) :: &
|
||||||
|
o
|
||||||
|
|
||||||
|
ChemPot = 1.0_pReal
|
||||||
|
dChemPot_dCh = 0.0_pReal
|
||||||
|
kBT = hydrogenflux_cahnhilliard_getEntropicCoeff(ip,el)
|
||||||
|
do o = 1_pInt, hydrogenPolyOrder
|
||||||
|
ChemPot = ChemPot + kBT*((2.0_pReal*Ch - 1.0_pReal)**real(2_pInt*o-1_pInt,pReal))/ &
|
||||||
|
real(2_pInt*o-1_pInt,pReal)
|
||||||
|
dChemPot_dCh = dChemPot_dCh + 2.0_pReal*kBT*(2.0_pReal*Ch - 1.0_pReal)**real(2_pInt*o-2_pInt,pReal)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
call hydrogenflux_cahnhilliard_KinematicChemPotAndItsTangent(KPot, dKPot_dCh, Ch, ip, el)
|
||||||
|
ChemPot = ChemPot + KPot
|
||||||
|
dChemPot_dCh = dChemPot_dCh + dKPot_dCh
|
||||||
|
|
||||||
|
if (Ch < 0.0_pReal) then
|
||||||
|
ChemPot = ChemPot - 3.0_pReal*hydrogenBoundPenalty*Ch*Ch
|
||||||
|
dChemPot_dCh = dChemPot_dCh - 6.0_pReal*hydrogenBoundPenalty*Ch
|
||||||
|
elseif (Ch > 1.0_pReal) then
|
||||||
|
ChemPot = ChemPot + 3.0_pReal*hydrogenBoundPenalty*(1.0_pReal - Ch)*(1.0_pReal - Ch)
|
||||||
|
dChemPot_dCh = dChemPot_dCh - 6.0_pReal*hydrogenBoundPenalty*(1.0_pReal - Ch)
|
||||||
|
endif
|
||||||
|
|
||||||
|
end subroutine hydrogenflux_cahnhilliard_getChemPotAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief updates hydrogen concentration with solution from Cahn-Hilliard PDE for solute transport
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine hydrogenflux_cahnhilliard_putHydrogenConcAndItsRate(Ch,Chdot,ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
hydrogenConc, &
|
||||||
|
hydrogenConcRate, &
|
||||||
|
hydrogenfluxMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
Ch, &
|
||||||
|
Chdot
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
offset
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = hydrogenfluxMapping(homog)%p(ip,el)
|
||||||
|
hydrogenConc (homog)%p(offset) = Ch
|
||||||
|
hydrogenConcRate(homog)%p(offset) = Chdot
|
||||||
|
|
||||||
|
end subroutine hydrogenflux_cahnhilliard_putHydrogenConcAndItsRate
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of hydrogen transport results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function hydrogenflux_cahnhilliard_postResults(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
hydrogenflux_typeInstance, &
|
||||||
|
hydrogenConc, &
|
||||||
|
hydrogenfluxMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(hydrogenflux_cahnhilliard_sizePostResults(hydrogenflux_typeInstance(mappingHomogenization(2,ip,el)))) :: &
|
||||||
|
hydrogenflux_cahnhilliard_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, homog, offset, o, c
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = hydrogenfluxMapping(homog)%p(ip,el)
|
||||||
|
instance = hydrogenflux_typeInstance(homog)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
hydrogenflux_cahnhilliard_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,hydrogenflux_cahnhilliard_Noutput(instance)
|
||||||
|
select case(hydrogenflux_cahnhilliard_outputID(o,instance))
|
||||||
|
|
||||||
|
case (hydrogenConc_ID)
|
||||||
|
hydrogenflux_cahnhilliard_postResults(c+1_pInt) = hydrogenConc(homog)%p(offset)
|
||||||
|
c = c + 1
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function hydrogenflux_cahnhilliard_postResults
|
||||||
|
|
||||||
|
end module hydrogenflux_cahnhilliard
|
|
@ -0,0 +1,64 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for constant hydrogen concentration
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module hydrogenflux_isoconc
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
hydrogenflux_isoconc_init
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief allocates all neccessary fields, reads information from material configuration file
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine hydrogenflux_isoconc_init()
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
use IO, only: &
|
||||||
|
IO_timeStamp
|
||||||
|
use material
|
||||||
|
use numerics, only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
NofMyHomog
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- hydrogenflux_'//HYDROGENFLUX_isoconc_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
initializeInstances: do homog = 1_pInt, material_Nhomogenization
|
||||||
|
|
||||||
|
myhomog: if (hydrogenflux_type(homog) == HYDROGENFLUX_isoconc_ID) then
|
||||||
|
NofMyHomog = count(material_homog == homog)
|
||||||
|
hydrogenfluxState(homog)%sizeState = 0_pInt
|
||||||
|
hydrogenfluxState(homog)%sizePostResults = 0_pInt
|
||||||
|
allocate(hydrogenfluxState(homog)%state0 (0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(hydrogenfluxState(homog)%subState0(0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(hydrogenfluxState(homog)%state (0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
|
deallocate(hydrogenConc (homog)%p)
|
||||||
|
deallocate(hydrogenConcRate(homog)%p)
|
||||||
|
allocate (hydrogenConc (homog)%p(1), source=0.0_pReal)
|
||||||
|
allocate (hydrogenConcRate(homog)%p(1), source=0.0_pReal)
|
||||||
|
|
||||||
|
endif myhomog
|
||||||
|
enddo initializeInstances
|
||||||
|
|
||||||
|
|
||||||
|
end subroutine hydrogenflux_isoconc_init
|
||||||
|
|
||||||
|
end module hydrogenflux_isoconc
|
|
@ -0,0 +1,305 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Luv Sharma, Max-Planck-Institut fŸr Eisenforschung GmbH
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut fŸr Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine incorporating kinematics resulting from opening of cleavage planes
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module kinematics_cleavage_opening
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
kinematics_cleavage_opening_sizePostResults, & !< cumulative size of post results
|
||||||
|
kinematics_cleavage_opening_offset, & !< which kinematics is my current damage mechanism?
|
||||||
|
kinematics_cleavage_opening_instance !< instance of damage kinematics mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
kinematics_cleavage_opening_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
kinematics_cleavage_opening_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
kinematics_cleavage_opening_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, private :: &
|
||||||
|
kinematics_cleavage_opening_totalNcleavage !< total number of cleavage systems
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, private :: &
|
||||||
|
kinematics_cleavage_opening_Ncleavage !< number of cleavage systems per family
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
kinematics_cleavage_opening_sdot_0, &
|
||||||
|
kinematics_cleavage_opening_N
|
||||||
|
|
||||||
|
real(pReal), dimension(:,:), allocatable, private :: &
|
||||||
|
kinematics_cleavage_opening_critDisp, &
|
||||||
|
kinematics_cleavage_opening_critLoad
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
kinematics_cleavage_opening_init, &
|
||||||
|
kinematics_cleavage_opening_LiAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_cleavage_opening_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_kinematics, &
|
||||||
|
phase_Nkinematics, &
|
||||||
|
phase_Noutput, &
|
||||||
|
KINEMATICS_cleavage_opening_label, &
|
||||||
|
KINEMATICS_cleavage_opening_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_maxNcleavageFamily, &
|
||||||
|
lattice_NcleavageSystem
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,phase,instance,kinematics
|
||||||
|
integer(pInt) :: Nchunks_CleavageFamilies = 0_pInt, j
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_cleavage_opening_LABEL//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_kinematics == KINEMATICS_cleavage_opening_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(kinematics_cleavage_opening_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(kinematics_cleavage_opening_instance(material_Nphase), source=0_pInt)
|
||||||
|
do phase = 1, material_Nphase
|
||||||
|
kinematics_cleavage_opening_instance(phase) = count(phase_kinematics(:,1:phase) == kinematics_cleavage_opening_ID)
|
||||||
|
do kinematics = 1, phase_Nkinematics(phase)
|
||||||
|
if (phase_kinematics(kinematics,phase) == kinematics_cleavage_opening_ID) &
|
||||||
|
kinematics_cleavage_opening_offset(phase) = kinematics
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
allocate(kinematics_cleavage_opening_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_cleavage_opening_sizePostResult(maxval(phase_Noutput),maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_cleavage_opening_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
kinematics_cleavage_opening_output = ''
|
||||||
|
allocate(kinematics_cleavage_opening_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
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_pInt)
|
||||||
|
allocate(kinematics_cleavage_opening_totalNcleavage(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_cleavage_opening_sdot_0(maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(kinematics_cleavage_opening_N(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_kinematics(:,phase) == KINEMATICS_cleavage_opening_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
instance = kinematics_cleavage_opening_instance(phase) ! which instance of my damage is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('anisobrittle_sdot0')
|
||||||
|
kinematics_cleavage_opening_sdot_0(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('anisobrittle_ratesensitivity')
|
||||||
|
kinematics_cleavage_opening_N(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('ncleavage') !
|
||||||
|
Nchunks_CleavageFamilies = positions(1) - 1_pInt
|
||||||
|
do j = 1_pInt, Nchunks_CleavageFamilies
|
||||||
|
kinematics_cleavage_opening_Ncleavage(j,instance) = IO_intValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
case ('anisobrittle_criticaldisplacement')
|
||||||
|
do j = 1_pInt, Nchunks_CleavageFamilies
|
||||||
|
kinematics_cleavage_opening_critDisp(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
case ('anisobrittle_criticalload')
|
||||||
|
do j = 1_pInt, Nchunks_CleavageFamilies
|
||||||
|
kinematics_cleavage_opening_critLoad(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! sanity checks
|
||||||
|
sanityChecks: do phase = 1_pInt, material_Nphase
|
||||||
|
myPhase: if (any(phase_kinematics(:,phase) == KINEMATICS_cleavage_opening_ID)) then
|
||||||
|
instance = kinematics_cleavage_opening_instance(phase)
|
||||||
|
kinematics_cleavage_opening_Ncleavage(1:lattice_maxNcleavageFamily,instance) = &
|
||||||
|
min(lattice_NcleavageSystem(1:lattice_maxNcleavageFamily,phase),& ! 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_pInt,el=instance,ext_msg='sdot_0 ('//KINEMATICS_cleavage_opening_LABEL//')')
|
||||||
|
if (any(kinematics_cleavage_opening_critDisp(1:Nchunks_CleavageFamilies,instance) < 0.0_pReal)) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='critical_displacement ('//KINEMATICS_cleavage_opening_LABEL//')')
|
||||||
|
if (any(kinematics_cleavage_opening_critLoad(1:Nchunks_CleavageFamilies,instance) < 0.0_pReal)) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='critical_load ('//KINEMATICS_cleavage_opening_LABEL//')')
|
||||||
|
if (kinematics_cleavage_opening_N(instance) <= 0.0_pReal) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='rate_sensitivity ('//KINEMATICS_cleavage_opening_LABEL//')')
|
||||||
|
endif myPhase
|
||||||
|
enddo sanityChecks
|
||||||
|
|
||||||
|
end subroutine kinematics_cleavage_opening_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief contains the constitutive equation for calculating the velocity gradient
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_cleavage_opening_LiAndItsTangent(Ld, dLd_dTstar3333, Tstar_v, ipc, ip, el)
|
||||||
|
use prec, only: &
|
||||||
|
tol_math_check
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
material_homog, &
|
||||||
|
damage, &
|
||||||
|
damageMapping
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_Scleavage, &
|
||||||
|
lattice_Scleavage_v, &
|
||||||
|
lattice_maxNcleavageFamily, &
|
||||||
|
lattice_NcleavageSystem
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in), dimension(6) :: &
|
||||||
|
Tstar_v !< 2nd Piola-Kirchhoff stress
|
||||||
|
real(pReal), intent(out), dimension(3,3) :: &
|
||||||
|
Ld !< damage velocity gradient
|
||||||
|
real(pReal), intent(out), dimension(3,3,3,3) :: &
|
||||||
|
dLd_dTstar3333 !< derivative of Ld with respect to Tstar (4th-order tensor)
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
constituent, &
|
||||||
|
instance, &
|
||||||
|
homog, damageOffset, &
|
||||||
|
f, i, index_myFamily, k, l, m, n
|
||||||
|
real(pReal) :: &
|
||||||
|
traction_d, traction_t, traction_n, traction_crit, &
|
||||||
|
udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = kinematics_cleavage_opening_instance(phase)
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
damageOffset = damageMapping(homog)%p(ip,el)
|
||||||
|
|
||||||
|
Ld = 0.0_pReal
|
||||||
|
dLd_dTstar3333 = 0.0_pReal
|
||||||
|
do f = 1_pInt,lattice_maxNcleavageFamily
|
||||||
|
index_myFamily = sum(lattice_NcleavageSystem(1:f-1_pInt,phase)) ! at which index starts my family
|
||||||
|
do i = 1_pInt,kinematics_cleavage_opening_Ncleavage(f,instance) ! process each (active) cleavage system in family
|
||||||
|
traction_d = dot_product(Tstar_v,lattice_Scleavage_v(1:6,1,index_myFamily+i,phase))
|
||||||
|
traction_t = dot_product(Tstar_v,lattice_Scleavage_v(1:6,2,index_myFamily+i,phase))
|
||||||
|
traction_n = dot_product(Tstar_v,lattice_Scleavage_v(1:6,3,index_myFamily+i,phase))
|
||||||
|
traction_crit = kinematics_cleavage_opening_critLoad(f,instance)* &
|
||||||
|
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_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
||||||
|
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(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 = &
|
||||||
|
sign(1.0_pReal,traction_t)* &
|
||||||
|
kinematics_cleavage_opening_sdot_0(instance)* &
|
||||||
|
(max(0.0_pReal, abs(traction_t) - traction_crit)/traction_crit)**kinematics_cleavage_opening_N(instance)
|
||||||
|
if (abs(udott) > tol_math_check) then
|
||||||
|
Ld = Ld + udott*lattice_Scleavage(1:3,1:3,2,index_myFamily+i,phase)
|
||||||
|
dudott_dt = sign(1.0_pReal,traction_t)*udott*kinematics_cleavage_opening_N(instance)/ &
|
||||||
|
max(0.0_pReal, abs(traction_t) - traction_crit)
|
||||||
|
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
||||||
|
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(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 = &
|
||||||
|
sign(1.0_pReal,traction_n)* &
|
||||||
|
kinematics_cleavage_opening_sdot_0(instance)* &
|
||||||
|
(max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**kinematics_cleavage_opening_N(instance)
|
||||||
|
if (abs(udotn) > tol_math_check) then
|
||||||
|
Ld = Ld + udotn*lattice_Scleavage(1:3,1:3,3,index_myFamily+i,phase)
|
||||||
|
dudotn_dt = sign(1.0_pReal,traction_n)*udotn*kinematics_cleavage_opening_N(instance)/ &
|
||||||
|
max(0.0_pReal, abs(traction_n) - traction_crit)
|
||||||
|
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
||||||
|
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(k,l,m,n) + &
|
||||||
|
dudotn_dt*lattice_Scleavage(k,l,3,index_myFamily+i,phase)* &
|
||||||
|
lattice_Scleavage(m,n,3,index_myFamily+i,phase)
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine kinematics_cleavage_opening_LiAndItsTangent
|
||||||
|
|
||||||
|
end module kinematics_cleavage_opening
|
|
@ -0,0 +1,220 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine incorporating kinematics resulting from interstitial hydrogen
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module kinematics_hydrogen_strain
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
kinematics_hydrogen_strain_sizePostResults, & !< cumulative size of post results
|
||||||
|
kinematics_hydrogen_strain_offset, & !< which kinematics is my current damage mechanism?
|
||||||
|
kinematics_hydrogen_strain_instance !< instance of damage kinematics mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
kinematics_hydrogen_strain_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
kinematics_hydrogen_strain_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
kinematics_hydrogen_strain_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
kinematics_hydrogen_strain_coeff
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
kinematics_hydrogen_strain_init, &
|
||||||
|
kinematics_hydrogen_strain_LiAndItsTangent, &
|
||||||
|
kinematics_hydrogen_strain_ChemPotAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_hydrogen_strain_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_kinematics, &
|
||||||
|
phase_Nkinematics, &
|
||||||
|
phase_Noutput, &
|
||||||
|
KINEMATICS_hydrogen_strain_label, &
|
||||||
|
KINEMATICS_hydrogen_strain_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,phase,instance,kinematics
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_hydrogen_strain_LABEL//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_kinematics == KINEMATICS_hydrogen_strain_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(kinematics_hydrogen_strain_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(kinematics_hydrogen_strain_instance(material_Nphase), source=0_pInt)
|
||||||
|
do phase = 1, material_Nphase
|
||||||
|
kinematics_hydrogen_strain_instance(phase) = count(phase_kinematics(:,1:phase) == kinematics_hydrogen_strain_ID)
|
||||||
|
do kinematics = 1, phase_Nkinematics(phase)
|
||||||
|
if (phase_kinematics(kinematics,phase) == kinematics_hydrogen_strain_ID) &
|
||||||
|
kinematics_hydrogen_strain_offset(phase) = kinematics
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
allocate(kinematics_hydrogen_strain_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_hydrogen_strain_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(kinematics_hydrogen_strain_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
kinematics_hydrogen_strain_output = ''
|
||||||
|
allocate(kinematics_hydrogen_strain_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_hydrogen_strain_coeff(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_kinematics(:,phase) == KINEMATICS_hydrogen_strain_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
instance = kinematics_hydrogen_strain_instance(phase) ! which instance of my damage is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('hydrogen_strain_coeff')
|
||||||
|
kinematics_hydrogen_strain_coeff(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
end subroutine kinematics_hydrogen_strain_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief contains the constitutive equation for calculating the velocity gradient
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_hydrogen_strain_LiAndItsTangent(Li, dLi_dTstar3333, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
material_phase, &
|
||||||
|
material_homog, &
|
||||||
|
hydrogenConcRate, &
|
||||||
|
hydrogenfluxMapping
|
||||||
|
use math, only: &
|
||||||
|
math_I3
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(out), dimension(3,3) :: &
|
||||||
|
Li !< thermal velocity gradient
|
||||||
|
real(pReal), intent(out), dimension(3,3,3,3) :: &
|
||||||
|
dLi_dTstar3333 !< derivative of Li with respect to Tstar (4th-order tensor)
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
instance, &
|
||||||
|
homog, offset
|
||||||
|
|
||||||
|
phase = material_phase(ipc,ip,el)
|
||||||
|
instance = kinematics_hydrogen_strain_instance(phase)
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
offset = hydrogenfluxMapping(homog)%p(ip,el)
|
||||||
|
|
||||||
|
Li = hydrogenConcRate(homog)%p(offset)* &
|
||||||
|
kinematics_hydrogen_strain_coeff(instance)* &
|
||||||
|
math_I3
|
||||||
|
dLi_dTstar3333 = 0.0_pReal
|
||||||
|
|
||||||
|
end subroutine kinematics_hydrogen_strain_LiAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief contains the kinematic contribution to hydrogen chemical potential
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_hydrogen_strain_ChemPotAndItsTangent(ChemPot, dChemPot_dCh, Tstar_v, Fi0, Fi, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
material_phase
|
||||||
|
use math, only: &
|
||||||
|
math_inv33, &
|
||||||
|
math_mul33x33, &
|
||||||
|
math_Mandel6to33, &
|
||||||
|
math_transpose33
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in), dimension(6) :: &
|
||||||
|
Tstar_v
|
||||||
|
real(pReal), intent(in), dimension(3,3) :: &
|
||||||
|
Fi0, Fi
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
ChemPot, dChemPot_dCh
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
instance
|
||||||
|
|
||||||
|
phase = material_phase(ipc,ip,el)
|
||||||
|
instance = kinematics_hydrogen_strain_instance(phase)
|
||||||
|
|
||||||
|
ChemPot = -kinematics_hydrogen_strain_coeff(instance)* &
|
||||||
|
sum(math_mul33x33(Fi,math_Mandel6to33(Tstar_v))* &
|
||||||
|
math_mul33x33(math_mul33x33(Fi,math_inv33(Fi0)),Fi))
|
||||||
|
dChemPot_dCh = 0.0_pReal
|
||||||
|
|
||||||
|
end subroutine kinematics_hydrogen_strain_ChemPotAndItsTangent
|
||||||
|
|
||||||
|
end module kinematics_hydrogen_strain
|
|
@ -0,0 +1,325 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Luv Sharma, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine incorporating kinematics resulting from opening of slip planes
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module kinematics_slipplane_opening
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
kinematics_slipplane_opening_sizePostResults, & !< cumulative size of post results
|
||||||
|
kinematics_slipplane_opening_offset, & !< which kinematics is my current damage mechanism?
|
||||||
|
kinematics_slipplane_opening_instance !< instance of damage kinematics mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
kinematics_slipplane_opening_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
kinematics_slipplane_opening_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
kinematics_slipplane_opening_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, private :: &
|
||||||
|
kinematics_slipplane_opening_totalNslip !< total number of slip systems
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, private :: &
|
||||||
|
kinematics_slipplane_opening_Nslip !< number of slip systems per family
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
kinematics_slipplane_opening_sdot_0, &
|
||||||
|
kinematics_slipplane_opening_N
|
||||||
|
|
||||||
|
real(pReal), dimension(:,:), allocatable, private :: &
|
||||||
|
kinematics_slipplane_opening_critPlasticStrain, &
|
||||||
|
kinematics_slipplane_opening_critLoad
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
kinematics_slipplane_opening_init, &
|
||||||
|
kinematics_slipplane_opening_LiAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_slipplane_opening_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_kinematics, &
|
||||||
|
phase_Nkinematics, &
|
||||||
|
phase_Noutput, &
|
||||||
|
KINEMATICS_slipplane_opening_label, &
|
||||||
|
KINEMATICS_slipplane_opening_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_maxNslipFamily, &
|
||||||
|
lattice_NslipSystem
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,phase,instance,kinematics
|
||||||
|
integer(pInt) :: Nchunks_SlipFamilies = 0_pInt, j
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_slipplane_opening_LABEL//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_kinematics == KINEMATICS_slipplane_opening_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(kinematics_slipplane_opening_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(kinematics_slipplane_opening_instance(material_Nphase), source=0_pInt)
|
||||||
|
do phase = 1, material_Nphase
|
||||||
|
kinematics_slipplane_opening_instance(phase) = count(phase_kinematics(:,1:phase) == kinematics_slipplane_opening_ID)
|
||||||
|
do kinematics = 1, phase_Nkinematics(phase)
|
||||||
|
if (phase_kinematics(kinematics,phase) == kinematics_slipplane_opening_ID) &
|
||||||
|
kinematics_slipplane_opening_offset(phase) = kinematics
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
allocate(kinematics_slipplane_opening_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_slipplane_opening_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(kinematics_slipplane_opening_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
kinematics_slipplane_opening_output = ''
|
||||||
|
allocate(kinematics_slipplane_opening_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_slipplane_opening_critLoad(lattice_maxNslipFamily,maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(kinematics_slipplane_opening_critPlasticStrain(lattice_maxNslipFamily,maxNinstance),source=0.0_pReal)
|
||||||
|
allocate(kinematics_slipplane_opening_Nslip(lattice_maxNslipFamily,maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_slipplane_opening_totalNslip(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_slipplane_opening_N(maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(kinematics_slipplane_opening_sdot_0(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_kinematics(:,phase) == KINEMATICS_slipplane_opening_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
instance = kinematics_slipplane_opening_instance(phase) ! which instance of my damage is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('nslip') !
|
||||||
|
Nchunks_SlipFamilies = positions(1) - 1_pInt
|
||||||
|
do j = 1_pInt, Nchunks_SlipFamilies
|
||||||
|
kinematics_slipplane_opening_Nslip(j,instance) = IO_intValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
case ('anisoductile_sdot0')
|
||||||
|
kinematics_slipplane_opening_sdot_0(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('anisoductile_criticalplasticstrain')
|
||||||
|
do j = 1_pInt, Nchunks_SlipFamilies
|
||||||
|
kinematics_slipplane_opening_critPlasticStrain(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
case ('anisoductile_ratesensitivity')
|
||||||
|
kinematics_slipplane_opening_N(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('anisoductile_criticalload')
|
||||||
|
do j = 1_pInt, Nchunks_SlipFamilies
|
||||||
|
kinematics_slipplane_opening_critLoad(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! sanity checks
|
||||||
|
sanityChecks: do phase = 1_pInt, material_Nphase
|
||||||
|
myPhase: if (any(phase_kinematics(:,phase) == KINEMATICS_slipplane_opening_ID)) then
|
||||||
|
instance = kinematics_slipplane_opening_instance(phase)
|
||||||
|
kinematics_slipplane_opening_Nslip(1:lattice_maxNslipFamily,instance) = &
|
||||||
|
min(lattice_NslipSystem(1:lattice_maxNslipFamily,phase),& ! limit active cleavage systems per family to min of available and requested
|
||||||
|
kinematics_slipplane_opening_Nslip(1:lattice_maxNslipFamily,instance))
|
||||||
|
kinematics_slipplane_opening_totalNslip(instance) = sum(kinematics_slipplane_opening_Nslip(:,instance))
|
||||||
|
if (kinematics_slipplane_opening_sdot_0(instance) <= 0.0_pReal) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='sdot_0 ('//KINEMATICS_slipplane_opening_LABEL//')')
|
||||||
|
if (any(kinematics_slipplane_opening_critPlasticStrain(:,instance) < 0.0_pReal)) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='criticaPlasticStrain ('//KINEMATICS_slipplane_opening_LABEL//')')
|
||||||
|
if (kinematics_slipplane_opening_N(instance) <= 0.0_pReal) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='rate_sensitivity ('//KINEMATICS_slipplane_opening_LABEL//')')
|
||||||
|
endif myPhase
|
||||||
|
enddo sanityChecks
|
||||||
|
|
||||||
|
|
||||||
|
end subroutine kinematics_slipplane_opening_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief contains the constitutive equation for calculating the velocity gradient
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_slipplane_opening_LiAndItsTangent(Ld, dLd_dTstar3333, Tstar_v, ipc, ip, el)
|
||||||
|
use prec, only: &
|
||||||
|
tol_math_check
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_maxNslipFamily, &
|
||||||
|
lattice_NslipSystem, &
|
||||||
|
lattice_sd, &
|
||||||
|
lattice_st, &
|
||||||
|
lattice_sn
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
material_homog, &
|
||||||
|
damage, &
|
||||||
|
damageMapping
|
||||||
|
use math, only: &
|
||||||
|
math_Plain3333to99, &
|
||||||
|
math_I3, &
|
||||||
|
math_identity4th, &
|
||||||
|
math_symmetric33, &
|
||||||
|
math_Mandel33to6, &
|
||||||
|
math_tensorproduct, &
|
||||||
|
math_det33, &
|
||||||
|
math_mul33x33
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in), dimension(6) :: &
|
||||||
|
Tstar_v !< 2nd Piola-Kirchhoff stress
|
||||||
|
real(pReal), intent(out), dimension(3,3) :: &
|
||||||
|
Ld !< damage velocity gradient
|
||||||
|
real(pReal), intent(out), dimension(3,3,3,3) :: &
|
||||||
|
dLd_dTstar3333 !< 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
|
||||||
|
real(pReal), dimension(6) :: &
|
||||||
|
projection_d_v, projection_t_v, projection_n_v !< projection modes 3x3 vector
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
constituent, &
|
||||||
|
instance, &
|
||||||
|
homog, damageOffset, &
|
||||||
|
f, i, index_myFamily, k, l, m, n
|
||||||
|
real(pReal) :: &
|
||||||
|
traction_d, traction_t, traction_n, traction_crit, &
|
||||||
|
udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = kinematics_slipplane_opening_instance(phase)
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
damageOffset = damageMapping(homog)%p(ip,el)
|
||||||
|
|
||||||
|
Ld = 0.0_pReal
|
||||||
|
dLd_dTstar3333 = 0.0_pReal
|
||||||
|
do f = 1_pInt,lattice_maxNslipFamily
|
||||||
|
index_myFamily = sum(lattice_NslipSystem(1:f-1_pInt,phase)) ! at which index starts my family
|
||||||
|
do i = 1_pInt,kinematics_slipplane_opening_Nslip(f,instance) ! process each (active) slip system in family
|
||||||
|
projection_d = math_tensorproduct(lattice_sd(1:3,index_myFamily+i,phase),&
|
||||||
|
lattice_sn(1:3,index_myFamily+i,phase))
|
||||||
|
projection_t = math_tensorproduct(lattice_st(1:3,index_myFamily+i,phase),&
|
||||||
|
lattice_sn(1:3,index_myFamily+i,phase))
|
||||||
|
projection_n = math_tensorproduct(lattice_sn(1:3,index_myFamily+i,phase),&
|
||||||
|
lattice_sn(1:3,index_myFamily+i,phase))
|
||||||
|
|
||||||
|
projection_d_v(1:6) = math_Mandel33to6(math_symmetric33(projection_d(1:3,1:3)))
|
||||||
|
projection_t_v(1:6) = math_Mandel33to6(math_symmetric33(projection_t(1:3,1:3)))
|
||||||
|
projection_n_v(1:6) = math_Mandel33to6(math_symmetric33(projection_n(1:3,1:3)))
|
||||||
|
|
||||||
|
traction_d = dot_product(Tstar_v,projection_d_v(1:6))
|
||||||
|
traction_t = dot_product(Tstar_v,projection_t_v(1:6))
|
||||||
|
traction_n = dot_product(Tstar_v,projection_n_v(1:6))
|
||||||
|
|
||||||
|
traction_crit = kinematics_slipplane_opening_critLoad(f,instance)* &
|
||||||
|
damage(homog)%p(damageOffset) ! degrading critical load carrying capacity by damage
|
||||||
|
|
||||||
|
udotd = &
|
||||||
|
sign(1.0_pReal,traction_d)* &
|
||||||
|
kinematics_slipplane_opening_sdot_0(instance)* &
|
||||||
|
(abs(traction_d)/traction_crit - &
|
||||||
|
abs(traction_d)/kinematics_slipplane_opening_critLoad(f,instance))**kinematics_slipplane_opening_N(instance)
|
||||||
|
if (abs(udotd) > tol_math_check) then
|
||||||
|
Ld = Ld + udotd*projection_d
|
||||||
|
dudotd_dt = udotd*kinematics_slipplane_opening_N(instance)/traction_d
|
||||||
|
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
||||||
|
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(k,l,m,n) + &
|
||||||
|
dudotd_dt*projection_d(k,l)*projection_d(m,n)
|
||||||
|
endif
|
||||||
|
|
||||||
|
udott = &
|
||||||
|
sign(1.0_pReal,traction_t)* &
|
||||||
|
kinematics_slipplane_opening_sdot_0(instance)* &
|
||||||
|
(abs(traction_t)/traction_crit - &
|
||||||
|
abs(traction_t)/kinematics_slipplane_opening_critLoad(f,instance))**kinematics_slipplane_opening_N(instance)
|
||||||
|
if (abs(udott) > tol_math_check) then
|
||||||
|
Ld = Ld + udott*projection_t
|
||||||
|
dudott_dt = udott*kinematics_slipplane_opening_N(instance)/traction_t
|
||||||
|
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
||||||
|
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(k,l,m,n) + &
|
||||||
|
dudott_dt*projection_t(k,l)*projection_t(m,n)
|
||||||
|
endif
|
||||||
|
udotn = &
|
||||||
|
kinematics_slipplane_opening_sdot_0(instance)* &
|
||||||
|
(max(0.0_pReal,traction_n)/traction_crit - &
|
||||||
|
max(0.0_pReal,traction_n)/kinematics_slipplane_opening_critLoad(f,instance))**kinematics_slipplane_opening_N(instance)
|
||||||
|
if (abs(udotn) > tol_math_check) then
|
||||||
|
Ld = Ld + udotn*projection_n
|
||||||
|
dudotn_dt = udotn*kinematics_slipplane_opening_N(instance)/traction_n
|
||||||
|
forall (k=1_pInt:3_pInt,l=1_pInt:3_pInt,m=1_pInt:3_pInt,n=1_pInt:3_pInt) &
|
||||||
|
dLd_dTstar3333(k,l,m,n) = dLd_dTstar3333(k,l,m,n) + &
|
||||||
|
dudotn_dt*projection_n(k,l)*projection_n(m,n)
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine kinematics_slipplane_opening_LiAndItsTangent
|
||||||
|
|
||||||
|
end module kinematics_slipplane_opening
|
|
@ -0,0 +1,182 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine incorporating kinematics resulting from thermal expansion
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module kinematics_thermal_expansion
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
kinematics_thermal_expansion_sizePostResults, & !< cumulative size of post results
|
||||||
|
kinematics_thermal_expansion_offset, & !< which kinematics is my current damage mechanism?
|
||||||
|
kinematics_thermal_expansion_instance !< instance of damage kinematics mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
kinematics_thermal_expansion_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
kinematics_thermal_expansion_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
kinematics_thermal_expansion_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
kinematics_thermal_expansion_coeff
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
kinematics_thermal_expansion_init, &
|
||||||
|
kinematics_thermal_expansion_LiAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_thermal_expansion_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_kinematics, &
|
||||||
|
phase_Nkinematics, &
|
||||||
|
phase_Noutput, &
|
||||||
|
KINEMATICS_thermal_expansion_label, &
|
||||||
|
KINEMATICS_thermal_expansion_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,phase,instance,kinematics
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_thermal_expansion_LABEL//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_kinematics == KINEMATICS_thermal_expansion_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(kinematics_thermal_expansion_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(kinematics_thermal_expansion_instance(material_Nphase), source=0_pInt)
|
||||||
|
do phase = 1, material_Nphase
|
||||||
|
kinematics_thermal_expansion_instance(phase) = count(phase_kinematics(:,1:phase) == kinematics_thermal_expansion_ID)
|
||||||
|
do kinematics = 1, phase_Nkinematics(phase)
|
||||||
|
if (phase_kinematics(kinematics,phase) == kinematics_thermal_expansion_ID) &
|
||||||
|
kinematics_thermal_expansion_offset(phase) = kinematics
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
allocate(kinematics_thermal_expansion_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_thermal_expansion_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(kinematics_thermal_expansion_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
kinematics_thermal_expansion_output = ''
|
||||||
|
allocate(kinematics_thermal_expansion_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_thermal_expansion_coeff(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_kinematics(:,phase) == KINEMATICS_thermal_expansion_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
instance = kinematics_thermal_expansion_instance(phase) ! which instance of my damage is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('thermal_expansion_coeff')
|
||||||
|
kinematics_thermal_expansion_coeff(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
end subroutine kinematics_thermal_expansion_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief contains the constitutive equation for calculating the velocity gradient
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_thermal_expansion_LiAndItsTangent(Li, dLi_dTstar3333, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
material_phase, &
|
||||||
|
material_homog, &
|
||||||
|
temperatureRate, &
|
||||||
|
thermalMapping
|
||||||
|
use math, only: &
|
||||||
|
math_I3
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(out), dimension(3,3) :: &
|
||||||
|
Li !< thermal velocity gradient
|
||||||
|
real(pReal), intent(out), dimension(3,3,3,3) :: &
|
||||||
|
dLi_dTstar3333 !< derivative of Li with respect to Tstar (4th-order tensor)
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
instance, &
|
||||||
|
homog, offset
|
||||||
|
|
||||||
|
phase = material_phase(ipc,ip,el)
|
||||||
|
instance = kinematics_thermal_expansion_instance(phase)
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
offset = thermalMapping(homog)%p(ip,el)
|
||||||
|
|
||||||
|
Li = temperatureRate(homog)%p(offset)* &
|
||||||
|
kinematics_thermal_expansion_coeff(instance)* &
|
||||||
|
math_I3
|
||||||
|
dLi_dTstar3333 = 0.0_pReal
|
||||||
|
|
||||||
|
end subroutine kinematics_thermal_expansion_LiAndItsTangent
|
||||||
|
|
||||||
|
end module kinematics_thermal_expansion
|
|
@ -0,0 +1,220 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine incorporating kinematics resulting from vacancy point defects
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module kinematics_vacancy_strain
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
kinematics_vacancy_strain_sizePostResults, & !< cumulative size of post results
|
||||||
|
kinematics_vacancy_strain_offset, & !< which kinematics is my current damage mechanism?
|
||||||
|
kinematics_vacancy_strain_instance !< instance of damage kinematics mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
kinematics_vacancy_strain_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
kinematics_vacancy_strain_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
kinematics_vacancy_strain_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
kinematics_vacancy_strain_coeff
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
kinematics_vacancy_strain_init, &
|
||||||
|
kinematics_vacancy_strain_LiAndItsTangent, &
|
||||||
|
kinematics_vacancy_strain_ChemPotAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_vacancy_strain_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_kinematics, &
|
||||||
|
phase_Nkinematics, &
|
||||||
|
phase_Noutput, &
|
||||||
|
KINEMATICS_vacancy_strain_label, &
|
||||||
|
KINEMATICS_vacancy_strain_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,phase,instance,kinematics
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- kinematics_'//KINEMATICS_vacancy_strain_LABEL//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_kinematics == KINEMATICS_vacancy_strain_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(kinematics_vacancy_strain_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(kinematics_vacancy_strain_instance(material_Nphase), source=0_pInt)
|
||||||
|
do phase = 1, material_Nphase
|
||||||
|
kinematics_vacancy_strain_instance(phase) = count(phase_kinematics(:,1:phase) == kinematics_vacancy_strain_ID)
|
||||||
|
do kinematics = 1, phase_Nkinematics(phase)
|
||||||
|
if (phase_kinematics(kinematics,phase) == kinematics_vacancy_strain_ID) &
|
||||||
|
kinematics_vacancy_strain_offset(phase) = kinematics
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
allocate(kinematics_vacancy_strain_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_vacancy_strain_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(kinematics_vacancy_strain_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
kinematics_vacancy_strain_output = ''
|
||||||
|
allocate(kinematics_vacancy_strain_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(kinematics_vacancy_strain_coeff(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_kinematics(:,phase) == KINEMATICS_vacancy_strain_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
instance = kinematics_vacancy_strain_instance(phase) ! which instance of my damage is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('vacancy_strain_coeff')
|
||||||
|
kinematics_vacancy_strain_coeff(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
end subroutine kinematics_vacancy_strain_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief contains the constitutive equation for calculating the velocity gradient
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_vacancy_strain_LiAndItsTangent(Li, dLi_dTstar3333, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
material_phase, &
|
||||||
|
material_homog, &
|
||||||
|
vacancyConcRate, &
|
||||||
|
vacancyfluxMapping
|
||||||
|
use math, only: &
|
||||||
|
math_I3
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(out), dimension(3,3) :: &
|
||||||
|
Li !< thermal velocity gradient
|
||||||
|
real(pReal), intent(out), dimension(3,3,3,3) :: &
|
||||||
|
dLi_dTstar3333 !< derivative of Li with respect to Tstar (4th-order tensor)
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
instance, &
|
||||||
|
homog, offset
|
||||||
|
|
||||||
|
phase = material_phase(ipc,ip,el)
|
||||||
|
instance = kinematics_vacancy_strain_instance(phase)
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
offset = vacancyfluxMapping(homog)%p(ip,el)
|
||||||
|
|
||||||
|
Li = vacancyConcRate(homog)%p(offset)* &
|
||||||
|
kinematics_vacancy_strain_coeff(instance)* &
|
||||||
|
math_I3
|
||||||
|
dLi_dTstar3333 = 0.0_pReal
|
||||||
|
|
||||||
|
end subroutine kinematics_vacancy_strain_LiAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief contains the kinematic contribution to vacancy chemical potential
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine kinematics_vacancy_strain_ChemPotAndItsTangent(ChemPot, dChemPot_dCv, Tstar_v, Fi0, Fi, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
material_phase
|
||||||
|
use math, only: &
|
||||||
|
math_inv33, &
|
||||||
|
math_mul33x33, &
|
||||||
|
math_Mandel6to33, &
|
||||||
|
math_transpose33
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in), dimension(6) :: &
|
||||||
|
Tstar_v
|
||||||
|
real(pReal), intent(in), dimension(3,3) :: &
|
||||||
|
Fi0, Fi
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
ChemPot, dChemPot_dCv
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
instance
|
||||||
|
|
||||||
|
phase = material_phase(ipc,ip,el)
|
||||||
|
instance = kinematics_vacancy_strain_instance(phase)
|
||||||
|
|
||||||
|
ChemPot = -kinematics_vacancy_strain_coeff(instance)* &
|
||||||
|
sum(math_mul33x33(Fi,math_Mandel6to33(Tstar_v))* &
|
||||||
|
math_mul33x33(math_mul33x33(Fi,math_inv33(Fi0)),Fi))
|
||||||
|
dChemPot_dCv = 0.0_pReal
|
||||||
|
|
||||||
|
end subroutine kinematics_vacancy_strain_ChemPotAndItsTangent
|
||||||
|
|
||||||
|
end module kinematics_vacancy_strain
|
|
@ -833,12 +833,18 @@ module lattice
|
||||||
lattice_thermalConductivity33, &
|
lattice_thermalConductivity33, &
|
||||||
lattice_thermalExpansion33, &
|
lattice_thermalExpansion33, &
|
||||||
lattice_damageDiffusion33, &
|
lattice_damageDiffusion33, &
|
||||||
lattice_vacancyDiffusion33
|
lattice_vacancyfluxDiffusion33, &
|
||||||
|
lattice_vacancyfluxMobility33, &
|
||||||
|
lattice_porosityDiffusion33, &
|
||||||
|
lattice_hydrogenfluxDiffusion33, &
|
||||||
|
lattice_hydrogenfluxMobility33
|
||||||
real(pReal), dimension(:), allocatable, public, protected :: &
|
real(pReal), dimension(:), allocatable, public, protected :: &
|
||||||
lattice_damageMobility, &
|
lattice_damageMobility, &
|
||||||
lattice_vacancyMobility, &
|
lattice_porosityMobility, &
|
||||||
lattice_massDensity, &
|
lattice_massDensity, &
|
||||||
lattice_specificHeat, &
|
lattice_specificHeat, &
|
||||||
|
lattice_vacancyVol, &
|
||||||
|
lattice_hydrogenVol, &
|
||||||
lattice_referenceTemperature, &
|
lattice_referenceTemperature, &
|
||||||
lattice_equilibriumVacancyConcentration
|
lattice_equilibriumVacancyConcentration
|
||||||
enum, bind(c)
|
enum, bind(c)
|
||||||
|
@ -1101,15 +1107,21 @@ subroutine lattice_init
|
||||||
allocate(lattice_structure(Nphases),source = LATTICE_undefined_ID)
|
allocate(lattice_structure(Nphases),source = LATTICE_undefined_ID)
|
||||||
allocate(lattice_C66(6,6,Nphases), source=0.0_pReal)
|
allocate(lattice_C66(6,6,Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_C3333(3,3,3,3,Nphases), source=0.0_pReal)
|
allocate(lattice_C3333(3,3,3,3,Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_thermalConductivity33(3,3,Nphases), source=0.0_pReal)
|
allocate(lattice_thermalConductivity33 (3,3,Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_thermalExpansion33 (3,3,Nphases), source=0.0_pReal)
|
allocate(lattice_thermalExpansion33 (3,3,Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_damageDiffusion33 (3,3,Nphases), source=0.0_pReal)
|
allocate(lattice_damageDiffusion33 (3,3,Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_vacancyDiffusion33 (3,3,Nphases), source=0.0_pReal)
|
allocate(lattice_vacancyfluxDiffusion33 (3,3,Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_damageMobility ( Nphases), source=0.0_pReal)
|
allocate(lattice_vacancyfluxMobility33 (3,3,Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_vacancyMobility ( Nphases), source=0.0_pReal)
|
allocate(lattice_PorosityDiffusion33 (3,3,Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_massDensity ( Nphases), source=0.0_pReal)
|
allocate(lattice_hydrogenfluxDiffusion33(3,3,Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_specificHeat ( Nphases), source=0.0_pReal)
|
allocate(lattice_hydrogenfluxMobility33 (3,3,Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_referenceTemperature ( Nphases), source=0.0_pReal)
|
allocate(lattice_damageMobility ( Nphases), source=0.0_pReal)
|
||||||
|
allocate(lattice_PorosityMobility ( Nphases), source=0.0_pReal)
|
||||||
|
allocate(lattice_massDensity ( Nphases), source=0.0_pReal)
|
||||||
|
allocate(lattice_specificHeat ( Nphases), source=0.0_pReal)
|
||||||
|
allocate(lattice_vacancyVol ( Nphases), source=0.0_pReal)
|
||||||
|
allocate(lattice_hydrogenVol ( Nphases), source=0.0_pReal)
|
||||||
|
allocate(lattice_referenceTemperature ( Nphases), source=0.0_pReal)
|
||||||
allocate(lattice_equilibriumVacancyConcentration(Nphases), source=0.0_pReal)
|
allocate(lattice_equilibriumVacancyConcentration(Nphases), source=0.0_pReal)
|
||||||
|
|
||||||
allocate(lattice_mu(Nphases), source=0.0_pReal)
|
allocate(lattice_mu(Nphases), source=0.0_pReal)
|
||||||
|
@ -1232,6 +1244,10 @@ subroutine lattice_init
|
||||||
lattice_thermalExpansion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
lattice_thermalExpansion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('specific_heat')
|
case ('specific_heat')
|
||||||
lattice_specificHeat(section) = IO_floatValue(line,positions,2_pInt)
|
lattice_specificHeat(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('vacancyvolume')
|
||||||
|
lattice_vacancyVol(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('hydrogenvolume')
|
||||||
|
lattice_hydrogenVol(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('mass_density')
|
case ('mass_density')
|
||||||
lattice_massDensity(section) = IO_floatValue(line,positions,2_pInt)
|
lattice_massDensity(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('reference_temperature')
|
case ('reference_temperature')
|
||||||
|
@ -1244,14 +1260,38 @@ subroutine lattice_init
|
||||||
lattice_DamageDiffusion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
lattice_DamageDiffusion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('damage_mobility')
|
case ('damage_mobility')
|
||||||
lattice_DamageMobility(section) = IO_floatValue(line,positions,2_pInt)
|
lattice_DamageMobility(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('vacancy_diffusion11')
|
case ('vacancyflux_diffusion11')
|
||||||
lattice_VacancyDiffusion33(1,1,section) = IO_floatValue(line,positions,2_pInt)
|
lattice_vacancyfluxDiffusion33(1,1,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('vacancy_diffusion22')
|
case ('vacancyflux_diffusion22')
|
||||||
lattice_VacancyDiffusion33(2,2,section) = IO_floatValue(line,positions,2_pInt)
|
lattice_vacancyfluxDiffusion33(2,2,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('vacancy_diffusion33')
|
case ('vacancyflux_diffusion33')
|
||||||
lattice_VacancyDiffusion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
lattice_vacancyfluxDiffusion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('vacancy_mobility')
|
case ('vacancyflux_mobility11')
|
||||||
lattice_VacancyMobility(section) = IO_floatValue(line,positions,2_pInt)
|
lattice_vacancyfluxMobility33(1,1,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('vacancyflux_mobility22')
|
||||||
|
lattice_vacancyfluxMobility33(2,2,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('vacancyflux_mobility33')
|
||||||
|
lattice_vacancyfluxMobility33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('porosity_diffusion11')
|
||||||
|
lattice_PorosityDiffusion33(1,1,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('porosity_diffusion22')
|
||||||
|
lattice_PorosityDiffusion33(2,2,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('porosity_diffusion33')
|
||||||
|
lattice_PorosityDiffusion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('porosity_mobility')
|
||||||
|
lattice_PorosityMobility(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('hydrogenflux_diffusion11')
|
||||||
|
lattice_hydrogenfluxDiffusion33(1,1,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('hydrogenflux_diffusion22')
|
||||||
|
lattice_hydrogenfluxDiffusion33(2,2,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('hydrogenflux_diffusion33')
|
||||||
|
lattice_hydrogenfluxDiffusion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('hydrogenflux_mobility11')
|
||||||
|
lattice_hydrogenfluxMobility33(1,1,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('hydrogenflux_mobility22')
|
||||||
|
lattice_hydrogenfluxMobility33(2,2,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('hydrogenflux_mobility33')
|
||||||
|
lattice_hydrogenfluxMobility33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('vacancy_eqcv')
|
case ('vacancy_eqcv')
|
||||||
lattice_equilibriumVacancyConcentration(section) = IO_floatValue(line,positions,2_pInt)
|
lattice_equilibriumVacancyConcentration(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
end select
|
end select
|
||||||
|
@ -1322,7 +1362,7 @@ subroutine lattice_initializeStructure(myPhase,CoverA,aA,aM,cM)
|
||||||
cd, cn, ct
|
cd, cn, ct
|
||||||
integer(pInt) :: &
|
integer(pInt) :: &
|
||||||
i,j, &
|
i,j, &
|
||||||
myNslip, myNtwin, myNtrans, myNcleavage
|
myNslip = 0_pInt, myNtwin = 0_pInt, myNtrans = 0_pInt, myNcleavage = 0_pInt
|
||||||
|
|
||||||
lattice_C66(1:6,1:6,myPhase) = lattice_symmetrizeC66(lattice_structure(myPhase),&
|
lattice_C66(1:6,1:6,myPhase) = lattice_symmetrizeC66(lattice_structure(myPhase),&
|
||||||
lattice_C66(1:6,1:6,myPhase))
|
lattice_C66(1:6,1:6,myPhase))
|
||||||
|
@ -1347,8 +1387,16 @@ subroutine lattice_initializeStructure(myPhase,CoverA,aA,aM,cM)
|
||||||
lattice_thermalExpansion33(1:3,1:3,myPhase))
|
lattice_thermalExpansion33(1:3,1:3,myPhase))
|
||||||
lattice_DamageDiffusion33(1:3,1:3,myPhase) = lattice_symmetrize33(lattice_structure(myPhase),&
|
lattice_DamageDiffusion33(1:3,1:3,myPhase) = lattice_symmetrize33(lattice_structure(myPhase),&
|
||||||
lattice_DamageDiffusion33(1:3,1:3,myPhase))
|
lattice_DamageDiffusion33(1:3,1:3,myPhase))
|
||||||
lattice_VacancyDiffusion33(1:3,1:3,myPhase) = lattice_symmetrize33(lattice_structure(myPhase),&
|
lattice_vacancyfluxDiffusion33(1:3,1:3,myPhase) = lattice_symmetrize33(lattice_structure(myPhase),&
|
||||||
lattice_VacancyDiffusion33(1:3,1:3,myPhase))
|
lattice_vacancyfluxDiffusion33(1:3,1:3,myPhase))
|
||||||
|
lattice_vacancyfluxMobility33(1:3,1:3,myPhase) = lattice_symmetrize33(lattice_structure(myPhase),&
|
||||||
|
lattice_vacancyfluxMobility33(1:3,1:3,myPhase))
|
||||||
|
lattice_PorosityDiffusion33(1:3,1:3,myPhase) = lattice_symmetrize33(lattice_structure(myPhase),&
|
||||||
|
lattice_PorosityDiffusion33(1:3,1:3,myPhase))
|
||||||
|
lattice_hydrogenfluxDiffusion33(1:3,1:3,myPhase) = lattice_symmetrize33(lattice_structure(myPhase),&
|
||||||
|
lattice_hydrogenfluxDiffusion33(1:3,1:3,myPhase))
|
||||||
|
lattice_hydrogenfluxMobility33(1:3,1:3,myPhase) = lattice_symmetrize33(lattice_structure(myPhase),&
|
||||||
|
lattice_hydrogenfluxMobility33(1:3,1:3,myPhase))
|
||||||
|
|
||||||
select case(lattice_structure(myPhase))
|
select case(lattice_structure(myPhase))
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -14,41 +14,55 @@ module material
|
||||||
pInt, &
|
pInt, &
|
||||||
tState, &
|
tState, &
|
||||||
tPlasticState, &
|
tPlasticState, &
|
||||||
tFieldData, &
|
tSourceState, &
|
||||||
|
tHomogMapping, &
|
||||||
|
tPhaseMapping, &
|
||||||
|
p_vec, &
|
||||||
p_intvec
|
p_intvec
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
character(len=*), parameter, public :: &
|
character(len=*), parameter, public :: &
|
||||||
ELASTICITY_hooke_label = 'hooke', &
|
ELASTICITY_hooke_label = 'hooke', &
|
||||||
PLASTICITY_none_label = 'none', &
|
PLASTICITY_none_label = 'none', &
|
||||||
PLASTICITY_j2_label = 'j2', &
|
PLASTICITY_j2_label = 'j2', &
|
||||||
PLASTICITY_phenopowerlaw_label = 'phenopowerlaw', &
|
PLASTICITY_phenopowerlaw_label = 'phenopowerlaw', &
|
||||||
PLASTICITY_dislotwin_label = 'dislotwin', &
|
PLASTICITY_dislotwin_label = 'dislo&twin', &
|
||||||
PLASTICITY_dislokmc_label = 'dislokmc', &
|
PLASTICITY_dislokmc_label = 'dislokmc', &
|
||||||
PLASTICITY_disloucla_label = 'disloucla', &
|
PLASTICITY_disloucla_label = 'disloucla', &
|
||||||
PLASTICITY_titanmod_label = 'titanmod', &
|
PLASTICITY_titanmod_label = 'titanmod', &
|
||||||
PLASTICITY_nonlocal_label = 'nonlocal', &
|
PLASTICITY_nonlocal_label = 'nonlocal', &
|
||||||
LOCAL_DAMAGE_none_LABEL = 'none', &
|
SOURCE_thermal_dissipation_label = 'thermal_dissipation', &
|
||||||
LOCAL_DAMAGE_isoBrittle_LABEL = 'isobrittle', &
|
SOURCE_damage_isoBrittle_label = 'damage_isobrittle', &
|
||||||
LOCAL_DAMAGE_isoDuctile_LABEL = 'isoductile', &
|
SOURCE_damage_isoDuctile_label = 'damage_isoductile', &
|
||||||
LOCAL_DAMAGE_anisoBrittle_LABEL= 'anisobrittle', &
|
SOURCE_damage_anisoBrittle_label = 'damage_anisobrittle', &
|
||||||
LOCAL_DAMAGE_anisoDuctile_LABEL= 'anisoductile', &
|
SOURCE_damage_anisoDuctile_label = 'damage_anisoductile', &
|
||||||
LOCAL_DAMAGE_gurson_LABEL = 'gurson', &
|
SOURCE_vacancy_phenoplasticity_label = 'vacancy_phenoplasticity', &
|
||||||
LOCAL_DAMAGE_phaseField_LABEL = 'phasefield', &
|
SOURCE_vacancy_irradiation_label = 'vacancy_irradiation', &
|
||||||
LOCAL_THERMAL_isothermal_label = 'isothermal', &
|
SOURCE_vacancy_thermalfluc_label = 'vacancy_thermalfluctuation', &
|
||||||
LOCAL_THERMAL_adiabatic_label = 'adiabatic', &
|
KINEMATICS_thermal_expansion_label = 'thermal_expansion', &
|
||||||
LOCAL_VACANCY_constant_label = 'constant', &
|
KINEMATICS_cleavage_opening_label = 'cleavage_opening', &
|
||||||
LOCAL_VACANCY_generation_label = 'generation', &
|
KINEMATICS_slipplane_opening_label = 'slipplane_opening', &
|
||||||
FIELD_DAMAGE_local_label = 'local', &
|
KINEMATICS_vacancy_strain_label = 'vacancy_strain', &
|
||||||
FIELD_DAMAGE_nonlocal_label = 'nonlocal', &
|
KINEMATICS_hydrogen_strain_label = 'hydrogen_strain', &
|
||||||
FIELD_THERMAL_local_label = 'local', &
|
STIFFNESS_DEGRADATION_damage_label = 'damage', &
|
||||||
FIELD_THERMAL_nonlocal_label = 'nonlocal', &
|
STIFFNESS_DEGRADATION_porosity_label = 'porosity', &
|
||||||
FIELD_VACANCY_local_label = 'local', &
|
THERMAL_isothermal_label = 'isothermal', &
|
||||||
FIELD_VACANCY_nonlocal_label = 'nonlocal', &
|
THERMAL_adiabatic_label = 'adiabatic', &
|
||||||
HOMOGENIZATION_none_label = 'none', &
|
THERMAL_conduction_label = 'conduction', &
|
||||||
HOMOGENIZATION_isostrain_label = 'isostrain', &
|
DAMAGE_none_label = 'none', &
|
||||||
HOMOGENIZATION_rgc_label = 'rgc'
|
DAMAGE_local_label = 'local', &
|
||||||
|
DAMAGE_nonlocal_label = 'nonlocal', &
|
||||||
|
VACANCYFLUX_isoconc_label = 'isoconcentration', &
|
||||||
|
VACANCYFLUX_isochempot_label = 'isochemicalpotential', &
|
||||||
|
VACANCYFLUX_cahnhilliard_label = 'cahnhilliard', &
|
||||||
|
POROSITY_none_label = 'none', &
|
||||||
|
POROSITY_phasefield_label = 'phasefield', &
|
||||||
|
HYDROGENFLUX_isoconc_label = 'isoconcentration', &
|
||||||
|
HYDROGENFLUX_cahnhilliard_label = 'cahnhilliard', &
|
||||||
|
HOMOGENIZATION_none_label = 'none', &
|
||||||
|
HOMOGENIZATION_isostrain_label = 'isostrain', &
|
||||||
|
HOMOGENIZATION_rgc_label = 'rgc'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,37 +81,61 @@ module material
|
||||||
PLASTICITY_titanmod_ID, &
|
PLASTICITY_titanmod_ID, &
|
||||||
PLASTICITY_nonlocal_ID
|
PLASTICITY_nonlocal_ID
|
||||||
end enum
|
end enum
|
||||||
|
|
||||||
enum, bind(c)
|
enum, bind(c)
|
||||||
enumerator :: LOCAL_DAMAGE_none_ID, &
|
enumerator :: SOURCE_undefined_ID, &
|
||||||
LOCAL_DAMAGE_isoBrittle_ID, &
|
SOURCE_thermal_dissipation_ID, &
|
||||||
LOCAL_DAMAGE_isoDuctile_ID, &
|
SOURCE_damage_isoBrittle_ID, &
|
||||||
LOCAL_DAMAGE_anisoBrittle_ID, &
|
SOURCE_damage_isoDuctile_ID, &
|
||||||
LOCAL_DAMAGE_anisoDuctile_ID, &
|
SOURCE_damage_anisoBrittle_ID, &
|
||||||
LOCAL_DAMAGE_gurson_ID, &
|
SOURCE_damage_anisoDuctile_ID, &
|
||||||
LOCAL_DAMAGE_phaseField_ID
|
SOURCE_vacancy_phenoplasticity_ID, &
|
||||||
end enum
|
SOURCE_vacancy_irradiation_ID, &
|
||||||
enum, bind(c)
|
SOURCE_vacancy_thermalfluc_ID
|
||||||
enumerator :: LOCAL_THERMAL_isothermal_ID, &
|
|
||||||
LOCAL_THERMAL_adiabatic_ID
|
|
||||||
end enum
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: LOCAL_VACANCY_constant_ID, &
|
|
||||||
LOCAL_VACANCY_generation_ID
|
|
||||||
end enum
|
end enum
|
||||||
|
|
||||||
enum, bind(c)
|
enum, bind(c)
|
||||||
enumerator :: FIELD_DAMAGE_local_ID ,&
|
enumerator :: KINEMATICS_undefined_ID, &
|
||||||
FIELD_DAMAGE_nonlocal_ID
|
KINEMATICS_cleavage_opening_ID, &
|
||||||
|
KINEMATICS_slipplane_opening_ID, &
|
||||||
|
KINEMATICS_thermal_expansion_ID, &
|
||||||
|
KINEMATICS_vacancy_strain_ID, &
|
||||||
|
KINEMATICS_hydrogen_strain_ID
|
||||||
|
end enum
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: STIFFNESS_DEGRADATION_undefined_ID, &
|
||||||
|
STIFFNESS_DEGRADATION_damage_ID, &
|
||||||
|
STIFFNESS_DEGRADATION_porosity_ID
|
||||||
|
end enum
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: THERMAL_isothermal_ID, &
|
||||||
|
THERMAL_adiabatic_ID, &
|
||||||
|
THERMAL_conduction_ID
|
||||||
|
end enum
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: DAMAGE_none_ID, &
|
||||||
|
DAMAGE_local_ID, &
|
||||||
|
DAMAGE_nonlocal_ID
|
||||||
|
end enum
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: VACANCYFLUX_isoconc_ID, &
|
||||||
|
VACANCYFLUX_isochempot_ID, &
|
||||||
|
VACANCYFLUX_cahnhilliard_ID
|
||||||
|
end enum
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: POROSITY_none_ID, &
|
||||||
|
POROSITY_phasefield_ID
|
||||||
end enum
|
end enum
|
||||||
enum, bind(c)
|
enum, bind(c)
|
||||||
enumerator :: FIELD_THERMAL_local_ID, &
|
enumerator :: HYDROGENFLUX_isoconc_ID, &
|
||||||
FIELD_THERMAL_nonlocal_ID
|
HYDROGENFLUX_cahnhilliard_ID
|
||||||
end enum
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: FIELD_VACANCY_local_ID, &
|
|
||||||
FIELD_VACANCY_nonlocal_ID
|
|
||||||
end enum
|
end enum
|
||||||
|
|
||||||
enum, bind(c)
|
enum, bind(c)
|
||||||
enumerator :: HOMOGENIZATION_undefined_ID, &
|
enumerator :: HOMOGENIZATION_undefined_ID, &
|
||||||
HOMOGENIZATION_none_ID, &
|
HOMOGENIZATION_none_ID, &
|
||||||
|
@ -118,18 +156,21 @@ module material
|
||||||
phase_elasticity !< elasticity of each phase
|
phase_elasticity !< elasticity of each phase
|
||||||
integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable, public, protected :: &
|
integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable, public, protected :: &
|
||||||
phase_plasticity !< plasticity of each phase
|
phase_plasticity !< plasticity of each phase
|
||||||
integer(kind(LOCAL_DAMAGE_none_ID)), dimension(:), allocatable, public, protected :: &
|
integer(kind(THERMAL_isothermal_ID)), dimension(:), allocatable, public, protected :: &
|
||||||
phase_damage !< local damage of each phase
|
thermal_type !< thermal transport model
|
||||||
integer(kind(LOCAL_THERMAL_isothermal_ID)), dimension(:), allocatable, public, protected :: &
|
integer(kind(DAMAGE_none_ID)), dimension(:), allocatable, public, protected :: &
|
||||||
phase_thermal !< local thermal of each phase
|
damage_type !< nonlocal damage model
|
||||||
integer(kind(LOCAL_VACANCY_constant_ID)), dimension(:), allocatable, public, protected :: &
|
integer(kind(VACANCYFLUX_isoconc_ID)), dimension(:), allocatable, public, protected :: &
|
||||||
phase_vacancy !< local vacancy model of each phase
|
vacancyflux_type !< vacancy transport model
|
||||||
integer(kind(FIELD_DAMAGE_local_ID)), dimension(:), allocatable, public, protected :: &
|
integer(kind(POROSITY_none_ID)), dimension(:), allocatable, public, protected :: &
|
||||||
field_damage_type !< field damage of each phase
|
porosity_type !< porosity evolution model
|
||||||
integer(kind(FIELD_THERMAL_local_ID)), dimension(:), allocatable, public, protected :: &
|
integer(kind(HYDROGENFLUX_isoconc_ID)), dimension(:), allocatable, public, protected :: &
|
||||||
field_thermal_type !< field thermal of each phase
|
hydrogenflux_type !< hydrogen transport model
|
||||||
integer(kind(FIELD_VACANCY_local_ID)), dimension(:), allocatable, public, protected :: &
|
|
||||||
field_vacancy_type !< field vacancy of each phase
|
integer(kind(SOURCE_undefined_ID)), dimension(:,:), allocatable, public, protected :: &
|
||||||
|
phase_source, & !< active sources mechanisms of each phase
|
||||||
|
phase_kinematics, & !< active kinematic mechanisms of each phase
|
||||||
|
phase_stiffnessDegradation !< active stiffness degradation mechanisms of each phase
|
||||||
|
|
||||||
integer(kind(HOMOGENIZATION_undefined_ID)), dimension(:), allocatable, public, protected :: &
|
integer(kind(HOMOGENIZATION_undefined_ID)), dimension(:), allocatable, public, protected :: &
|
||||||
homogenization_type !< type of each homogenization
|
homogenization_type !< type of each homogenization
|
||||||
|
@ -146,17 +187,24 @@ module material
|
||||||
material_Nmicrostructure, & !< number of microstructures
|
material_Nmicrostructure, & !< number of microstructures
|
||||||
material_Ncrystallite !< number of crystallite settings
|
material_Ncrystallite !< number of crystallite settings
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
phase_Nsources, & !< number of source mechanisms active in each phase
|
||||||
|
phase_Nkinematics, & !< number of kinematic mechanisms active in each phase
|
||||||
|
phase_NstiffnessDegradations !< number of stiffness degradation mechanisms active in each phase
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
homogenization_Ngrains, & !< number of grains in each homogenization
|
homogenization_Ngrains, & !< number of grains in each homogenization
|
||||||
homogenization_Noutput, & !< number of '(output)' items per homogenization
|
homogenization_Noutput, & !< number of '(output)' items per homogenization
|
||||||
phase_Noutput, & !< number of '(output)' items per phase
|
phase_Noutput, & !< number of '(output)' items per phase
|
||||||
phase_elasticityInstance, & !< instance of particular elasticity of each phase
|
phase_elasticityInstance, & !< instance of particular elasticity of each phase
|
||||||
phase_plasticityInstance, & !< instance of particular plasticity of each phase
|
phase_plasticityInstance, & !< instance of particular plasticity of each phase
|
||||||
phase_damageInstance, & !< instance of particular damage of each phase
|
|
||||||
phase_thermalInstance, & !< instance of particular thermal of each phase
|
|
||||||
phase_vacancyInstance, & !< instance of particular vacancy model of each phase
|
|
||||||
crystallite_Noutput, & !< number of '(output)' items per crystallite setting
|
crystallite_Noutput, & !< number of '(output)' items per crystallite setting
|
||||||
homogenization_typeInstance, & !< instance of particular type of each homogenization
|
homogenization_typeInstance, & !< instance of particular type of each homogenization
|
||||||
|
thermal_typeInstance, & !< instance of particular type of each thermal transport
|
||||||
|
damage_typeInstance, & !< instance of particular type of each nonlocal damage
|
||||||
|
vacancyflux_typeInstance, & !< instance of particular type of each vacancy flux
|
||||||
|
porosity_typeInstance, & !< instance of particular type of each porosity model
|
||||||
|
hydrogenflux_typeInstance, & !< instance of particular type of each hydrogen flux
|
||||||
microstructure_crystallite !< crystallite setting ID of each microstructure
|
microstructure_crystallite !< crystallite setting ID of each microstructure
|
||||||
|
|
||||||
integer(pInt), dimension(:,:,:), allocatable, public :: &
|
integer(pInt), dimension(:,:,:), allocatable, public :: &
|
||||||
|
@ -165,19 +213,15 @@ module material
|
||||||
material_homog !< homogenization (index) of each IP,element
|
material_homog !< homogenization (index) of each IP,element
|
||||||
type(tPlasticState), allocatable, dimension(:), public :: &
|
type(tPlasticState), allocatable, dimension(:), public :: &
|
||||||
plasticState
|
plasticState
|
||||||
type(tState), allocatable, dimension(:), public :: &
|
type(tSourceState), allocatable, dimension(:), public :: &
|
||||||
|
sourceState
|
||||||
|
type(tState), allocatable, dimension(:), public :: &
|
||||||
|
homogState, &
|
||||||
|
thermalState, &
|
||||||
damageState, &
|
damageState, &
|
||||||
thermalState,&
|
vacancyfluxState, &
|
||||||
vacancyState,&
|
porosityState, &
|
||||||
homogState
|
hydrogenfluxState
|
||||||
|
|
||||||
type(tFieldData), allocatable, dimension(:), public :: &
|
|
||||||
fieldDamage
|
|
||||||
type(tFieldData), allocatable, dimension(:), public :: &
|
|
||||||
fieldThermal
|
|
||||||
type(tFieldData), allocatable, dimension(:), public :: &
|
|
||||||
fieldVacancy
|
|
||||||
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:,:), allocatable, public, protected :: &
|
integer(pInt), dimension(:,:,:), allocatable, public, protected :: &
|
||||||
material_texture !< texture (index) of each grain,IP,element
|
material_texture !< texture (index) of each grain,IP,element
|
||||||
|
@ -230,9 +274,27 @@ module material
|
||||||
logical, dimension(:), allocatable, private :: &
|
logical, dimension(:), allocatable, private :: &
|
||||||
homogenization_active
|
homogenization_active
|
||||||
|
|
||||||
integer(pInt), dimension(:,:,:,:), allocatable, public, protected :: mappingConstitutive
|
integer(pInt), dimension(:,:,:,:), allocatable, public, target :: mappingConstitutive
|
||||||
integer(pInt), dimension(:,:,:), allocatable, public, protected :: mappingCrystallite
|
integer(pInt), dimension(:,:,:), allocatable, public, target :: mappingCrystallite
|
||||||
integer(pInt), dimension(:,:,:), allocatable, public, protected :: mappingHomogenization
|
integer(pInt), dimension(:,:,:), allocatable, public, target :: mappingHomogenization !< mapping from material points to offset in heterogenous state/field
|
||||||
|
integer(pInt), dimension(:,:), allocatable, public, target :: mappingHomogenizationConst !< mapping from material points to offset in constant state/field
|
||||||
|
|
||||||
|
type(tHomogMapping), allocatable, dimension(:), public :: &
|
||||||
|
thermalMapping, & !< mapping for thermal state/fields
|
||||||
|
damageMapping, & !< mapping for damage state/fields
|
||||||
|
vacancyfluxMapping, & !< mapping for vacancy conc state/fields
|
||||||
|
porosityMapping, & !< mapping for porosity state/fields
|
||||||
|
hydrogenfluxMapping !< mapping for hydrogen conc state/fields
|
||||||
|
|
||||||
|
type(p_vec), allocatable, dimension(:), public :: &
|
||||||
|
temperature, & !< temperature field
|
||||||
|
damage, & !< damage field
|
||||||
|
vacancyConc, & !< vacancy conc field
|
||||||
|
porosity, & !< porosity field
|
||||||
|
hydrogenConc, & !< hydrogen conc field
|
||||||
|
temperatureRate, & !< temperature change rate field
|
||||||
|
vacancyConcRate, & !< vacancy conc change field
|
||||||
|
hydrogenConcRate !< hydrogen conc change field
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
material_init, &
|
material_init, &
|
||||||
|
@ -245,23 +307,34 @@ module material
|
||||||
PLASTICITY_disloucla_ID, &
|
PLASTICITY_disloucla_ID, &
|
||||||
PLASTICITY_titanmod_ID, &
|
PLASTICITY_titanmod_ID, &
|
||||||
PLASTICITY_nonlocal_ID, &
|
PLASTICITY_nonlocal_ID, &
|
||||||
LOCAL_DAMAGE_none_ID, &
|
SOURCE_thermal_dissipation_ID, &
|
||||||
LOCAL_DAMAGE_isoBrittle_ID, &
|
SOURCE_damage_isoBrittle_ID, &
|
||||||
LOCAL_DAMAGE_isoDuctile_ID, &
|
SOURCE_damage_isoDuctile_ID, &
|
||||||
LOCAL_DAMAGE_anisoBrittle_ID, &
|
SOURCE_damage_anisoBrittle_ID, &
|
||||||
LOCAL_DAMAGE_anisoDuctile_ID, &
|
SOURCE_damage_anisoDuctile_ID, &
|
||||||
LOCAL_DAMAGE_gurson_ID, &
|
SOURCE_vacancy_phenoplasticity_ID, &
|
||||||
LOCAL_DAMAGE_phaseField_ID, &
|
SOURCE_vacancy_irradiation_ID, &
|
||||||
LOCAL_THERMAL_isothermal_ID, &
|
SOURCE_vacancy_thermalfluc_ID, &
|
||||||
LOCAL_THERMAL_adiabatic_ID, &
|
KINEMATICS_cleavage_opening_ID, &
|
||||||
LOCAL_VACANCY_constant_ID, &
|
KINEMATICS_slipplane_opening_ID, &
|
||||||
LOCAL_VACANCY_generation_ID, &
|
KINEMATICS_thermal_expansion_ID, &
|
||||||
FIELD_DAMAGE_local_ID, &
|
KINEMATICS_vacancy_strain_ID, &
|
||||||
FIELD_DAMAGE_nonlocal_ID, &
|
KINEMATICS_hydrogen_strain_ID, &
|
||||||
FIELD_THERMAL_local_ID, &
|
STIFFNESS_DEGRADATION_damage_ID, &
|
||||||
FIELD_THERMAL_nonlocal_ID, &
|
STIFFNESS_DEGRADATION_porosity_ID, &
|
||||||
FIELD_VACANCY_local_ID, &
|
THERMAL_isothermal_ID, &
|
||||||
FIELD_VACANCY_nonlocal_ID, &
|
THERMAL_adiabatic_ID, &
|
||||||
|
THERMAL_conduction_ID, &
|
||||||
|
DAMAGE_none_ID, &
|
||||||
|
DAMAGE_local_ID, &
|
||||||
|
DAMAGE_nonlocal_ID, &
|
||||||
|
VACANCYFLUX_isoconc_ID, &
|
||||||
|
VACANCYFLUX_isochempot_ID, &
|
||||||
|
VACANCYFLUX_cahnhilliard_ID, &
|
||||||
|
POROSITY_none_ID, &
|
||||||
|
POROSITY_phasefield_ID, &
|
||||||
|
HYDROGENFLUX_isoconc_ID, &
|
||||||
|
HYDROGENFLUX_cahnhilliard_ID, &
|
||||||
HOMOGENIZATION_none_ID, &
|
HOMOGENIZATION_none_ID, &
|
||||||
HOMOGENIZATION_isostrain_ID, &
|
HOMOGENIZATION_isostrain_ID, &
|
||||||
#ifdef HDF
|
#ifdef HDF
|
||||||
|
@ -285,7 +358,7 @@ contains
|
||||||
!> @details figures out if solverJobName.materialConfig is present, if not looks for
|
!> @details figures out if solverJobName.materialConfig is present, if not looks for
|
||||||
!> material.config
|
!> material.config
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine material_init(temperature_init)
|
subroutine material_init()
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
use IO, only: &
|
use IO, only: &
|
||||||
IO_error, &
|
IO_error, &
|
||||||
|
@ -307,16 +380,13 @@ subroutine material_init(temperature_init)
|
||||||
worldrank
|
worldrank
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
real(pReal), intent(in) :: temperature_init !< initial field temperature
|
|
||||||
integer(pInt), parameter :: FILEUNIT = 200_pInt
|
integer(pInt), parameter :: FILEUNIT = 200_pInt
|
||||||
integer(pInt) :: m,c,h, myDebug, myHomog
|
integer(pInt) :: m,c,h, myDebug, myPhase, myHomog
|
||||||
integer(pInt) :: &
|
integer(pInt) :: &
|
||||||
g, & !< grain number
|
g, & !< grain number
|
||||||
i, & !< integration point number
|
i, & !< integration point number
|
||||||
e, & !< element number
|
e, & !< element number
|
||||||
phase, &
|
phase
|
||||||
homog, &
|
|
||||||
NofMyField
|
|
||||||
integer(pInt), dimension(:), allocatable :: ConstitutivePosition
|
integer(pInt), dimension(:), allocatable :: ConstitutivePosition
|
||||||
integer(pInt), dimension(:), allocatable :: CrystallitePosition
|
integer(pInt), dimension(:), allocatable :: CrystallitePosition
|
||||||
integer(pInt), dimension(:), allocatable :: HomogenizationPosition
|
integer(pInt), dimension(:), allocatable :: HomogenizationPosition
|
||||||
|
@ -344,14 +414,35 @@ subroutine material_init(temperature_init)
|
||||||
if (iand(myDebug,debug_levelBasic) /= 0_pInt) write(6,'(a)') ' Phase parsed'; flush(6)
|
if (iand(myDebug,debug_levelBasic) /= 0_pInt) write(6,'(a)') ' Phase parsed'; flush(6)
|
||||||
close(FILEUNIT)
|
close(FILEUNIT)
|
||||||
|
|
||||||
allocate(plasticState(material_Nphase))
|
allocate(plasticState (material_Nphase))
|
||||||
allocate(damageState (material_Nphase))
|
allocate(sourceState (material_Nphase))
|
||||||
allocate(thermalState(material_Nphase))
|
do myPhase = 1,material_Nphase
|
||||||
allocate(vacancyState(material_Nphase))
|
allocate(sourceState(myPhase)%p(phase_Nsources(myPhase)))
|
||||||
allocate(homogState (material_Nhomogenization))
|
enddo
|
||||||
allocate(fieldDamage (material_Nhomogenization))
|
|
||||||
allocate(fieldThermal(material_Nhomogenization))
|
allocate(homogState (material_Nhomogenization))
|
||||||
allocate(fieldVacancy(material_Nhomogenization))
|
allocate(thermalState (material_Nhomogenization))
|
||||||
|
allocate(damageState (material_Nhomogenization))
|
||||||
|
allocate(vacancyfluxState (material_Nhomogenization))
|
||||||
|
allocate(porosityState (material_Nhomogenization))
|
||||||
|
allocate(hydrogenfluxState (material_Nhomogenization))
|
||||||
|
|
||||||
|
allocate(thermalMapping (material_Nhomogenization))
|
||||||
|
allocate(damageMapping (material_Nhomogenization))
|
||||||
|
allocate(vacancyfluxMapping (material_Nhomogenization))
|
||||||
|
allocate(porosityMapping (material_Nhomogenization))
|
||||||
|
allocate(hydrogenfluxMapping(material_Nhomogenization))
|
||||||
|
|
||||||
|
allocate(temperature (material_Nhomogenization))
|
||||||
|
allocate(damage (material_Nhomogenization))
|
||||||
|
allocate(vacancyConc (material_Nhomogenization))
|
||||||
|
allocate(porosity (material_Nhomogenization))
|
||||||
|
allocate(hydrogenConc (material_Nhomogenization))
|
||||||
|
|
||||||
|
allocate(temperatureRate (material_Nhomogenization))
|
||||||
|
allocate(vacancyConcRate (material_Nhomogenization))
|
||||||
|
allocate(hydrogenConcRate (material_Nhomogenization))
|
||||||
|
|
||||||
do m = 1_pInt,material_Nmicrostructure
|
do m = 1_pInt,material_Nmicrostructure
|
||||||
if(microstructure_crystallite(m) < 1_pInt .or. &
|
if(microstructure_crystallite(m) < 1_pInt .or. &
|
||||||
microstructure_crystallite(m) > material_Ncrystallite) &
|
microstructure_crystallite(m) > material_Ncrystallite) &
|
||||||
|
@ -365,6 +456,7 @@ subroutine material_init(temperature_init)
|
||||||
if(microstructure_Nconstituents(m) < 1_pInt) &
|
if(microstructure_Nconstituents(m) < 1_pInt) &
|
||||||
call IO_error(151_pInt,m)
|
call IO_error(151_pInt,m)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
debugOut: if (iand(myDebug,debug_levelExtensive) /= 0_pInt) then
|
debugOut: if (iand(myDebug,debug_levelExtensive) /= 0_pInt) then
|
||||||
write(6,'(/,a,/)') ' MATERIAL configuration'
|
write(6,'(/,a,/)') ' MATERIAL configuration'
|
||||||
write(6,'(a32,1x,a16,1x,a6)') 'homogenization ','type ','grains'
|
write(6,'(a32,1x,a16,1x,a6)') 'homogenization ','type ','grains'
|
||||||
|
@ -390,14 +482,14 @@ subroutine material_init(temperature_init)
|
||||||
|
|
||||||
call material_populateGrains
|
call material_populateGrains
|
||||||
|
|
||||||
allocate(mappingConstitutive(2,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems),source=0_pInt)
|
allocate(mappingConstitutive (2,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems),source=0_pInt)
|
||||||
allocate(mappingHomogenization(2,mesh_maxNips,mesh_NcpElems),source=0_pInt)
|
allocate(mappingHomogenization (2, mesh_maxNips,mesh_NcpElems),source=0_pInt)
|
||||||
|
allocate(mappingCrystallite (2,homogenization_maxNgrains, mesh_NcpElems),source=0_pInt)
|
||||||
allocate(mappingCrystallite (2,homogenization_maxNgrains,mesh_NcpElems),source=0_pInt)
|
allocate(mappingHomogenizationConst( mesh_maxNips,mesh_NcpElems),source=1_pInt)
|
||||||
allocate(ConstitutivePosition(material_Nphase),source=0_pInt)
|
|
||||||
|
|
||||||
|
allocate(ConstitutivePosition (material_Nphase), source=0_pInt)
|
||||||
allocate(HomogenizationPosition(material_Nhomogenization),source=0_pInt)
|
allocate(HomogenizationPosition(material_Nhomogenization),source=0_pInt)
|
||||||
allocate(CrystallitePosition(material_Nphase),source=0_pInt)
|
allocate(CrystallitePosition (material_Nphase), source=0_pInt)
|
||||||
|
|
||||||
ElemLoop:do e = 1_pInt,mesh_NcpElems ! loop over elements
|
ElemLoop:do e = 1_pInt,mesh_NcpElems ! loop over elements
|
||||||
myHomog = mesh_element(3,e)
|
myHomog = mesh_element(3,e)
|
||||||
|
@ -412,55 +504,21 @@ subroutine material_init(temperature_init)
|
||||||
enddo IPloop
|
enddo IPloop
|
||||||
enddo ElemLoop
|
enddo ElemLoop
|
||||||
|
|
||||||
do homog = 1,material_Nhomogenization
|
! hack needed to initialize field values used during constitutive and crystallite initializations
|
||||||
NofMyField=count(material_homog==homog)
|
do myHomog = 1,material_Nhomogenization
|
||||||
select case(field_damage_type(homog))
|
thermalMapping (myHomog)%p => mappingHomogenizationConst
|
||||||
case (FIELD_DAMAGE_LOCAL_ID)
|
damageMapping (myHomog)%p => mappingHomogenizationConst
|
||||||
fieldDamage(homog)%sizeField = 0_pInt
|
vacancyfluxMapping (myHomog)%p => mappingHomogenizationConst
|
||||||
fieldDamage(homog)%sizePostResults = 0_pInt
|
porosityMapping (myHomog)%p => mappingHomogenizationConst
|
||||||
allocate(fieldDamage(homog)%field(fieldDamage(homog)%sizeField,NofMyField), source = 1.0_pReal)
|
hydrogenfluxMapping(myHomog)%p => mappingHomogenizationConst
|
||||||
|
allocate(temperature (myHomog)%p(1), source=300.0_pReal)
|
||||||
case (FIELD_DAMAGE_NONLOCAL_ID)
|
allocate(damage (myHomog)%p(1), source=1.0_pReal)
|
||||||
fieldDamage(homog)%sizeField = 1_pInt
|
allocate(vacancyConc (myHomog)%p(1), source=0.0_pReal)
|
||||||
fieldDamage(homog)%sizePostResults = 1_pInt
|
allocate(porosity (myHomog)%p(1), source=1.0_pReal)
|
||||||
allocate(fieldDamage(homog)%field(fieldDamage(homog)%sizeField,NofMyField), source = 1.0_pReal)
|
allocate(hydrogenConc (myHomog)%p(1), source=0.0_pReal)
|
||||||
|
allocate(temperatureRate (myHomog)%p(1), source=0.0_pReal)
|
||||||
end select
|
allocate(vacancyConcRate (myHomog)%p(1), source=0.0_pReal)
|
||||||
enddo
|
allocate(hydrogenConcRate(myHomog)%p(1), source=0.0_pReal)
|
||||||
|
|
||||||
do homog = 1,material_Nhomogenization
|
|
||||||
NofMyField=count(material_homog==homog)
|
|
||||||
select case(field_thermal_type(homog))
|
|
||||||
case (FIELD_THERMAL_local_ID)
|
|
||||||
fieldThermal(homog)%sizeField = 0_pInt
|
|
||||||
fieldThermal(homog)%sizePostResults = 0_pInt
|
|
||||||
allocate(fieldThermal(homog)%field(fieldThermal(homog)%sizeField,NofMyField))
|
|
||||||
|
|
||||||
case (FIELD_THERMAL_nonlocal_ID)
|
|
||||||
fieldThermal(homog)%sizeField = 1_pInt
|
|
||||||
fieldThermal(homog)%sizePostResults = 1_pInt
|
|
||||||
allocate(fieldThermal(homog)%field(fieldThermal(homog)%sizeField,NofMyField), &
|
|
||||||
source = temperature_init)
|
|
||||||
|
|
||||||
end select
|
|
||||||
enddo
|
|
||||||
|
|
||||||
do homog = 1,material_Nhomogenization
|
|
||||||
NofMyField=count(material_homog==homog)
|
|
||||||
select case(field_vacancy_type(homog))
|
|
||||||
case (FIELD_VACANCY_local_ID)
|
|
||||||
fieldVacancy(homog)%sizeField = 0_pInt
|
|
||||||
fieldVacancy(homog)%sizePostResults = 0_pInt
|
|
||||||
allocate(fieldVacancy(homog)%field(fieldVacancy(homog)%sizeField,NofMyField), &
|
|
||||||
source = 0.0_pReal)
|
|
||||||
|
|
||||||
case (FIELD_VACANCY_nonlocal_ID)
|
|
||||||
fieldVacancy(homog)%sizeField = 1_pInt
|
|
||||||
fieldVacancy(homog)%sizePostResults = 1_pInt
|
|
||||||
allocate(fieldVacancy(homog)%field(fieldVacancy(homog)%sizeField,NofMyField), &
|
|
||||||
source = 0.0_pReal)
|
|
||||||
|
|
||||||
end select
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
end subroutine material_init
|
end subroutine material_init
|
||||||
|
@ -493,7 +551,7 @@ subroutine material_parseHomogenization(fileUnit,myPart)
|
||||||
integer(pInt), parameter :: MAXNCHUNKS = 2_pInt
|
integer(pInt), parameter :: MAXNCHUNKS = 2_pInt
|
||||||
|
|
||||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
integer(pInt) :: Nsections, section, s
|
integer(pInt) :: Nsections, section, s, p
|
||||||
character(len=65536) :: &
|
character(len=65536) :: &
|
||||||
tag, line
|
tag, line
|
||||||
logical :: echo
|
logical :: echo
|
||||||
|
@ -505,10 +563,17 @@ subroutine material_parseHomogenization(fileUnit,myPart)
|
||||||
|
|
||||||
allocate(homogenization_name(Nsections)); homogenization_name = ''
|
allocate(homogenization_name(Nsections)); homogenization_name = ''
|
||||||
allocate(homogenization_type(Nsections), source=HOMOGENIZATION_undefined_ID)
|
allocate(homogenization_type(Nsections), source=HOMOGENIZATION_undefined_ID)
|
||||||
allocate(FIELD_DAMAGE_type(Nsections), source=FIELD_DAMAGE_local_ID)
|
allocate(thermal_type(Nsections), source=THERMAL_isothermal_ID)
|
||||||
allocate(FIELD_THERMAL_type(Nsections), source=FIELD_THERMAL_local_ID)
|
allocate(damage_type (Nsections), source=DAMAGE_none_ID)
|
||||||
allocate(FIELD_VACANCY_type(Nsections), source=FIELD_VACANCY_local_ID)
|
allocate(vacancyflux_type(Nsections), source=VACANCYFLUX_isoconc_ID)
|
||||||
|
allocate(porosity_type (Nsections), source=POROSITY_none_ID)
|
||||||
|
allocate(hydrogenflux_type(Nsections), source=HYDROGENFLUX_isoconc_ID)
|
||||||
allocate(homogenization_typeInstance(Nsections), source=0_pInt)
|
allocate(homogenization_typeInstance(Nsections), source=0_pInt)
|
||||||
|
allocate(thermal_typeInstance(Nsections), source=0_pInt)
|
||||||
|
allocate(damage_typeInstance(Nsections), source=0_pInt)
|
||||||
|
allocate(vacancyflux_typeInstance(Nsections), source=0_pInt)
|
||||||
|
allocate(porosity_typeInstance(Nsections), source=0_pInt)
|
||||||
|
allocate(hydrogenflux_typeInstance(Nsections), source=0_pInt)
|
||||||
allocate(homogenization_Ngrains(Nsections), source=0_pInt)
|
allocate(homogenization_Ngrains(Nsections), source=0_pInt)
|
||||||
allocate(homogenization_Noutput(Nsections), source=0_pInt)
|
allocate(homogenization_Noutput(Nsections), source=0_pInt)
|
||||||
allocate(homogenization_active(Nsections), source=.false.) !!!!!!!!!!!!!!!
|
allocate(homogenization_active(Nsections), source=.false.) !!!!!!!!!!!!!!!
|
||||||
|
@ -554,32 +619,58 @@ subroutine material_parseHomogenization(fileUnit,myPart)
|
||||||
end select
|
end select
|
||||||
homogenization_typeInstance(section) = &
|
homogenization_typeInstance(section) = &
|
||||||
count(homogenization_type==homogenization_type(section)) ! count instances
|
count(homogenization_type==homogenization_type(section)) ! count instances
|
||||||
case ('field_damage')
|
case ('thermal')
|
||||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
case(FIELD_DAMAGE_LOCAL_label)
|
case(THERMAL_isothermal_label)
|
||||||
FIELD_DAMAGE_type(section) = FIELD_DAMAGE_LOCAL_ID
|
thermal_type(section) = THERMAL_isothermal_ID
|
||||||
case(FIELD_DAMAGE_NONLOCAL_label)
|
case(THERMAL_adiabatic_label)
|
||||||
FIELD_DAMAGE_type(section) = FIELD_DAMAGE_NONLOCAL_ID
|
thermal_type(section) = THERMAL_adiabatic_ID
|
||||||
|
case(THERMAL_conduction_label)
|
||||||
|
thermal_type(section) = THERMAL_conduction_ID
|
||||||
case default
|
case default
|
||||||
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||||
end select
|
end select
|
||||||
|
|
||||||
case ('field_thermal')
|
case ('damage')
|
||||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
case(FIELD_THERMAL_local_label)
|
case(DAMAGE_NONE_label)
|
||||||
FIELD_THERMAL_type(section) = FIELD_THERMAL_local_ID
|
damage_type(section) = DAMAGE_none_ID
|
||||||
case(FIELD_THERMAL_nonlocal_label)
|
case(DAMAGE_LOCAL_label)
|
||||||
FIELD_THERMAL_type(section) = FIELD_THERMAL_nonlocal_ID
|
damage_type(section) = DAMAGE_local_ID
|
||||||
|
case(DAMAGE_NONLOCAL_label)
|
||||||
|
damage_type(section) = DAMAGE_nonlocal_ID
|
||||||
case default
|
case default
|
||||||
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||||
end select
|
end select
|
||||||
|
|
||||||
case ('field_vacancy')
|
case ('vacancyflux')
|
||||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
case(FIELD_VACANCY_local_label)
|
case(VACANCYFLUX_isoconc_label)
|
||||||
FIELD_VACANCY_type(section) = FIELD_VACANCY_local_ID
|
vacancyflux_type(section) = VACANCYFLUX_isoconc_ID
|
||||||
case(FIELD_VACANCY_nonlocal_label)
|
case(VACANCYFLUX_isochempot_label)
|
||||||
FIELD_VACANCY_type(section) = FIELD_VACANCY_nonlocal_ID
|
vacancyflux_type(section) = VACANCYFLUX_isochempot_ID
|
||||||
|
case(VACANCYFLUX_cahnhilliard_label)
|
||||||
|
vacancyflux_type(section) = VACANCYFLUX_cahnhilliard_ID
|
||||||
|
case default
|
||||||
|
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
end select
|
||||||
|
|
||||||
|
case ('porosity')
|
||||||
|
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case(POROSITY_NONE_label)
|
||||||
|
porosity_type(section) = POROSITY_none_ID
|
||||||
|
case(POROSITY_phasefield_label)
|
||||||
|
porosity_type(section) = POROSITY_phasefield_ID
|
||||||
|
case default
|
||||||
|
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
end select
|
||||||
|
|
||||||
|
case ('hydrogenflux')
|
||||||
|
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case(HYDROGENFLUX_isoconc_label)
|
||||||
|
hydrogenflux_type(section) = HYDROGENFLUX_isoconc_ID
|
||||||
|
case(HYDROGENFLUX_cahnhilliard_label)
|
||||||
|
hydrogenflux_type(section) = HYDROGENFLUX_cahnhilliard_ID
|
||||||
case default
|
case default
|
||||||
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||||
end select
|
end select
|
||||||
|
@ -590,6 +681,15 @@ subroutine material_parseHomogenization(fileUnit,myPart)
|
||||||
endif
|
endif
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
do p=1_pInt, Nsections
|
||||||
|
homogenization_typeInstance(p) = count(homogenization_type(1:p) == homogenization_type(p))
|
||||||
|
thermal_typeInstance(p) = count(thermal_type (1:p) == thermal_type (p))
|
||||||
|
damage_typeInstance(p) = count(damage_type (1:p) == damage_type (p))
|
||||||
|
vacancyflux_typeInstance(p) = count(vacancyflux_type (1:p) == vacancyflux_type (p))
|
||||||
|
porosity_typeInstance(p) = count(porosity_type (1:p) == porosity_type (p))
|
||||||
|
hydrogenflux_typeInstance(p) = count(hydrogenflux_type (1:p) == hydrogenflux_type (p))
|
||||||
|
enddo
|
||||||
|
|
||||||
homogenization_maxNgrains = maxval(homogenization_Ngrains,homogenization_active)
|
homogenization_maxNgrains = maxval(homogenization_Ngrains,homogenization_active)
|
||||||
|
|
||||||
end subroutine material_parseHomogenization
|
end subroutine material_parseHomogenization
|
||||||
|
@ -775,7 +875,7 @@ subroutine material_parsePhase(fileUnit,myPart)
|
||||||
integer(pInt), parameter :: MAXNCHUNKS = 2_pInt
|
integer(pInt), parameter :: MAXNCHUNKS = 2_pInt
|
||||||
|
|
||||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
integer(pInt) :: Nsections, section, p
|
integer(pInt) :: Nsections, section, sourceCtr, kinematicsCtr, stiffDegradationCtr, p
|
||||||
character(len=65536) :: &
|
character(len=65536) :: &
|
||||||
tag,line
|
tag,line
|
||||||
logical :: echo
|
logical :: echo
|
||||||
|
@ -791,18 +891,23 @@ subroutine material_parsePhase(fileUnit,myPart)
|
||||||
allocate(phase_elasticityInstance(Nsections), source=0_pInt)
|
allocate(phase_elasticityInstance(Nsections), source=0_pInt)
|
||||||
allocate(phase_plasticity(Nsections) , source=PLASTICITY_undefined_ID)
|
allocate(phase_plasticity(Nsections) , source=PLASTICITY_undefined_ID)
|
||||||
allocate(phase_plasticityInstance(Nsections), source=0_pInt)
|
allocate(phase_plasticityInstance(Nsections), source=0_pInt)
|
||||||
allocate(phase_damage(Nsections) , source=LOCAL_DAMAGE_none_ID)
|
allocate(phase_Nsources(Nsections), source=0_pInt)
|
||||||
allocate(phase_damageInstance(Nsections), source=0_pInt)
|
allocate(phase_Nkinematics(Nsections), source=0_pInt)
|
||||||
allocate(phase_thermal(Nsections) , source=LOCAL_THERMAL_isothermal_ID)
|
allocate(phase_NstiffnessDegradations(Nsections),source=0_pInt)
|
||||||
allocate(phase_thermalInstance(Nsections), source=0_pInt)
|
|
||||||
allocate(phase_vacancy(Nsections) , source=LOCAL_VACANCY_constant_ID)
|
|
||||||
allocate(phase_vacancyInstance(Nsections), source=0_pInt)
|
|
||||||
allocate(phase_Noutput(Nsections), source=0_pInt)
|
allocate(phase_Noutput(Nsections), source=0_pInt)
|
||||||
allocate(phase_localPlasticity(Nsections), source=.false.)
|
allocate(phase_localPlasticity(Nsections), source=.false.)
|
||||||
|
|
||||||
phase_Noutput = IO_countTagInPart(fileUnit,myPart,'(output)',Nsections)
|
phase_Noutput = IO_countTagInPart(fileUnit,myPart,'(output)',Nsections)
|
||||||
|
phase_Nsources = IO_countTagInPart(fileUnit,myPart,'(source)',Nsections)
|
||||||
|
phase_Nkinematics = IO_countTagInPart(fileUnit,myPart,'(kinematics)',Nsections)
|
||||||
|
phase_NstiffnessDegradations = IO_countTagInPart(fileUnit,myPart,'(stiffness_degradation)',Nsections)
|
||||||
phase_localPlasticity = .not. IO_spotTagInPart(fileUnit,myPart,'/nonlocal/',Nsections)
|
phase_localPlasticity = .not. IO_spotTagInPart(fileUnit,myPart,'/nonlocal/',Nsections)
|
||||||
|
|
||||||
|
allocate(phase_source(maxval(phase_Nsources),Nsections), source=SOURCE_undefined_ID)
|
||||||
|
allocate(phase_kinematics(maxval(phase_Nkinematics),Nsections), source=KINEMATICS_undefined_ID)
|
||||||
|
allocate(phase_stiffnessDegradation(maxval(phase_NstiffnessDegradations),Nsections), &
|
||||||
|
source=STIFFNESS_DEGRADATION_undefined_ID)
|
||||||
|
|
||||||
rewind(fileUnit)
|
rewind(fileUnit)
|
||||||
line = '' ! to have it initialized
|
line = '' ! to have it initialized
|
||||||
section = 0_pInt ! - " -
|
section = 0_pInt ! - " -
|
||||||
|
@ -821,6 +926,9 @@ subroutine material_parsePhase(fileUnit,myPart)
|
||||||
if (echo) write(6,'(2x,a)') trim(line) ! echo back read lines
|
if (echo) write(6,'(2x,a)') trim(line) ! echo back read lines
|
||||||
if (IO_getTag(line,'[',']') /= '') then ! next section
|
if (IO_getTag(line,'[',']') /= '') then ! next section
|
||||||
section = section + 1_pInt
|
section = section + 1_pInt
|
||||||
|
sourceCtr = 0_pInt
|
||||||
|
kinematicsCtr = 0_pInt
|
||||||
|
stiffDegradationCtr = 0_pInt
|
||||||
phase_name(section) = IO_getTag(line,'[',']')
|
phase_name(section) = IO_getTag(line,'[',']')
|
||||||
endif
|
endif
|
||||||
if (section > 0_pInt) then
|
if (section > 0_pInt) then
|
||||||
|
@ -855,42 +963,47 @@ subroutine material_parsePhase(fileUnit,myPart)
|
||||||
case default
|
case default
|
||||||
call IO_error(201_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
call IO_error(201_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||||
end select
|
end select
|
||||||
case ('damage')
|
case ('(source)')
|
||||||
|
sourceCtr = sourceCtr + 1_pInt
|
||||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
case (LOCAL_DAMAGE_none_label)
|
case (SOURCE_thermal_dissipation_label)
|
||||||
phase_damage(section) = LOCAL_DAMAGE_none_ID
|
phase_source(sourceCtr,section) = SOURCE_thermal_dissipation_ID
|
||||||
case (LOCAL_DAMAGE_isoBrittle_label)
|
case (SOURCE_damage_isoBrittle_label)
|
||||||
phase_damage(section) = LOCAL_DAMAGE_isoBrittle_ID
|
phase_source(sourceCtr,section) = SOURCE_damage_isoBrittle_ID
|
||||||
case (LOCAL_DAMAGE_isoDuctile_label)
|
case (SOURCE_damage_isoDuctile_label)
|
||||||
phase_damage(section) = LOCAL_DAMAGE_isoDuctile_ID
|
phase_source(sourceCtr,section) = SOURCE_damage_isoDuctile_ID
|
||||||
case (LOCAL_DAMAGE_anisoBrittle_label)
|
case (SOURCE_damage_anisoBrittle_label)
|
||||||
phase_damage(section) = LOCAL_DAMAGE_anisoBrittle_ID
|
phase_source(sourceCtr,section) = SOURCE_damage_anisoBrittle_ID
|
||||||
case (LOCAL_DAMAGE_anisoDuctile_label)
|
case (SOURCE_damage_anisoDuctile_label)
|
||||||
phase_damage(section) = LOCAL_DAMAGE_anisoDuctile_ID
|
phase_source(sourceCtr,section) = SOURCE_damage_anisoDuctile_ID
|
||||||
case (LOCAL_DAMAGE_gurson_label)
|
case (SOURCE_vacancy_phenoplasticity_label)
|
||||||
phase_damage(section) = LOCAL_DAMAGE_gurson_ID
|
phase_source(sourceCtr,section) = SOURCE_vacancy_phenoplasticity_ID
|
||||||
case (LOCAL_DAMAGE_phaseField_label)
|
case (SOURCE_vacancy_irradiation_label)
|
||||||
phase_damage(section) = LOCAL_DAMAGE_phaseField_ID
|
phase_source(sourceCtr,section) = SOURCE_vacancy_irradiation_ID
|
||||||
case default
|
case (SOURCE_vacancy_thermalfluc_label)
|
||||||
call IO_error(200_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
phase_source(sourceCtr,section) = SOURCE_vacancy_thermalfluc_ID
|
||||||
end select
|
end select
|
||||||
case ('thermal')
|
case ('(kinematics)')
|
||||||
|
kinematicsCtr = kinematicsCtr + 1_pInt
|
||||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
case (LOCAL_THERMAL_ISOTHERMAL_label)
|
case (KINEMATICS_cleavage_opening_label)
|
||||||
phase_thermal(section) = LOCAL_THERMAL_isothermal_ID
|
phase_kinematics(kinematicsCtr,section) = KINEMATICS_cleavage_opening_ID
|
||||||
case (LOCAL_THERMAL_ADIABATIC_label)
|
case (KINEMATICS_slipplane_opening_label)
|
||||||
phase_thermal(section) = LOCAL_THERMAL_adiabatic_ID
|
phase_kinematics(kinematicsCtr,section) = KINEMATICS_slipplane_opening_ID
|
||||||
case default
|
case (KINEMATICS_thermal_expansion_label)
|
||||||
call IO_error(200_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
phase_kinematics(kinematicsCtr,section) = KINEMATICS_thermal_expansion_ID
|
||||||
|
case (KINEMATICS_vacancy_strain_label)
|
||||||
|
phase_kinematics(kinematicsCtr,section) = KINEMATICS_vacancy_strain_ID
|
||||||
|
case (KINEMATICS_hydrogen_strain_label)
|
||||||
|
phase_kinematics(kinematicsCtr,section) = KINEMATICS_hydrogen_strain_ID
|
||||||
end select
|
end select
|
||||||
case ('vacancy')
|
case ('(stiffness_degradation)')
|
||||||
|
stiffDegradationCtr = stiffDegradationCtr + 1_pInt
|
||||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
case (LOCAL_VACANCY_CONSTANT_label)
|
case (STIFFNESS_DEGRADATION_damage_label)
|
||||||
phase_vacancy(section) = LOCAL_VACANCY_constant_ID
|
phase_stiffnessDegradation(stiffDegradationCtr,section) = STIFFNESS_DEGRADATION_damage_ID
|
||||||
case (LOCAL_VACANCY_GENERATION_label)
|
case (STIFFNESS_DEGRADATION_porosity_label)
|
||||||
phase_vacancy(section) = LOCAL_VACANCY_generation_ID
|
phase_stiffnessDegradation(stiffDegradationCtr,section) = STIFFNESS_DEGRADATION_porosity_ID
|
||||||
case default
|
|
||||||
call IO_error(200_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
|
||||||
end select
|
end select
|
||||||
|
|
||||||
end select
|
end select
|
||||||
|
@ -898,14 +1011,10 @@ subroutine material_parsePhase(fileUnit,myPart)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
do p=1_pInt, Nsections
|
do p=1_pInt, Nsections
|
||||||
phase_elasticityInstance(p) = count(phase_elasticity(1:p) == phase_elasticity(p))
|
phase_elasticityInstance(p) = count(phase_elasticity(1:p) == phase_elasticity(p))
|
||||||
phase_plasticityInstance(p) = count(phase_plasticity(1:p) == phase_plasticity(p))
|
phase_plasticityInstance(p) = count(phase_plasticity(1:p) == phase_plasticity(p))
|
||||||
phase_damageInstance(p) = count(phase_damage(1:p) == phase_damage(p))
|
|
||||||
phase_thermalInstance(p) = count(phase_thermal(1:p) == phase_thermal(p))
|
|
||||||
phase_vacancyInstance(p) = count(phase_vacancy(1:p) == phase_vacancy(p))
|
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
|
|
||||||
end subroutine material_parsePhase
|
end subroutine material_parsePhase
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -70,6 +70,31 @@ module numerics
|
||||||
usePingPong = .true., &
|
usePingPong = .true., &
|
||||||
numerics_timeSyncing = .false. !< flag indicating if time synchronization in crystallite is used for nonlocal plasticity
|
numerics_timeSyncing = .false. !< flag indicating if time synchronization in crystallite is used for nonlocal plasticity
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! field parameters:
|
||||||
|
real(pReal), protected, public :: &
|
||||||
|
err_struct_tolAbs = 1.0e-10_pReal, & !< absolute tolerance for mechanical equilibrium
|
||||||
|
err_struct_tolRel = 1.0e-4_pReal, & !< relative tolerance for mechanical equilibrium
|
||||||
|
err_thermal_tolAbs = 1.0e-2_pReal, & !< absolute tolerance for thermal equilibrium
|
||||||
|
err_thermal_tolRel = 1.0e-6_pReal, & !< relative tolerance for thermal equilibrium
|
||||||
|
err_damage_tolAbs = 1.0e-2_pReal, & !< absolute tolerance for damage evolution
|
||||||
|
err_damage_tolRel = 1.0e-6_pReal, & !< relative tolerance for damage evolution
|
||||||
|
err_vacancyflux_tolAbs = 1.0e-8_pReal, & !< absolute tolerance for vacancy transport
|
||||||
|
err_vacancyflux_tolRel = 1.0e-6_pReal, & !< relative tolerance for vacancy transport
|
||||||
|
err_porosity_tolAbs = 1.0e-2_pReal, & !< absolute tolerance for porosity evolution
|
||||||
|
err_porosity_tolRel = 1.0e-6_pReal, & !< relative tolerance for porosity evolution
|
||||||
|
err_hydrogenflux_tolAbs = 1.0e-8_pReal, & !< absolute tolerance for hydrogen transport
|
||||||
|
err_hydrogenflux_tolRel = 1.0e-6_pReal, & !< relative tolerance for hydrogen transport
|
||||||
|
vacancyBoundPenalty = 1.0e+4_pReal, & !< penalty to enforce 0 < Cv < 1
|
||||||
|
hydrogenBoundPenalty = 1.0e+4_pReal !< penalty to enforce 0 < Ch < 1
|
||||||
|
integer(pInt), protected, public :: &
|
||||||
|
itmax = 250_pInt, & !< maximum number of iterations
|
||||||
|
itmin = 1_pInt, & !< minimum number of iterations
|
||||||
|
stagItMax = 10_pInt, & !< max number of field level staggered iterations
|
||||||
|
maxCutBack = 3_pInt, & !< max number of cut backs
|
||||||
|
vacancyPolyOrder = 10_pInt, & !< order of polynomial approximation of entropic contribution to vacancy chemical potential
|
||||||
|
hydrogenPolyOrder = 10_pInt !< order of polynomial approximation of entropic contribution to hydrogen chemical potential
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! spectral parameters:
|
! spectral parameters:
|
||||||
#ifdef Spectral
|
#ifdef Spectral
|
||||||
|
@ -94,9 +119,6 @@ module numerics
|
||||||
&-snes_ngmres_anderson '
|
&-snes_ngmres_anderson '
|
||||||
integer(pInt), protected, public :: &
|
integer(pInt), protected, public :: &
|
||||||
fftw_planner_flag = 32_pInt, & !< conversion of fftw_plan_mode to integer, basically what is usually done in the include file of fftw
|
fftw_planner_flag = 32_pInt, & !< conversion of fftw_plan_mode to integer, basically what is usually done in the include file of fftw
|
||||||
itmax = 250_pInt, & !< maximum number of iterations
|
|
||||||
itmin = 2_pInt, & !< minimum number of iterations
|
|
||||||
maxCutBack = 3_pInt, & !< max number of cut backs
|
|
||||||
continueCalculation = 0_pInt, & !< 0: exit if BVP solver does not converge, 1: continue calculation if BVP solver does not converge
|
continueCalculation = 0_pInt, & !< 0: exit if BVP solver does not converge, 1: continue calculation if BVP solver does not converge
|
||||||
divergence_correction = 2_pInt !< correct divergence calculation in fourier space 0: no correction, 1: size scaled to 1, 2: size scaled to Npoints
|
divergence_correction = 2_pInt !< correct divergence calculation in fourier space 0: no correction, 1: size scaled to 1, 2: size scaled to Npoints
|
||||||
logical, protected, public :: &
|
logical, protected, public :: &
|
||||||
|
@ -107,13 +129,16 @@ module numerics
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! FEM parameters:
|
! FEM parameters:
|
||||||
#ifdef FEM
|
#ifdef FEM
|
||||||
real(pReal), protected, public :: &
|
integer(pInt), protected, public :: &
|
||||||
err_struct_tolAbs = 1.0e-10_pReal, & !< absolute tolerance for equilibrium
|
integrationOrder = 2_pInt, & !< order of quadrature rule required
|
||||||
err_struct_tolRel = 1.0e-4_pReal, & !< relative tolerance for equilibrium
|
structOrder = 2_pInt, & !< order of displacement shape functions
|
||||||
err_thermal_tol = 1.0e-1_pReal, &
|
thermalOrder = 2_pInt, & !< order of temperature field shape functions
|
||||||
err_damage_tol = 1.0e-2_pReal, &
|
damageOrder = 2_pInt, & !< order of damage field shape functions
|
||||||
err_vacancydiffusion_tol = 1.0e-8_pReal, &
|
vacancyfluxOrder = 2_pInt, & !< order of vacancy concentration and chemical potential field shape functions
|
||||||
vacancyBoundPenalty = 1.0e+4_pReal !< penalty to enforce 0 < Cv < 1
|
porosityOrder = 2_pInt, & !< order of porosity field shape functions
|
||||||
|
hydrogenfluxOrder = 2_pInt !< order of hydrogen concentration and chemical potential field shape functions
|
||||||
|
logical, protected, public :: &
|
||||||
|
BBarStabilisation = .false.
|
||||||
character(len=4096), protected, public :: &
|
character(len=4096), protected, public :: &
|
||||||
petsc_optionsFEM = '-mech_snes_type newtonls &
|
petsc_optionsFEM = '-mech_snes_type newtonls &
|
||||||
&-mech_snes_linesearch_type cp &
|
&-mech_snes_linesearch_type cp &
|
||||||
|
@ -123,50 +148,43 @@ module numerics
|
||||||
&-mech_ksp_type fgmres &
|
&-mech_ksp_type fgmres &
|
||||||
&-mech_ksp_max_it 25 &
|
&-mech_ksp_max_it 25 &
|
||||||
&-mech_pc_type ml &
|
&-mech_pc_type ml &
|
||||||
&-mech_pc_ml_maxNlevels 2 &
|
|
||||||
&-mech_mg_coarse_ksp_type preonly &
|
|
||||||
&-mech_mg_coarse_pc_type lu &
|
|
||||||
&-mech_mg_coarse_pc_factor_mat_solver_package superlu_dist &
|
|
||||||
&-mech_mg_levels_ksp_type chebyshev &
|
&-mech_mg_levels_ksp_type chebyshev &
|
||||||
&-mech_mg_levels_ksp_chebyshev_estimate_eigenvalues 0,0.1,0,1.1 &
|
|
||||||
&-mech_mg_levels_pc_type sor &
|
&-mech_mg_levels_pc_type sor &
|
||||||
&-mech_pc_ml_nullspace user &
|
&-mech_pc_ml_nullspace user &
|
||||||
&-damage_snes_type newtonls &
|
&-damage_snes_type newtonls &
|
||||||
&-damage_snes_linesearch_type cp &
|
&-damage_snes_linesearch_type cp &
|
||||||
&-damage_ksp_type fgmres &
|
&-damage_ksp_type fgmres &
|
||||||
|
&-damage_ksp_max_it 25 &
|
||||||
&-damage_snes_atol 1e-8 &
|
&-damage_snes_atol 1e-8 &
|
||||||
&-damage_pc_type ml &
|
&-damage_pc_type hypre &
|
||||||
&-damage_mg_levels_ksp_type chebyshev &
|
|
||||||
&-damage_mg_levels_ksp_chebyshev_estimate_eigenvalues 0,0.1,0,1.1 &
|
|
||||||
&-damage_mg_levels_pc_type sor &
|
|
||||||
&-thermal_snes_type newtonls &
|
&-thermal_snes_type newtonls &
|
||||||
&-thermal_snes_linesearch_type cp &
|
&-thermal_snes_linesearch_type cp &
|
||||||
&-thermal_ksp_type fgmres &
|
&-thermal_ksp_type fgmres &
|
||||||
|
&-thermal_ksp_max_it 25 &
|
||||||
&-thermal_snes_atol 1e-1 &
|
&-thermal_snes_atol 1e-1 &
|
||||||
&-thermal_pc_type ml &
|
&-thermal_pc_type hypre &
|
||||||
&-thermal_mg_levels_ksp_type chebyshev &
|
|
||||||
&-thermal_mg_levels_ksp_chebyshev_estimate_eigenvalues 0,0.1,0,1.1 &
|
|
||||||
&-thermal_mg_levels_pc_type sor &
|
|
||||||
&-vacancy_snes_type newtonls &
|
&-vacancy_snes_type newtonls &
|
||||||
&-vacancy_snes_linesearch_type cp &
|
&-vacancy_snes_linesearch_type cp &
|
||||||
&-vacancy_ksp_type fgmres &
|
|
||||||
&-vacancy_snes_atol 1e-9 &
|
&-vacancy_snes_atol 1e-9 &
|
||||||
|
&-vacancy_ksp_type fgmres &
|
||||||
|
&-vacancy_ksp_max_it 25 &
|
||||||
&-vacancy_pc_type ml &
|
&-vacancy_pc_type ml &
|
||||||
&-vacancy_mg_levels_ksp_type chebyshev &
|
&-vacancy_mg_levels_ksp_type chebyshev &
|
||||||
&-vacancy_mg_levels_ksp_chebyshev_estimate_eigenvalues 0,0.1,0,1.1 &
|
&-vacancy_mg_levels_pc_type sor &
|
||||||
&-vacancy_mg_levels_pc_type sor '
|
&-porosity_snes_type newtonls &
|
||||||
integer(pInt), protected, public :: &
|
&-porosity_snes_linesearch_type cp &
|
||||||
itmaxFEM = 25_pInt, & !< maximum number of iterations
|
&-porosity_ksp_type fgmres &
|
||||||
itminFEM = 1_pInt, & !< minimum number of iterations
|
&-porosity_ksp_max_it 25 &
|
||||||
stagItMax = 10_pInt, & !< max number of field level staggered iterations
|
&-porosity_snes_atol 1e-8 &
|
||||||
maxCutBackFEM = 3_pInt, & !< max number of cut backs
|
&-porosity_pc_type hypre &
|
||||||
integrationOrder = 2_pInt, &
|
&-hydrogen_snes_type newtonls &
|
||||||
structOrder = 2_pInt, &
|
&-hydrogen_snes_linesearch_type cp &
|
||||||
thermalOrder = 2_pInt, &
|
&-hydrogen_snes_atol 1e-9 &
|
||||||
damageOrder = 2_pInt, &
|
&-hydrogen_ksp_type fgmres &
|
||||||
vacancyDiffusionOrder = 2_pInt
|
&-hydrogen_ksp_max_it 25 &
|
||||||
logical, protected, public :: &
|
&-hydrogen_pc_type ml &
|
||||||
BBarStabilisation = .false.
|
&-hydrogen_mg_levels_ksp_type chebyshev &
|
||||||
|
&-hydrogen_mg_levels_pc_type sor '
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public :: numerics_init
|
public :: numerics_init
|
||||||
|
@ -350,6 +368,49 @@ subroutine numerics_init
|
||||||
case ('residualstiffness')
|
case ('residualstiffness')
|
||||||
residualStiffness = IO_floatValue(line,positions,2_pInt)
|
residualStiffness = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! field parameters
|
||||||
|
case ('err_struct_tolabs')
|
||||||
|
err_struct_tolAbs = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_struct_tolrel')
|
||||||
|
err_struct_tolRel = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_thermal_tolabs')
|
||||||
|
err_thermal_tolabs = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_thermal_tolrel')
|
||||||
|
err_thermal_tolrel = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_damage_tolabs')
|
||||||
|
err_damage_tolabs = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_damage_tolrel')
|
||||||
|
err_damage_tolrel = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_vacancyflux_tolabs')
|
||||||
|
err_vacancyflux_tolabs = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_vacancyflux_tolrel')
|
||||||
|
err_vacancyflux_tolrel = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_porosity_tolabs')
|
||||||
|
err_porosity_tolabs = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_porosity_tolrel')
|
||||||
|
err_porosity_tolrel = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_hydrogenflux_tolabs')
|
||||||
|
err_hydrogenflux_tolabs = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('err_hydrogenflux_tolrel')
|
||||||
|
err_hydrogenflux_tolrel = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('vacancyboundpenalty')
|
||||||
|
vacancyBoundPenalty = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('hydrogenboundpenalty')
|
||||||
|
hydrogenBoundPenalty = IO_floatValue(line,positions,2_pInt)
|
||||||
|
case ('itmax')
|
||||||
|
itmax = IO_intValue(line,positions,2_pInt)
|
||||||
|
case ('itmin')
|
||||||
|
itmin = IO_intValue(line,positions,2_pInt)
|
||||||
|
case ('maxcutback')
|
||||||
|
maxCutBack = IO_intValue(line,positions,2_pInt)
|
||||||
|
case ('maxstaggerediter')
|
||||||
|
stagItMax = IO_intValue(line,positions,2_pInt)
|
||||||
|
case ('vacancypolyorder')
|
||||||
|
vacancyPolyOrder = IO_intValue(line,positions,2_pInt)
|
||||||
|
case ('hydrogenpolyorder')
|
||||||
|
hydrogenPolyOrder = IO_intValue(line,positions,2_pInt)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! spectral parameters
|
! spectral parameters
|
||||||
#ifdef Spectral
|
#ifdef Spectral
|
||||||
|
@ -361,12 +422,6 @@ subroutine numerics_init
|
||||||
err_stress_tolrel = IO_floatValue(line,positions,2_pInt)
|
err_stress_tolrel = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('err_stress_tolabs')
|
case ('err_stress_tolabs')
|
||||||
err_stress_tolabs = IO_floatValue(line,positions,2_pInt)
|
err_stress_tolabs = IO_floatValue(line,positions,2_pInt)
|
||||||
case ('itmax')
|
|
||||||
itmax = IO_intValue(line,positions,2_pInt)
|
|
||||||
case ('itmin')
|
|
||||||
itmin = IO_intValue(line,positions,2_pInt)
|
|
||||||
case ('maxcutback')
|
|
||||||
maxCutBack = IO_intValue(line,positions,2_pInt)
|
|
||||||
case ('continuecalculation')
|
case ('continuecalculation')
|
||||||
continueCalculation = IO_intValue(line,positions,2_pInt)
|
continueCalculation = IO_intValue(line,positions,2_pInt)
|
||||||
case ('memory_efficient')
|
case ('memory_efficient')
|
||||||
|
@ -395,36 +450,16 @@ subroutine numerics_init
|
||||||
polarBeta = IO_floatValue(line,positions,2_pInt)
|
polarBeta = IO_floatValue(line,positions,2_pInt)
|
||||||
#else
|
#else
|
||||||
case ('err_div_tolabs','err_div_tolrel','err_stress_tolrel','err_stress_tolabs',& ! found spectral parameter for FEM build
|
case ('err_div_tolabs','err_div_tolrel','err_stress_tolrel','err_stress_tolabs',& ! found spectral parameter for FEM build
|
||||||
'itmax', 'itmin','memory_efficient','fftw_timelimit','fftw_plan_mode', &
|
'memory_efficient','fftw_timelimit','fftw_plan_mode', &
|
||||||
'divergence_correction','update_gamma','spectralfilter','myfilter', &
|
'divergence_correction','update_gamma','spectralfilter','myfilter', &
|
||||||
'err_curl_tolabs','err_curl_tolrel', &
|
'err_curl_tolabs','err_curl_tolrel', &
|
||||||
'maxcutback','polaralpha','polarbeta')
|
'polaralpha','polarbeta')
|
||||||
call IO_warning(40_pInt,ext_msg=tag)
|
call IO_warning(40_pInt,ext_msg=tag)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! FEM parameters
|
! FEM parameters
|
||||||
#ifdef FEM
|
#ifdef FEM
|
||||||
case ('err_struct_tolabs')
|
|
||||||
err_struct_tolAbs = IO_floatValue(line,positions,2_pInt)
|
|
||||||
case ('err_struct_tolrel')
|
|
||||||
err_struct_tolRel = IO_floatValue(line,positions,2_pInt)
|
|
||||||
case ('err_thermal_tol')
|
|
||||||
err_thermal_tol = IO_floatValue(line,positions,2_pInt)
|
|
||||||
case ('err_damage_tol')
|
|
||||||
err_damage_tol = IO_floatValue(line,positions,2_pInt)
|
|
||||||
case ('err_vacancydiffusion_tol')
|
|
||||||
err_vacancyDiffusion_tol = IO_floatValue(line,positions,2_pInt)
|
|
||||||
case ('vacancyboundpenalty')
|
|
||||||
vacancyBoundPenalty = IO_floatValue(line,positions,2_pInt)
|
|
||||||
case ('itmaxfem')
|
|
||||||
itmaxFEM = IO_intValue(line,positions,2_pInt)
|
|
||||||
case ('itminfem')
|
|
||||||
itminFEM = IO_intValue(line,positions,2_pInt)
|
|
||||||
case ('maxcutbackfem')
|
|
||||||
maxCutBackFEM = IO_intValue(line,positions,2_pInt)
|
|
||||||
case ('maxstaggerediter')
|
|
||||||
stagItMax = IO_intValue(line,positions,2_pInt)
|
|
||||||
case ('integrationorder')
|
case ('integrationorder')
|
||||||
integrationorder = IO_intValue(line,positions,2_pInt)
|
integrationorder = IO_intValue(line,positions,2_pInt)
|
||||||
case ('structorder')
|
case ('structorder')
|
||||||
|
@ -433,16 +468,19 @@ subroutine numerics_init
|
||||||
thermalorder = IO_intValue(line,positions,2_pInt)
|
thermalorder = IO_intValue(line,positions,2_pInt)
|
||||||
case ('damageorder')
|
case ('damageorder')
|
||||||
damageorder = IO_intValue(line,positions,2_pInt)
|
damageorder = IO_intValue(line,positions,2_pInt)
|
||||||
case ('vacancydiffusionorder')
|
case ('vacancyfluxorder')
|
||||||
vacancyDiffusionOrder = IO_intValue(line,positions,2_pInt)
|
vacancyfluxOrder = IO_intValue(line,positions,2_pInt)
|
||||||
|
case ('porosityorder')
|
||||||
|
porosityOrder = IO_intValue(line,positions,2_pInt)
|
||||||
|
case ('hydrogenfluxorder')
|
||||||
|
hydrogenfluxOrder = IO_intValue(line,positions,2_pInt)
|
||||||
case ('petsc_optionsfem')
|
case ('petsc_optionsfem')
|
||||||
petsc_optionsFEM = trim(line(positions(4):))
|
petsc_optionsFEM = trim(line(positions(4):))
|
||||||
case ('bbarstabilisation')
|
case ('bbarstabilisation')
|
||||||
BBarStabilisation = IO_intValue(line,positions,2_pInt) > 0_pInt
|
BBarStabilisation = IO_intValue(line,positions,2_pInt) > 0_pInt
|
||||||
#else
|
#else
|
||||||
case ('err_struct_tolabs','err_struct_tolrel','err_thermal_tol','err_damage_tol','err_vacancydiffusion_tol',& ! found FEM parameter for spectral/Abaqus/Marc build
|
case ('integrationorder','structorder','thermalorder', 'damageorder','vacancyfluxorder', &
|
||||||
'vacancyboundpenalty','itmaxfem', 'itminfem','maxcutbackfem','maxstaggerediter','integrationorder',&
|
'porosityorder','hydrogenfluxorder','petsc_optionsfem','bbarstabilisation')
|
||||||
'structorder','thermalorder', 'damageorder','petsc_optionsfem','bbarstabilisation')
|
|
||||||
call IO_warning(40_pInt,ext_msg=tag)
|
call IO_warning(40_pInt,ext_msg=tag)
|
||||||
#endif
|
#endif
|
||||||
case default ! found unknown keyword
|
case default ! found unknown keyword
|
||||||
|
@ -541,11 +579,31 @@ subroutine numerics_init
|
||||||
!$ write(6,'(a24,1x,i8,/)') ' number of threads: ',DAMASK_NumThreadsInt
|
!$ write(6,'(a24,1x,i8,/)') ' number of threads: ',DAMASK_NumThreadsInt
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! spectral parameters
|
! field parameters
|
||||||
#ifdef Spectral
|
|
||||||
write(6,'(a24,1x,i8)') ' itmax: ',itmax
|
write(6,'(a24,1x,i8)') ' itmax: ',itmax
|
||||||
write(6,'(a24,1x,i8)') ' itmin: ',itmin
|
write(6,'(a24,1x,i8)') ' itmin: ',itmin
|
||||||
write(6,'(a24,1x,i8)') ' maxCutBack: ',maxCutBack
|
write(6,'(a24,1x,i8)') ' maxCutBack: ',maxCutBack
|
||||||
|
write(6,'(a24,1x,i8)') ' maxStaggeredIter: ',stagItMax
|
||||||
|
write(6,'(a24,1x,i8)') ' vacancyPolyOrder: ',vacancyPolyOrder
|
||||||
|
write(6,'(a24,1x,i8)') ' hydrogenPolyOrder: ',hydrogenPolyOrder
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_struct_tolAbs: ',err_struct_tolAbs
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_struct_tolRel: ',err_struct_tolRel
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_thermal_tolabs: ',err_thermal_tolabs
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_thermal_tolrel: ',err_thermal_tolrel
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_damage_tolabs: ',err_damage_tolabs
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_damage_tolrel: ',err_damage_tolrel
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_vacancyflux_tolabs: ',err_vacancyflux_tolabs
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_vacancyflux_tolrel: ',err_vacancyflux_tolrel
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_porosity_tolabs: ',err_porosity_tolabs
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_porosity_tolrel: ',err_porosity_tolrel
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_hydrogenflux_tolabs:',err_hydrogenflux_tolabs
|
||||||
|
write(6,'(a24,1x,es8.1)') ' err_hydrogenflux_tolrel:',err_hydrogenflux_tolrel
|
||||||
|
write(6,'(a24,1x,es8.1)') ' vacancyBoundPenalty: ',vacancyBoundPenalty
|
||||||
|
write(6,'(a24,1x,es8.1)') ' hydrogenBoundPenalty: ',hydrogenBoundPenalty
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! spectral parameters
|
||||||
|
#ifdef Spectral
|
||||||
write(6,'(a24,1x,i8)') ' continueCalculation: ',continueCalculation
|
write(6,'(a24,1x,i8)') ' continueCalculation: ',continueCalculation
|
||||||
write(6,'(a24,1x,L8)') ' memory_efficient: ',memory_efficient
|
write(6,'(a24,1x,L8)') ' memory_efficient: ',memory_efficient
|
||||||
write(6,'(a24,1x,i8)') ' divergence_correction: ',divergence_correction
|
write(6,'(a24,1x,i8)') ' divergence_correction: ',divergence_correction
|
||||||
|
@ -573,21 +631,13 @@ subroutine numerics_init
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! spectral parameters
|
! spectral parameters
|
||||||
#ifdef FEM
|
#ifdef FEM
|
||||||
write(6,'(a24,1x,i8)') ' itmaxFEM: ',itmaxFEM
|
|
||||||
write(6,'(a24,1x,i8)') ' itminFEM: ',itminFEM
|
|
||||||
write(6,'(a24,1x,i8)') ' maxCutBackFEM: ',maxCutBackFEM
|
|
||||||
write(6,'(a24,1x,i8)') ' maxStaggeredIter: ',stagItMax
|
|
||||||
write(6,'(a24,1x,i8)') ' integrationOrder: ',integrationOrder
|
write(6,'(a24,1x,i8)') ' integrationOrder: ',integrationOrder
|
||||||
write(6,'(a24,1x,i8)') ' structOrder: ',structOrder
|
write(6,'(a24,1x,i8)') ' structOrder: ',structOrder
|
||||||
write(6,'(a24,1x,i8)') ' thermalOrder: ',thermalOrder
|
write(6,'(a24,1x,i8)') ' thermalOrder: ',thermalOrder
|
||||||
write(6,'(a24,1x,i8)') ' damageOrder: ',damageOrder
|
write(6,'(a24,1x,i8)') ' damageOrder: ',damageOrder
|
||||||
write(6,'(a24,1x,i8)') ' vacancyDiffusionOrder: ',vacancyDiffusionOrder
|
write(6,'(a24,1x,i8)') ' vacancyfluxOrder: ',vacancyfluxOrder
|
||||||
write(6,'(a24,1x,es8.1)') ' err_struct_tolAbs: ',err_struct_tolAbs
|
write(6,'(a24,1x,i8)') ' porosityOrder: ',porosityOrder
|
||||||
write(6,'(a24,1x,es8.1)') ' err_struct_tolRel: ',err_struct_tolRel
|
write(6,'(a24,1x,i8)') ' hydrogenfluxOrder: ',hydrogenfluxOrder
|
||||||
write(6,'(a24,1x,es8.1)') ' err_thermal_tol: ',err_thermal_tol
|
|
||||||
write(6,'(a24,1x,es8.1)') ' err_damage_tol: ',err_damage_tol
|
|
||||||
write(6,'(a24,1x,es8.1)') ' err_vacancyDiff_tol: ',err_vacancyDiffusion_tol
|
|
||||||
write(6,'(a24,1x,es8.1)') ' vacancyBoundPenalty: ',vacancyBoundPenalty
|
|
||||||
write(6,'(a24,1x,a)') ' PETSc_optionsFEM: ',trim(petsc_optionsFEM)
|
write(6,'(a24,1x,a)') ' PETSc_optionsFEM: ',trim(petsc_optionsFEM)
|
||||||
write(6,'(a24,1x,L8)') ' B-Bar stabilisation: ',BBarStabilisation
|
write(6,'(a24,1x,L8)') ' B-Bar stabilisation: ',BBarStabilisation
|
||||||
#endif
|
#endif
|
||||||
|
@ -634,14 +684,28 @@ subroutine numerics_init
|
||||||
if (volDiscrMod_RGC < 0.0_pReal) call IO_error(301_pInt,ext_msg='volDiscrMod_RGC')
|
if (volDiscrMod_RGC < 0.0_pReal) call IO_error(301_pInt,ext_msg='volDiscrMod_RGC')
|
||||||
if (volDiscrPow_RGC <= 0.0_pReal) call IO_error(301_pInt,ext_msg='volDiscrPw_RGC')
|
if (volDiscrPow_RGC <= 0.0_pReal) call IO_error(301_pInt,ext_msg='volDiscrPw_RGC')
|
||||||
if (residualStiffness <= 0.0_pReal) call IO_error(301_pInt,ext_msg='residualStiffness')
|
if (residualStiffness <= 0.0_pReal) call IO_error(301_pInt,ext_msg='residualStiffness')
|
||||||
#ifdef Spectral
|
|
||||||
if (itmax <= 1_pInt) call IO_error(301_pInt,ext_msg='itmax')
|
if (itmax <= 1_pInt) call IO_error(301_pInt,ext_msg='itmax')
|
||||||
if (itmin > itmax .or. itmin < 1_pInt) call IO_error(301_pInt,ext_msg='itmin')
|
if (itmin > itmax .or. itmin < 1_pInt) call IO_error(301_pInt,ext_msg='itmin')
|
||||||
|
if (maxCutBack < 0_pInt) call IO_error(301_pInt,ext_msg='maxCutBack')
|
||||||
|
if (stagItMax < 0_pInt) call IO_error(301_pInt,ext_msg='maxStaggeredIter')
|
||||||
|
if (vacancyPolyOrder < 0_pInt) call IO_error(301_pInt,ext_msg='vacancyPolyOrder')
|
||||||
|
if (err_struct_tolRel <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_struct_tolRel')
|
||||||
|
if (err_struct_tolAbs <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_struct_tolAbs')
|
||||||
|
if (err_thermal_tolabs <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_thermal_tolabs')
|
||||||
|
if (err_thermal_tolrel <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_thermal_tolrel')
|
||||||
|
if (err_damage_tolabs <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_damage_tolabs')
|
||||||
|
if (err_damage_tolrel <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_damage_tolrel')
|
||||||
|
if (err_vacancyflux_tolabs <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_vacancyflux_tolabs')
|
||||||
|
if (err_vacancyflux_tolrel <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_vacancyflux_tolrel')
|
||||||
|
if (err_porosity_tolabs <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_porosity_tolabs')
|
||||||
|
if (err_porosity_tolrel <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_porosity_tolrel')
|
||||||
|
if (err_hydrogenflux_tolabs <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_hydrogenflux_tolabs')
|
||||||
|
if (err_hydrogenflux_tolrel <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_hydrogenflux_tolrel')
|
||||||
|
#ifdef Spectral
|
||||||
if (continueCalculation /= 0_pInt .and. &
|
if (continueCalculation /= 0_pInt .and. &
|
||||||
continueCalculation /= 1_pInt) call IO_error(301_pInt,ext_msg='continueCalculation')
|
continueCalculation /= 1_pInt) call IO_error(301_pInt,ext_msg='continueCalculation')
|
||||||
if (divergence_correction < 0_pInt .or. &
|
if (divergence_correction < 0_pInt .or. &
|
||||||
divergence_correction > 2_pInt) call IO_error(301_pInt,ext_msg='divergence_correction')
|
divergence_correction > 2_pInt) call IO_error(301_pInt,ext_msg='divergence_correction')
|
||||||
if (maxCutBack < 0_pInt) call IO_error(301_pInt,ext_msg='maxCutBack')
|
|
||||||
if (update_gamma .and. &
|
if (update_gamma .and. &
|
||||||
.not. memory_efficient) call IO_error(error_ID = 847_pInt)
|
.not. memory_efficient) call IO_error(error_ID = 847_pInt)
|
||||||
if (err_stress_tolrel <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_stress_tolRel')
|
if (err_stress_tolrel <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_stress_tolRel')
|
||||||
|
@ -655,18 +719,6 @@ subroutine numerics_init
|
||||||
if (polarBeta < 0.0_pReal .or. &
|
if (polarBeta < 0.0_pReal .or. &
|
||||||
polarBeta > 2.0_pReal) call IO_error(301_pInt,ext_msg='polarBeta')
|
polarBeta > 2.0_pReal) call IO_error(301_pInt,ext_msg='polarBeta')
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEM
|
|
||||||
if (itmaxFEM <= 1_pInt) call IO_error(301_pInt,ext_msg='itmaxFEM')
|
|
||||||
if (itminFEM > itmaxFEM .or. &
|
|
||||||
itminFEM < 0_pInt) call IO_error(301_pInt,ext_msg='itminFEM')
|
|
||||||
if (maxCutBackFEM < 0_pInt) call IO_error(301_pInt,ext_msg='maxCutBackFEM')
|
|
||||||
if (stagItMax < 0_pInt) call IO_error(301_pInt,ext_msg='maxStaggeredIter')
|
|
||||||
if (err_struct_tolRel <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_struct_tolRel')
|
|
||||||
if (err_struct_tolAbs <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_struct_tolAbs')
|
|
||||||
if (err_thermal_tol <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_thermal_tol')
|
|
||||||
if (err_damage_tol <= 0.0_pReal) call IO_error(301_pInt,ext_msg='err_damage_tol')
|
|
||||||
if (err_vacancyDiffusion_tol <= 0.0_pReal)call IO_error(301_pInt,ext_msg='err_vacancydiffusion_tol')
|
|
||||||
#endif
|
|
||||||
|
|
||||||
end subroutine numerics_init
|
end subroutine numerics_init
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for constant porosity
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module porosity_none
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
porosity_none_init
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief allocates all neccessary fields, reads information from material configuration file
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine porosity_none_init()
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
use IO, only: &
|
||||||
|
IO_timeStamp
|
||||||
|
use material
|
||||||
|
use numerics, only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
NofMyHomog
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- porosity_'//POROSITY_none_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
initializeInstances: do homog = 1_pInt, material_Nhomogenization
|
||||||
|
|
||||||
|
myhomog: if (porosity_type(homog) == POROSITY_none_ID) then
|
||||||
|
NofMyHomog = count(material_homog == homog)
|
||||||
|
porosityState(homog)%sizeState = 0_pInt
|
||||||
|
porosityState(homog)%sizePostResults = 0_pInt
|
||||||
|
allocate(porosityState(homog)%state0 (0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(porosityState(homog)%subState0(0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(porosityState(homog)%state (0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
|
deallocate(porosity(homog)%p)
|
||||||
|
allocate (porosity(homog)%p(1), source=1.0_pReal)
|
||||||
|
|
||||||
|
endif myhomog
|
||||||
|
enddo initializeInstances
|
||||||
|
|
||||||
|
|
||||||
|
end subroutine porosity_none_init
|
||||||
|
|
||||||
|
end module porosity_none
|
|
@ -0,0 +1,488 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for phase field modelling of pore nucleation and growth
|
||||||
|
!> @details phase field model for pore nucleation and growth based on vacancy clustering
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module porosity_phasefield
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
porosity_phasefield_sizePostResults !< cumulative size of post results
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
porosity_phasefield_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
porosity_phasefield_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
porosity_phasefield_Noutput !< number of outputs per instance of this porosity
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
porosity_phasefield_specificFormationEnergy, &
|
||||||
|
porosity_phasefield_surfaceEnergy
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
porosity_ID
|
||||||
|
end enum
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
porosity_phasefield_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
porosity_phasefield_init, &
|
||||||
|
porosity_phasefield_getFormationEnergy, &
|
||||||
|
porosity_phasefield_getSurfaceEnergy, &
|
||||||
|
porosity_phasefield_getSourceAndItsTangent, &
|
||||||
|
porosity_phasefield_getDiffusion33, &
|
||||||
|
porosity_phasefield_getMobility, &
|
||||||
|
porosity_phasefield_putPorosity, &
|
||||||
|
porosity_phasefield_postResults
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine porosity_phasefield_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_vacancyVol
|
||||||
|
use material, only: &
|
||||||
|
porosity_type, &
|
||||||
|
porosity_typeInstance, &
|
||||||
|
homogenization_Noutput, &
|
||||||
|
POROSITY_phasefield_label, &
|
||||||
|
POROSITY_phasefield_ID, &
|
||||||
|
material_homog, &
|
||||||
|
material_Nphase, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
porosityState, &
|
||||||
|
porosityMapping, &
|
||||||
|
porosity, &
|
||||||
|
material_partHomogenization, &
|
||||||
|
material_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,section,instance,o
|
||||||
|
integer(pInt) :: sizeState
|
||||||
|
integer(pInt) :: NofMyHomog
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- porosity_'//POROSITY_phasefield_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(porosity_type == POROSITY_phasefield_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
allocate(porosity_phasefield_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(porosity_phasefield_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(porosity_phasefield_output (maxval(homogenization_Noutput),maxNinstance))
|
||||||
|
porosity_phasefield_output = ''
|
||||||
|
allocate(porosity_phasefield_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID)
|
||||||
|
allocate(porosity_phasefield_Noutput (maxNinstance), source=0_pInt)
|
||||||
|
allocate(porosity_phasefield_specificFormationEnergy(material_Nphase), source=0.0_pReal)
|
||||||
|
allocate(porosity_phasefield_surfaceEnergy (material_Nphase), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
section = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partHomogenization)! wind forward to <homogenization>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingHomog: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
|
section = section + 1_pInt ! advance homog section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (section > 0_pInt ) then; if (porosity_type(section) == POROSITY_phasefield_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = porosity_typeInstance(section) ! which instance of my porosity is present homog
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('porosity')
|
||||||
|
porosity_phasefield_Noutput(instance) = porosity_phasefield_Noutput(instance) + 1_pInt
|
||||||
|
porosity_phasefield_outputID(porosity_phasefield_Noutput(instance),instance) = porosity_ID
|
||||||
|
porosity_phasefield_output(porosity_phasefield_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingHomog
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
section = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partPhase) ! wind forward to <homogenization>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingPhase: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
|
section = section + 1_pInt ! advance homog section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (section > 0_pInt ) then; if (porosity_type(section) == POROSITY_phasefield_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('vacancyformationenergy')
|
||||||
|
porosity_phasefield_specificFormationEnergy(section) = IO_floatValue(line,positions,2_pInt)/&
|
||||||
|
lattice_vacancyVol(section)
|
||||||
|
|
||||||
|
case ('voidsurfaceenergy')
|
||||||
|
porosity_phasefield_surfaceEnergy(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingPhase
|
||||||
|
|
||||||
|
initializeInstances: do section = 1_pInt, size(porosity_type)
|
||||||
|
if (porosity_type(section) == POROSITY_phasefield_ID) then
|
||||||
|
NofMyHomog=count(material_homog==section)
|
||||||
|
instance = porosity_typeInstance(section)
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,porosity_phasefield_Noutput(instance)
|
||||||
|
select case(porosity_phasefield_outputID(o,instance))
|
||||||
|
case(porosity_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
porosity_phasefield_sizePostResult(o,instance) = mySize
|
||||||
|
porosity_phasefield_sizePostResults(instance) = porosity_phasefield_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
|
||||||
|
! allocate state arrays
|
||||||
|
sizeState = 0_pInt
|
||||||
|
porosityState(section)%sizeState = sizeState
|
||||||
|
porosityState(section)%sizePostResults = porosity_phasefield_sizePostResults(instance)
|
||||||
|
allocate(porosityState(section)%state0 (sizeState,NofMyHomog))
|
||||||
|
allocate(porosityState(section)%subState0(sizeState,NofMyHomog))
|
||||||
|
allocate(porosityState(section)%state (sizeState,NofMyHomog))
|
||||||
|
|
||||||
|
nullify(porosityMapping(section)%p)
|
||||||
|
porosityMapping(section)%p => mappingHomogenization(1,:,:)
|
||||||
|
deallocate(porosity(section)%p)
|
||||||
|
allocate(porosity(section)%p(NofMyHomog), source=1.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine porosity_phasefield_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized vacancy formation energy
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function porosity_phasefield_getFormationEnergy(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal) :: &
|
||||||
|
porosity_phasefield_getFormationEnergy
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain
|
||||||
|
|
||||||
|
porosity_phasefield_getFormationEnergy = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
porosity_phasefield_getFormationEnergy = porosity_phasefield_getFormationEnergy + &
|
||||||
|
porosity_phasefield_specificFormationEnergy(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
porosity_phasefield_getFormationEnergy = &
|
||||||
|
porosity_phasefield_getFormationEnergy/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function porosity_phasefield_getFormationEnergy
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized pore surface energy (normalized by characteristic length)
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function porosity_phasefield_getSurfaceEnergy(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal) :: &
|
||||||
|
porosity_phasefield_getSurfaceEnergy
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain
|
||||||
|
|
||||||
|
porosity_phasefield_getSurfaceEnergy = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
porosity_phasefield_getSurfaceEnergy = porosity_phasefield_getSurfaceEnergy + &
|
||||||
|
porosity_phasefield_surfaceEnergy(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
porosity_phasefield_getSurfaceEnergy = &
|
||||||
|
porosity_phasefield_getSurfaceEnergy/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function porosity_phasefield_getSurfaceEnergy
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates homogenized local driving force for pore nucleation and growth
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine porosity_phasefield_getSourceAndItsTangent(phiDot, dPhiDot_dPhi, phi, ip, el)
|
||||||
|
use math, only : &
|
||||||
|
math_mul33x33, &
|
||||||
|
math_mul66x6, &
|
||||||
|
math_Mandel33to6, &
|
||||||
|
math_transpose33, &
|
||||||
|
math_I3
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_homog, &
|
||||||
|
material_phase, &
|
||||||
|
phase_NstiffnessDegradations, &
|
||||||
|
phase_stiffnessDegradation, &
|
||||||
|
vacancyConc, &
|
||||||
|
vacancyfluxMapping, &
|
||||||
|
damage, &
|
||||||
|
damageMapping, &
|
||||||
|
STIFFNESS_DEGRADATION_damage_ID
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_Fe
|
||||||
|
use constitutive, only: &
|
||||||
|
constitutive_homogenizedC
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
grain, &
|
||||||
|
homog, &
|
||||||
|
mech
|
||||||
|
real(pReal) :: &
|
||||||
|
phiDot, dPhiDot_dPhi, Cv, W_e, strain(6), C(6,6)
|
||||||
|
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
Cv = vacancyConc(homog)%p(vacancyfluxMapping(homog)%p(ip,el))
|
||||||
|
|
||||||
|
W_e = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(homog)
|
||||||
|
phase = material_phase(grain,ip,el)
|
||||||
|
strain = math_Mandel33to6(math_mul33x33(math_transpose33(crystallite_Fe(1:3,1:3,grain,ip,el)), &
|
||||||
|
crystallite_Fe(1:3,1:3,grain,ip,el)) - math_I3)/2.0_pReal
|
||||||
|
C = constitutive_homogenizedC(grain,ip,el)
|
||||||
|
do mech = 1_pInt, phase_NstiffnessDegradations(phase)
|
||||||
|
select case(phase_stiffnessDegradation(mech,phase))
|
||||||
|
case (STIFFNESS_DEGRADATION_damage_ID)
|
||||||
|
C = damage(homog)%p(damageMapping(homog)%p(ip,el))* &
|
||||||
|
damage(homog)%p(damageMapping(homog)%p(ip,el))* &
|
||||||
|
C
|
||||||
|
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
W_e = W_e + sum(abs(strain*math_mul66x6(C,strain)))
|
||||||
|
enddo
|
||||||
|
W_e = W_e/homogenization_Ngrains(homog)
|
||||||
|
|
||||||
|
phiDot = 2.0_pReal*(1.0_pReal - phi)*(1.0_pReal - Cv)*(1.0_pReal - Cv) - &
|
||||||
|
2.0_pReal*phi*(W_e + Cv*porosity_phasefield_getFormationEnergy(ip,el))/ &
|
||||||
|
porosity_phasefield_getSurfaceEnergy (ip,el)
|
||||||
|
dPhiDot_dPhi = - 2.0_pReal*(1.0_pReal - Cv)*(1.0_pReal - Cv) &
|
||||||
|
- 2.0_pReal*(W_e + Cv*porosity_phasefield_getFormationEnergy(ip,el))/ &
|
||||||
|
porosity_phasefield_getSurfaceEnergy (ip,el)
|
||||||
|
|
||||||
|
end subroutine porosity_phasefield_getSourceAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized nonlocal diffusion tensor in reference configuration
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function porosity_phasefield_getDiffusion33(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_PorosityDiffusion33
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_phase, &
|
||||||
|
mappingHomogenization
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), dimension(3,3) :: &
|
||||||
|
porosity_phasefield_getDiffusion33
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
grain
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
porosity_phasefield_getDiffusion33 = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(homog)
|
||||||
|
porosity_phasefield_getDiffusion33 = porosity_phasefield_getDiffusion33 + &
|
||||||
|
crystallite_push33ToRef(grain,ip,el,lattice_PorosityDiffusion33(1:3,1:3,material_phase(grain,ip,el)))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
porosity_phasefield_getDiffusion33 = &
|
||||||
|
porosity_phasefield_getDiffusion33/ &
|
||||||
|
homogenization_Ngrains(homog)
|
||||||
|
|
||||||
|
end function porosity_phasefield_getDiffusion33
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief Returns homogenized phase field mobility
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
real(pReal) function porosity_phasefield_getMobility(ip,el)
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_PorosityMobility
|
||||||
|
use material, only: &
|
||||||
|
material_phase, &
|
||||||
|
homogenization_Ngrains
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
integer(pInt) :: &
|
||||||
|
ipc
|
||||||
|
|
||||||
|
porosity_phasefield_getMobility = 0.0_pReal
|
||||||
|
|
||||||
|
do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
porosity_phasefield_getMobility = porosity_phasefield_getMobility + lattice_PorosityMobility(material_phase(ipc,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
porosity_phasefield_getMobility = porosity_phasefield_getMobility/homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function porosity_phasefield_getMobility
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief updates porosity with solution from phasefield PDE
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine porosity_phasefield_putPorosity(phi,ip,el)
|
||||||
|
use material, only: &
|
||||||
|
material_homog, &
|
||||||
|
porosityMapping, &
|
||||||
|
porosity
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
offset
|
||||||
|
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
offset = porosityMapping(homog)%p(ip,el)
|
||||||
|
porosity(homog)%p(offset) = phi
|
||||||
|
|
||||||
|
end subroutine porosity_phasefield_putPorosity
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of porosity results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function porosity_phasefield_postResults(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
porosity_typeInstance, &
|
||||||
|
porosity
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(porosity_phasefield_sizePostResults(porosity_typeInstance(mappingHomogenization(2,ip,el)))) :: &
|
||||||
|
porosity_phasefield_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, homog, offset, o, c
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = mappingHomogenization(1,ip,el)
|
||||||
|
instance = porosity_typeInstance(homog)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
porosity_phasefield_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,porosity_phasefield_Noutput(instance)
|
||||||
|
select case(porosity_phasefield_outputID(o,instance))
|
||||||
|
|
||||||
|
case (porosity_ID)
|
||||||
|
porosity_phasefield_postResults(c+1_pInt) = porosity(homog)%p(offset)
|
||||||
|
c = c + 1
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function porosity_phasefield_postResults
|
||||||
|
|
||||||
|
end module porosity_phasefield
|
|
@ -58,11 +58,11 @@ use ifport
|
||||||
real(pReal), parameter, public :: tol_math_check = 1.0e-8_pReal !< tolerance for internal math self-checks (rotation)
|
real(pReal), parameter, public :: tol_math_check = 1.0e-8_pReal !< tolerance for internal math self-checks (rotation)
|
||||||
|
|
||||||
type, public :: p_vec !< variable length datatype used for storage of state
|
type, public :: p_vec !< variable length datatype used for storage of state
|
||||||
real(pReal), dimension(:), allocatable :: p
|
real(pReal), dimension(:), pointer :: p
|
||||||
end type p_vec
|
end type p_vec
|
||||||
|
|
||||||
type, public :: p_intvec
|
type, public :: p_intvec
|
||||||
integer(pInt), dimension(:), allocatable :: p
|
integer(pInt), dimension(:), pointer :: p
|
||||||
end type p_intvec
|
end type p_intvec
|
||||||
|
|
||||||
!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
|
||||||
|
@ -71,14 +71,11 @@ type, public :: p_intvec
|
||||||
sizeState = 0_pInt , & !< size of state
|
sizeState = 0_pInt , & !< size of state
|
||||||
sizeDotState = 0_pInt, & !< size of dot state, i.e. parts of the state that are integrated
|
sizeDotState = 0_pInt, & !< size of dot state, i.e. parts of the state that are integrated
|
||||||
sizePostResults = 0_pInt !< size of output data
|
sizePostResults = 0_pInt !< size of output data
|
||||||
logical :: &
|
|
||||||
nonlocal = .false. !< absolute tolerance for state integration
|
|
||||||
real(pReal), allocatable, dimension(:) :: &
|
real(pReal), allocatable, dimension(:) :: &
|
||||||
atolState
|
atolState
|
||||||
real(pReal), pointer, dimension(:,:), contiguous :: & ! a pointer is needed here because we might point to state/doState. However, they will never point to something, but are rather allocated and, hence, contiguous
|
real(pReal), pointer, dimension(:,:), contiguous :: & ! a pointer is needed here because we might point to state/doState. However, they will never point to something, but are rather allocated and, hence, contiguous
|
||||||
state, & !< state
|
state, & !< state
|
||||||
dotState !< state rate
|
dotState, & !< state rate
|
||||||
real(pReal), allocatable, dimension(:,:) :: &
|
|
||||||
state0, &
|
state0, &
|
||||||
partionedState0, &
|
partionedState0, &
|
||||||
subState0, &
|
subState0, &
|
||||||
|
@ -97,17 +94,23 @@ type, public :: p_intvec
|
||||||
nSlip = 0_pInt , &
|
nSlip = 0_pInt , &
|
||||||
nTwin = 0_pInt, &
|
nTwin = 0_pInt, &
|
||||||
nTrans = 0_pInt
|
nTrans = 0_pInt
|
||||||
|
logical :: &
|
||||||
|
nonlocal = .false. !< absolute tolerance for state integration
|
||||||
real(pReal), pointer, dimension(:,:), contiguous :: &
|
real(pReal), pointer, dimension(:,:), contiguous :: &
|
||||||
slipRate, & !< slip rate
|
slipRate, & !< slip rate
|
||||||
accumulatedSlip !< accumulated plastic slip
|
accumulatedSlip !< accumulated plastic slip
|
||||||
end type
|
end type
|
||||||
|
|
||||||
type, public :: tFieldData
|
type, public :: tSourceState
|
||||||
integer(pInt) :: &
|
type(tState), dimension(:), allocatable :: p !< tState for each active source mechanism in a phase
|
||||||
sizeField = 0_pInt , &
|
end type
|
||||||
sizePostResults = 0_pInt
|
|
||||||
real(pReal), allocatable, dimension(:,:) :: &
|
type, public :: tHomogMapping
|
||||||
field !< field data
|
integer(pInt), pointer, dimension(:,:) :: p
|
||||||
|
end type
|
||||||
|
|
||||||
|
type, public :: tPhaseMapping
|
||||||
|
integer(pInt), pointer, dimension(:,:,:) :: p
|
||||||
end type
|
end type
|
||||||
|
|
||||||
#ifdef FEM
|
#ifdef FEM
|
||||||
|
|
|
@ -0,0 +1,423 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Luv Sharma, Max-Planck-Institut fŸr Eisenforschung GmbH
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut fŸr Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine incorporating anisotropic brittle damage source mechanism
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module source_damage_anisoBrittle
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
source_damage_anisoBrittle_sizePostResults, & !< cumulative size of post results
|
||||||
|
source_damage_anisoBrittle_offset, & !< which source is my current source mechanism?
|
||||||
|
source_damage_anisoBrittle_instance !< instance of source mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_damage_anisoBrittle_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_damage_anisoBrittle_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
source_damage_anisoBrittle_Noutput !< number of outputs per instance of this source
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, private :: &
|
||||||
|
source_damage_anisoBrittle_totalNcleavage !< total number of cleavage systems
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, private :: &
|
||||||
|
source_damage_anisoBrittle_Ncleavage !< number of cleavage systems per family
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
source_damage_anisoBrittle_aTol, &
|
||||||
|
source_damage_anisoBrittle_sdot_0, &
|
||||||
|
source_damage_anisoBrittle_N
|
||||||
|
|
||||||
|
real(pReal), dimension(:,:), allocatable, private :: &
|
||||||
|
source_damage_anisoBrittle_critDisp, &
|
||||||
|
source_damage_anisoBrittle_critLoad
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
damage_drivingforce_ID
|
||||||
|
end enum
|
||||||
|
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
source_damage_anisoBrittle_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
source_damage_anisoBrittle_init, &
|
||||||
|
source_damage_anisoBrittle_dotState, &
|
||||||
|
source_damage_anisobrittle_getRateAndItsTangent, &
|
||||||
|
source_damage_anisoBrittle_postResults
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_anisoBrittle_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
phase_Noutput, &
|
||||||
|
SOURCE_damage_anisoBrittle_label, &
|
||||||
|
SOURCE_damage_anisoBrittle_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
material_phase, &
|
||||||
|
sourceState, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank, &
|
||||||
|
numerics_integrator
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_maxNcleavageFamily, &
|
||||||
|
lattice_NcleavageSystem
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,source,sourceOffset,o
|
||||||
|
integer(pInt) :: sizeState, sizeDotState
|
||||||
|
integer(pInt) :: NofMyPhase
|
||||||
|
integer(pInt) :: Nchunks_CleavageFamilies = 0_pInt, j
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- source_'//SOURCE_damage_anisoBrittle_LABEL//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_source == SOURCE_damage_anisoBrittle_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(source_damage_anisoBrittle_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoBrittle_instance(material_Nphase), source=0_pInt)
|
||||||
|
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_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoBrittle_sizePostResult(maxval(phase_Noutput),maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoBrittle_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
source_damage_anisoBrittle_output = ''
|
||||||
|
allocate(source_damage_anisoBrittle_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
||||||
|
allocate(source_damage_anisoBrittle_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoBrittle_critDisp(lattice_maxNcleavageFamily,maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_damage_anisoBrittle_critLoad(lattice_maxNcleavageFamily,maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_damage_anisoBrittle_Ncleavage(lattice_maxNcleavageFamily,maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoBrittle_totalNcleavage(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoBrittle_aTol(maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_damage_anisoBrittle_sdot_0(maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_damage_anisoBrittle_N(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_source(:,phase) == SOURCE_damage_anisoBrittle_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
instance = source_damage_anisoBrittle_instance(phase) ! which instance of my damage is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('anisobrittle_drivingforce')
|
||||||
|
source_damage_anisoBrittle_Noutput(instance) = source_damage_anisoBrittle_Noutput(instance) + 1_pInt
|
||||||
|
source_damage_anisoBrittle_outputID(source_damage_anisoBrittle_Noutput(instance),instance) = damage_drivingforce_ID
|
||||||
|
source_damage_anisoBrittle_output(source_damage_anisoBrittle_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
case ('anisobrittle_atol')
|
||||||
|
source_damage_anisoBrittle_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('anisobrittle_sdot0')
|
||||||
|
source_damage_anisoBrittle_sdot_0(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('anisobrittle_ratesensitivity')
|
||||||
|
source_damage_anisoBrittle_N(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('ncleavage') !
|
||||||
|
Nchunks_CleavageFamilies = positions(1) - 1_pInt
|
||||||
|
do j = 1_pInt, Nchunks_CleavageFamilies
|
||||||
|
source_damage_anisoBrittle_Ncleavage(j,instance) = IO_intValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
case ('anisobrittle_criticaldisplacement')
|
||||||
|
do j = 1_pInt, Nchunks_CleavageFamilies
|
||||||
|
source_damage_anisoBrittle_critDisp(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
case ('anisobrittle_criticalload')
|
||||||
|
do j = 1_pInt, Nchunks_CleavageFamilies
|
||||||
|
source_damage_anisoBrittle_critLoad(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! sanity checks
|
||||||
|
sanityChecks: do phase = 1_pInt, material_Nphase
|
||||||
|
myPhase: if (any(phase_source(:,phase) == SOURCE_damage_anisoBrittle_ID)) then
|
||||||
|
instance = source_damage_anisoBrittle_instance(phase)
|
||||||
|
source_damage_anisoBrittle_Ncleavage(1:lattice_maxNcleavageFamily,instance) = &
|
||||||
|
min(lattice_NcleavageSystem(1:lattice_maxNcleavageFamily,phase),& ! limit active cleavage systems per family to min of available and requested
|
||||||
|
source_damage_anisoBrittle_Ncleavage(1:lattice_maxNcleavageFamily,instance))
|
||||||
|
source_damage_anisoBrittle_totalNcleavage(instance) = sum(source_damage_anisoBrittle_Ncleavage(:,instance)) ! how many cleavage systems altogether
|
||||||
|
if (source_damage_anisoBrittle_aTol(instance) < 0.0_pReal) &
|
||||||
|
source_damage_anisoBrittle_aTol(instance) = 1.0e-3_pReal ! default absolute tolerance 1e-3
|
||||||
|
if (source_damage_anisoBrittle_sdot_0(instance) <= 0.0_pReal) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='sdot_0 ('//SOURCE_damage_anisoBrittle_LABEL//')')
|
||||||
|
if (any(source_damage_anisoBrittle_critDisp(1:Nchunks_CleavageFamilies,instance) < 0.0_pReal)) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='critical_displacement ('//SOURCE_damage_anisoBrittle_LABEL//')')
|
||||||
|
if (any(source_damage_anisoBrittle_critLoad(1:Nchunks_CleavageFamilies,instance) < 0.0_pReal)) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='critical_load ('//SOURCE_damage_anisoBrittle_LABEL//')')
|
||||||
|
if (source_damage_anisoBrittle_N(instance) <= 0.0_pReal) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='rate_sensitivity ('//SOURCE_damage_anisoBrittle_LABEL//')')
|
||||||
|
endif myPhase
|
||||||
|
enddo sanityChecks
|
||||||
|
|
||||||
|
initializeInstances: do phase = 1_pInt, material_Nphase
|
||||||
|
if (any(phase_source(:,phase) == SOURCE_damage_anisoBrittle_ID)) then
|
||||||
|
NofMyPhase=count(material_phase==phase)
|
||||||
|
instance = source_damage_anisoBrittle_instance(phase)
|
||||||
|
sourceOffset = source_damage_anisoBrittle_offset(phase)
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,source_damage_anisoBrittle_Noutput(instance)
|
||||||
|
select case(source_damage_anisoBrittle_outputID(o,instance))
|
||||||
|
case(damage_drivingforce_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
source_damage_anisoBrittle_sizePostResult(o,instance) = mySize
|
||||||
|
source_damage_anisoBrittle_sizePostResults(instance) = source_damage_anisoBrittle_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of state array
|
||||||
|
sizeDotState = 1_pInt
|
||||||
|
sizeState = 1_pInt
|
||||||
|
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeState = sizeState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeDotState = sizeDotState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizePostResults = source_damage_anisoBrittle_sizePostResults(instance)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%aTolState (sizeState), &
|
||||||
|
source=source_damage_anisoBrittle_aTol(instance))
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 1_pInt)) then
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
endif
|
||||||
|
if (any(numerics_integrator == 4_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 5_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine source_damage_anisoBrittle_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates derived quantities from state
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_anisoBrittle_dotState(Tstar_v, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState, &
|
||||||
|
material_homog, &
|
||||||
|
damage, &
|
||||||
|
damageMapping
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_Scleavage_v, &
|
||||||
|
lattice_maxNcleavageFamily, &
|
||||||
|
lattice_NcleavageSystem
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), intent(in), dimension(6) :: &
|
||||||
|
Tstar_v !< 2nd Piola Kirchhoff stress tensor (Mandel)
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
constituent, &
|
||||||
|
instance, &
|
||||||
|
sourceOffset, &
|
||||||
|
damageOffset, &
|
||||||
|
homog, &
|
||||||
|
f, i, index_myFamily
|
||||||
|
real(pReal) :: &
|
||||||
|
traction_d, traction_t, traction_n, traction_crit
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_damage_anisoBrittle_instance(phase)
|
||||||
|
sourceOffset = source_damage_anisoBrittle_offset(phase)
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
damageOffset = damageMapping(homog)%p(ip,el)
|
||||||
|
|
||||||
|
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = 0.0_pReal
|
||||||
|
do f = 1_pInt,lattice_maxNcleavageFamily
|
||||||
|
index_myFamily = sum(lattice_NcleavageSystem(1:f-1_pInt,phase)) ! at which index starts my family
|
||||||
|
do i = 1_pInt,source_damage_anisoBrittle_Ncleavage(f,instance) ! process each (active) cleavage system in family
|
||||||
|
traction_d = dot_product(Tstar_v,lattice_Scleavage_v(1:6,1,index_myFamily+i,phase))
|
||||||
|
traction_t = dot_product(Tstar_v,lattice_Scleavage_v(1:6,2,index_myFamily+i,phase))
|
||||||
|
traction_n = dot_product(Tstar_v,lattice_Scleavage_v(1:6,3,index_myFamily+i,phase))
|
||||||
|
|
||||||
|
traction_crit = source_damage_anisoBrittle_critLoad(f,instance)* &
|
||||||
|
damage(homog)%p(damageOffset)
|
||||||
|
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = &
|
||||||
|
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) + &
|
||||||
|
source_damage_anisoBrittle_sdot_0(instance)* &
|
||||||
|
((max(0.0_pReal, abs(traction_d) - traction_crit)/traction_crit)**source_damage_anisoBrittle_N(instance) + &
|
||||||
|
(max(0.0_pReal, abs(traction_t) - traction_crit)/traction_crit)**source_damage_anisoBrittle_N(instance) + &
|
||||||
|
(max(0.0_pReal, abs(traction_n) - traction_crit)/traction_crit)**source_damage_anisoBrittle_N(instance))/ &
|
||||||
|
source_damage_anisoBrittle_critDisp(f,instance)
|
||||||
|
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine source_damage_anisoBrittle_dotState
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns local part of nonlocal damage driving force
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_anisobrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
localphiDot, &
|
||||||
|
dLocalphiDot_dPhi
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, constituent, sourceOffset
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
sourceOffset = source_damage_anisoBrittle_offset(phase)
|
||||||
|
|
||||||
|
localphiDot = 1.0_pReal - &
|
||||||
|
max(1.0_pReal,sourceState(phase)%p(sourceOffset)%state(1,constituent))* &
|
||||||
|
phi
|
||||||
|
|
||||||
|
dLocalphiDot_dPhi = -max(1.0_pReal,sourceState(phase)%p(sourceOffset)%state(1,constituent))
|
||||||
|
|
||||||
|
end subroutine source_damage_anisobrittle_getRateAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of local damage results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function source_damage_anisoBrittle_postResults(ipc,ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(source_damage_anisoBrittle_sizePostResults( &
|
||||||
|
source_damage_anisoBrittle_instance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
||||||
|
source_damage_anisoBrittle_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, phase, constituent, sourceOffset, o, c
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_damage_anisoBrittle_instance(phase)
|
||||||
|
sourceOffset = source_damage_anisoBrittle_offset(phase)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
source_damage_anisoBrittle_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,source_damage_anisoBrittle_Noutput(instance)
|
||||||
|
select case(source_damage_anisoBrittle_outputID(o,instance))
|
||||||
|
case (damage_drivingforce_ID)
|
||||||
|
source_damage_anisoBrittle_postResults(c+1_pInt) = &
|
||||||
|
sourceState(phase)%p(sourceOffset)%state(1,constituent)
|
||||||
|
c = c + 1_pInt
|
||||||
|
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function source_damage_anisoBrittle_postResults
|
||||||
|
|
||||||
|
end module source_damage_anisoBrittle
|
|
@ -0,0 +1,412 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Luv Sharma, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine incorporating anisotropic ductile damage source mechanism
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module source_damage_anisoDuctile
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
source_damage_anisoDuctile_sizePostResults, & !< cumulative size of post results
|
||||||
|
source_damage_anisoDuctile_offset, & !< which source is my current damage mechanism?
|
||||||
|
source_damage_anisoDuctile_instance !< instance of damage source mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_damage_anisoDuctile_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_damage_anisoDuctile_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
source_damage_anisoDuctile_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, private :: &
|
||||||
|
source_damage_anisoDuctile_totalNslip !< total number of slip systems
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, private :: &
|
||||||
|
source_damage_anisoDuctile_Nslip !< number of slip systems per family
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
source_damage_anisoDuctile_aTol
|
||||||
|
|
||||||
|
real(pReal), dimension(:,:), allocatable, private :: &
|
||||||
|
source_damage_anisoDuctile_critPlasticStrain
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
source_damage_anisoDuctile_sdot_0, &
|
||||||
|
source_damage_anisoDuctile_N
|
||||||
|
|
||||||
|
real(pReal), dimension(:,:), allocatable, private :: &
|
||||||
|
source_damage_anisoDuctile_critLoad
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
damage_drivingforce_ID
|
||||||
|
end enum
|
||||||
|
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
source_damage_anisoDuctile_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
source_damage_anisoDuctile_init, &
|
||||||
|
source_damage_anisoDuctile_dotState, &
|
||||||
|
source_damage_anisoDuctile_getRateAndItsTangent, &
|
||||||
|
source_damage_anisoDuctile_postResults
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_anisoDuctile_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
phase_Noutput, &
|
||||||
|
SOURCE_damage_anisoDuctile_label, &
|
||||||
|
SOURCE_damage_anisoDuctile_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
material_phase, &
|
||||||
|
sourceState, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank, &
|
||||||
|
numerics_integrator
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_maxNslipFamily, &
|
||||||
|
lattice_NslipSystem
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,source,sourceOffset,o
|
||||||
|
integer(pInt) :: sizeState, sizeDotState
|
||||||
|
integer(pInt) :: NofMyPhase
|
||||||
|
integer(pInt) :: Nchunks_SlipFamilies = 0_pInt, j
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- source_'//SOURCE_damage_anisoDuctile_LABEL//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_source == SOURCE_damage_anisoDuctile_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(source_damage_anisoDuctile_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoDuctile_instance(material_Nphase), source=0_pInt)
|
||||||
|
do phase = 1, material_Nphase
|
||||||
|
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(source_damage_anisoDuctile_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoDuctile_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(source_damage_anisoDuctile_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
source_damage_anisoDuctile_output = ''
|
||||||
|
allocate(source_damage_anisoDuctile_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
||||||
|
allocate(source_damage_anisoDuctile_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoDuctile_critLoad(lattice_maxNslipFamily,maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_damage_anisoDuctile_critPlasticStrain(lattice_maxNslipFamily,maxNinstance),source=0.0_pReal)
|
||||||
|
allocate(source_damage_anisoDuctile_Nslip(lattice_maxNslipFamily,maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoDuctile_totalNslip(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_anisoDuctile_N(maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_damage_anisoDuctile_sdot_0(maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_damage_anisoDuctile_aTol(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_source(:,phase) == SOURCE_damage_anisoDuctile_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
instance = source_damage_anisoDuctile_instance(phase) ! which instance of my damage is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('anisoductile_drivingforce')
|
||||||
|
source_damage_anisoDuctile_Noutput(instance) = source_damage_anisoDuctile_Noutput(instance) + 1_pInt
|
||||||
|
source_damage_anisoDuctile_outputID(source_damage_anisoDuctile_Noutput(instance),instance) = damage_drivingforce_ID
|
||||||
|
source_damage_anisoDuctile_output(source_damage_anisoDuctile_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
case ('anisoductile_atol')
|
||||||
|
source_damage_anisoDuctile_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('nslip') !
|
||||||
|
Nchunks_SlipFamilies = positions(1) - 1_pInt
|
||||||
|
do j = 1_pInt, Nchunks_SlipFamilies
|
||||||
|
source_damage_anisoDuctile_Nslip(j,instance) = IO_intValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
case ('anisoductile_sdot0')
|
||||||
|
source_damage_anisoDuctile_sdot_0(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('anisoductile_criticalplasticstrain')
|
||||||
|
do j = 1_pInt, Nchunks_SlipFamilies
|
||||||
|
source_damage_anisoDuctile_critPlasticStrain(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
case ('anisoductile_ratesensitivity')
|
||||||
|
source_damage_anisoDuctile_N(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('anisoductile_criticalload')
|
||||||
|
do j = 1_pInt, Nchunks_SlipFamilies
|
||||||
|
source_damage_anisoDuctile_critLoad(j,instance) = IO_floatValue(line,positions,1_pInt+j)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! sanity checks
|
||||||
|
sanityChecks: do phase = 1_pInt, size(phase_source)
|
||||||
|
myPhase: if (any(phase_source(:,phase) == SOURCE_damage_anisoDuctile_ID)) then
|
||||||
|
instance = source_damage_anisoDuctile_instance(phase)
|
||||||
|
source_damage_anisoDuctile_Nslip(1:lattice_maxNslipFamily,instance) = &
|
||||||
|
min(lattice_NslipSystem(1:lattice_maxNslipFamily,phase),& ! limit active cleavage systems per family to min of available and requested
|
||||||
|
source_damage_anisoDuctile_Nslip(1:lattice_maxNslipFamily,instance))
|
||||||
|
source_damage_anisoDuctile_totalNslip(instance) = sum(source_damage_anisoDuctile_Nslip(:,instance))
|
||||||
|
if (source_damage_anisoDuctile_aTol(instance) < 0.0_pReal) &
|
||||||
|
source_damage_anisoDuctile_aTol(instance) = 1.0e-3_pReal ! default absolute tolerance 1e-3
|
||||||
|
if (source_damage_anisoDuctile_sdot_0(instance) <= 0.0_pReal) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='sdot_0 ('//SOURCE_damage_anisoDuctile_LABEL//')')
|
||||||
|
if (any(source_damage_anisoDuctile_critPlasticStrain(:,instance) < 0.0_pReal)) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='criticaPlasticStrain ('//SOURCE_damage_anisoDuctile_LABEL//')')
|
||||||
|
if (source_damage_anisoDuctile_N(instance) <= 0.0_pReal) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='rate_sensitivity ('//SOURCE_damage_anisoDuctile_LABEL//')')
|
||||||
|
endif myPhase
|
||||||
|
enddo sanityChecks
|
||||||
|
|
||||||
|
|
||||||
|
initializeInstances: do phase = 1_pInt, material_Nphase
|
||||||
|
if (any(phase_source(:,phase) == SOURCE_damage_anisoDuctile_ID)) then
|
||||||
|
NofMyPhase=count(material_phase==phase)
|
||||||
|
instance = source_damage_anisoDuctile_instance(phase)
|
||||||
|
sourceOffset = source_damage_anisoDuctile_offset(phase)
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,source_damage_anisoDuctile_Noutput(instance)
|
||||||
|
select case(source_damage_anisoDuctile_outputID(o,instance))
|
||||||
|
case(damage_drivingforce_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
source_damage_anisoDuctile_sizePostResult(o,instance) = mySize
|
||||||
|
source_damage_anisoDuctile_sizePostResults(instance) = source_damage_anisoDuctile_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of state array
|
||||||
|
sizeDotState = 1_pInt
|
||||||
|
sizeState = 1_pInt
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeState = sizeState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeDotState = sizeDotState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizePostResults = source_damage_anisoDuctile_sizePostResults(instance)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%aTolState (sizeState), &
|
||||||
|
source=source_damage_anisoDuctile_aTol(instance))
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 1_pInt)) then
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
endif
|
||||||
|
if (any(numerics_integrator == 4_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 5_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine source_damage_anisoDuctile_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates derived quantities from state
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_anisoDuctile_dotState(ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
plasticState, &
|
||||||
|
sourceState, &
|
||||||
|
material_homog, &
|
||||||
|
damage, &
|
||||||
|
damageMapping
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_maxNslipFamily
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
constituent, &
|
||||||
|
sourceOffset, &
|
||||||
|
homog, damageOffset, &
|
||||||
|
instance, &
|
||||||
|
index, f, i
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_damage_anisoDuctile_instance(phase)
|
||||||
|
sourceOffset = source_damage_anisoDuctile_offset(phase)
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
damageOffset = damageMapping(homog)%p(ip,el)
|
||||||
|
|
||||||
|
index = 1_pInt
|
||||||
|
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = 0.0_pReal
|
||||||
|
do f = 1_pInt,lattice_maxNslipFamily
|
||||||
|
do i = 1_pInt,source_damage_anisoDuctile_Nslip(f,instance) ! process each (active) slip system in family
|
||||||
|
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = &
|
||||||
|
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) + &
|
||||||
|
plasticState(phase)%slipRate(index,constituent)/ &
|
||||||
|
((damage(homog)%p(damageOffset))**source_damage_anisoDuctile_N(instance))/ &
|
||||||
|
source_damage_anisoDuctile_critPlasticStrain(f,instance)
|
||||||
|
|
||||||
|
index = index + 1_pInt
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine source_damage_anisoDuctile_dotState
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns local part of nonlocal damage driving force
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_anisoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
localphiDot, &
|
||||||
|
dLocalphiDot_dPhi
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, constituent, sourceOffset
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
sourceOffset = source_damage_anisoDuctile_offset(phase)
|
||||||
|
|
||||||
|
localphiDot = 1.0_pReal - &
|
||||||
|
max(1.0_pReal,sourceState(phase)%p(sourceOffset)%state(1,constituent))* &
|
||||||
|
phi
|
||||||
|
|
||||||
|
dLocalphiDot_dPhi = -max(1.0_pReal,sourceState(phase)%p(sourceOffset)%state(1,constituent))
|
||||||
|
|
||||||
|
end subroutine source_damage_anisoDuctile_getRateAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of local damage results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function source_damage_anisoDuctile_postResults(ipc,ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(source_damage_anisoDuctile_sizePostResults( &
|
||||||
|
source_damage_anisoDuctile_instance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
||||||
|
source_damage_anisoDuctile_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, phase, constituent, sourceOffset, o, c
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_damage_anisoDuctile_instance(phase)
|
||||||
|
sourceOffset = source_damage_anisoDuctile_offset(phase)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
source_damage_anisoDuctile_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,source_damage_anisoDuctile_Noutput(instance)
|
||||||
|
select case(source_damage_anisoDuctile_outputID(o,instance))
|
||||||
|
case (damage_drivingforce_ID)
|
||||||
|
source_damage_anisoDuctile_postResults(c+1_pInt) = &
|
||||||
|
sourceState(phase)%p(sourceOffset)%state(1,constituent)
|
||||||
|
c = c + 1_pInt
|
||||||
|
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function source_damage_anisoDuctile_postResults
|
||||||
|
|
||||||
|
end module source_damage_anisoDuctile
|
|
@ -0,0 +1,362 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @author Luv Sharma, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine incoprorating isotropic brittle damage source mechanism
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module source_damage_isoBrittle
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
source_damage_isoBrittle_sizePostResults, & !< cumulative size of post results
|
||||||
|
source_damage_isoBrittle_offset, & !< which source is my current damage mechanism?
|
||||||
|
source_damage_isoBrittle_instance !< instance of damage source mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_damage_isoBrittle_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_damage_isoBrittle_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
source_damage_isoBrittle_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
source_damage_isoBrittle_aTol, &
|
||||||
|
source_damage_isoBrittle_critStrainEnergy
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
damage_drivingforce_ID
|
||||||
|
end enum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11 ToDo
|
||||||
|
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
source_damage_isoBrittle_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
source_damage_isoBrittle_init, &
|
||||||
|
source_damage_isoBrittle_deltaState, &
|
||||||
|
source_damage_isoBrittle_getRateAndItsTangent, &
|
||||||
|
source_damage_isoBrittle_postResults
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_isoBrittle_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
phase_Noutput, &
|
||||||
|
SOURCE_damage_isoBrittle_label, &
|
||||||
|
SOURCE_damage_isoBrittle_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
material_phase, &
|
||||||
|
sourceState, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank, &
|
||||||
|
numerics_integrator
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,source,sourceOffset,o
|
||||||
|
integer(pInt) :: sizeState, sizeDotState
|
||||||
|
integer(pInt) :: NofMyPhase
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- source_'//SOURCE_damage_isoBrittle_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_source == SOURCE_damage_isoBrittle_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(source_damage_isoBrittle_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(source_damage_isoBrittle_instance(material_Nphase), source=0_pInt)
|
||||||
|
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(source_damage_isoBrittle_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_isoBrittle_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(source_damage_isoBrittle_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
source_damage_isoBrittle_output = ''
|
||||||
|
allocate(source_damage_isoBrittle_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
||||||
|
allocate(source_damage_isoBrittle_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_isoBrittle_critStrainEnergy(maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_damage_isoBrittle_aTol(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_source(:,phase) == SOURCE_damage_isoBrittle_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
instance = source_damage_isoBrittle_instance(phase) ! which instance of my damage is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('isobrittle_drivingforce')
|
||||||
|
source_damage_isoBrittle_Noutput(instance) = source_damage_isoBrittle_Noutput(instance) + 1_pInt
|
||||||
|
source_damage_isoBrittle_outputID(source_damage_isoBrittle_Noutput(instance),instance) = damage_drivingforce_ID
|
||||||
|
source_damage_isoBrittle_output(source_damage_isoBrittle_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
case ('isobrittle_criticalstrainenergy')
|
||||||
|
source_damage_isoBrittle_critStrainEnergy(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('isobrittle_atol')
|
||||||
|
source_damage_isoBrittle_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! sanity checks
|
||||||
|
sanityChecks: do phase = 1_pInt, material_Nphase
|
||||||
|
myPhase: if (any(phase_source(:,phase) == SOURCE_damage_isoBrittle_ID)) then
|
||||||
|
instance = source_damage_isoBrittle_instance(phase)
|
||||||
|
if (source_damage_isoBrittle_aTol(instance) < 0.0_pReal) &
|
||||||
|
source_damage_isoBrittle_aTol(instance) = 1.0e-3_pReal ! default absolute tolerance 1e-3
|
||||||
|
if (source_damage_isoBrittle_critStrainEnergy(instance) <= 0.0_pReal) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='criticalStrainEnergy ('//SOURCE_damage_isoBrittle_LABEL//')')
|
||||||
|
endif myPhase
|
||||||
|
enddo sanityChecks
|
||||||
|
|
||||||
|
initializeInstances: do phase = 1_pInt, material_Nphase
|
||||||
|
if (any(phase_source(:,phase) == SOURCE_damage_isoBrittle_ID)) then
|
||||||
|
NofMyPhase=count(material_phase==phase)
|
||||||
|
instance = source_damage_isoBrittle_instance(phase)
|
||||||
|
sourceOffset = source_damage_isoBrittle_offset(phase)
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,source_damage_isoBrittle_Noutput(instance)
|
||||||
|
select case(source_damage_isoBrittle_outputID(o,instance))
|
||||||
|
case(damage_drivingforce_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
source_damage_isoBrittle_sizePostResult(o,instance) = mySize
|
||||||
|
source_damage_isoBrittle_sizePostResults(instance) = source_damage_isoBrittle_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
! Determine size of state array
|
||||||
|
sizeDotState = 1_pInt
|
||||||
|
sizeState = 1_pInt
|
||||||
|
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeState = sizeState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeDotState = sizeDotState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizePostResults = source_damage_isoBrittle_sizePostResults(instance)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%aTolState (sizeState), &
|
||||||
|
source=source_damage_isoBrittle_aTol(instance))
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state0 (sizeState,NofMyPhase), source=.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 1_pInt)) then
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
endif
|
||||||
|
if (any(numerics_integrator == 4_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 5_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine source_damage_isoBrittle_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates derived quantities from state
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_isoBrittle_deltaState(C, Fe, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState, &
|
||||||
|
material_homog, &
|
||||||
|
phase_NstiffnessDegradations, &
|
||||||
|
phase_stiffnessDegradation, &
|
||||||
|
porosity, &
|
||||||
|
porosityMapping, &
|
||||||
|
STIFFNESS_DEGRADATION_porosity_ID
|
||||||
|
use math, only : &
|
||||||
|
math_mul33x33, &
|
||||||
|
math_mul66x6, &
|
||||||
|
math_Mandel33to6, &
|
||||||
|
math_transpose33, &
|
||||||
|
math_I3
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), intent(in), dimension(3,3) :: &
|
||||||
|
Fe
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, constituent, instance, sourceOffset, mech
|
||||||
|
real(pReal) :: &
|
||||||
|
strain(6), &
|
||||||
|
C(6,6)
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_damage_isoBrittle_instance(phase)
|
||||||
|
sourceOffset = source_damage_isoBrittle_offset(phase)
|
||||||
|
|
||||||
|
do mech = 1_pInt, phase_NstiffnessDegradations(phase)
|
||||||
|
select case(phase_stiffnessDegradation(mech,phase))
|
||||||
|
case (STIFFNESS_DEGRADATION_porosity_ID)
|
||||||
|
C = porosity(material_homog(ip,el))%p(porosityMapping(material_homog(ip,el))%p(ip,el))* &
|
||||||
|
porosity(material_homog(ip,el))%p(porosityMapping(material_homog(ip,el))%p(ip,el))* &
|
||||||
|
C
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
strain = 0.5_pReal*math_Mandel33to6(math_mul33x33(math_transpose33(Fe),Fe)-math_I3)
|
||||||
|
|
||||||
|
sourceState(phase)%p(sourceOffset)%deltaState(1,constituent) = &
|
||||||
|
2.0_pReal*sum(strain*math_mul66x6(C,strain))/source_damage_isoBrittle_critStrainEnergy(instance) - &
|
||||||
|
sourceState(phase)%p(sourceOffset)%state(1,constituent)
|
||||||
|
|
||||||
|
end subroutine source_damage_isoBrittle_deltaState
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns local part of nonlocal damage driving force
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_isoBrittle_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
localphiDot, &
|
||||||
|
dLocalphiDot_dPhi
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, constituent, sourceOffset
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
sourceOffset = source_damage_isoBrittle_offset(phase)
|
||||||
|
|
||||||
|
localphiDot = 1.0_pReal - &
|
||||||
|
max(1.0_pReal,sourceState(phase)%p(sourceOffset)%state(1,constituent))* &
|
||||||
|
phi
|
||||||
|
|
||||||
|
dLocalphiDot_dPhi = -max(1.0_pReal,sourceState(phase)%p(sourceOffset)%state(1,constituent))
|
||||||
|
|
||||||
|
end subroutine source_damage_isoBrittle_getRateAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of local damage results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function source_damage_isoBrittle_postResults(ipc,ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(source_damage_isoBrittle_sizePostResults( &
|
||||||
|
source_damage_isoBrittle_instance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
||||||
|
source_damage_isoBrittle_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, phase, constituent, sourceOffset, o, c
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_damage_isoBrittle_instance(phase)
|
||||||
|
sourceOffset = source_damage_isoBrittle_offset(phase)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
source_damage_isoBrittle_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,source_damage_isoBrittle_Noutput(instance)
|
||||||
|
select case(source_damage_isoBrittle_outputID(o,instance))
|
||||||
|
case (damage_drivingforce_ID)
|
||||||
|
source_damage_isoBrittle_postResults(c+1_pInt) = sourceState(phase)%p(sourceOffset)%state(1,constituent)
|
||||||
|
c = c + 1
|
||||||
|
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function source_damage_isoBrittle_postResults
|
||||||
|
|
||||||
|
end module source_damage_isoBrittle
|
|
@ -0,0 +1,347 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut fŸr Eisenforschung GmbH
|
||||||
|
!> @author Luv Sharma, Max-Planck-Institut fŸr Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine incoprorating isotropic ductile damage source mechanism
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module source_damage_isoDuctile
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
source_damage_isoDuctile_sizePostResults, & !< cumulative size of post results
|
||||||
|
source_damage_isoDuctile_offset, & !< which source is my current damage mechanism?
|
||||||
|
source_damage_isoDuctile_instance !< instance of damage source mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_damage_isoDuctile_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_damage_isoDuctile_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
source_damage_isoDuctile_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
source_damage_isoDuctile_aTol, &
|
||||||
|
source_damage_isoDuctile_critPlasticStrain, &
|
||||||
|
source_damage_isoDuctile_N
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
damage_drivingforce_ID
|
||||||
|
end enum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11 ToDo
|
||||||
|
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
source_damage_isoDuctile_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
source_damage_isoDuctile_init, &
|
||||||
|
source_damage_isoDuctile_dotState, &
|
||||||
|
source_damage_isoDuctile_getRateAndItsTangent, &
|
||||||
|
source_damage_isoDuctile_postResults
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_isoDuctile_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
phase_Noutput, &
|
||||||
|
SOURCE_damage_isoDuctile_label, &
|
||||||
|
SOURCE_damage_isoDuctile_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
material_phase, &
|
||||||
|
sourceState, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank, &
|
||||||
|
numerics_integrator
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,source,sourceOffset,o
|
||||||
|
integer(pInt) :: sizeState, sizeDotState
|
||||||
|
integer(pInt) :: NofMyPhase
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- source_'//SOURCE_damage_isoDuctile_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_source == SOURCE_damage_isoDuctile_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(source_damage_isoDuctile_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(source_damage_isoDuctile_instance(material_Nphase), source=0_pInt)
|
||||||
|
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(source_damage_isoDuctile_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_isoDuctile_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(source_damage_isoDuctile_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
source_damage_isoDuctile_output = ''
|
||||||
|
allocate(source_damage_isoDuctile_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
||||||
|
allocate(source_damage_isoDuctile_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_damage_isoDuctile_critPlasticStrain(maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_damage_isoDuctile_N(maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_damage_isoDuctile_aTol(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_source(:,phase) == SOURCE_damage_isoDuctile_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
instance = source_damage_isoDuctile_instance(phase) ! which instance of my damage is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('isoductile_drivingforce')
|
||||||
|
source_damage_isoDuctile_Noutput(instance) = source_damage_isoDuctile_Noutput(instance) + 1_pInt
|
||||||
|
source_damage_isoDuctile_outputID(source_damage_isoDuctile_Noutput(instance),instance) = damage_drivingforce_ID
|
||||||
|
source_damage_isoDuctile_output(source_damage_isoDuctile_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
case ('isoductile_criticalplasticstrain')
|
||||||
|
source_damage_isoDuctile_critPlasticStrain(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('isoductile_ratesensitivity')
|
||||||
|
source_damage_isoDuctile_N(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('isoductile_atol')
|
||||||
|
source_damage_isoDuctile_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! sanity checks
|
||||||
|
sanityChecks: do phase = 1_pInt, material_Nphase
|
||||||
|
myPhase: if (any(phase_source(:,phase) == SOURCE_damage_isoDuctile_ID)) then
|
||||||
|
instance = source_damage_isoDuctile_instance(phase)
|
||||||
|
if (source_damage_isoDuctile_aTol(instance) < 0.0_pReal) &
|
||||||
|
source_damage_isoDuctile_aTol(instance) = 1.0e-3_pReal ! default absolute tolerance 1e-3
|
||||||
|
if (source_damage_isoDuctile_critPlasticStrain(instance) <= 0.0_pReal) &
|
||||||
|
call IO_error(211_pInt,el=instance,ext_msg='critical plastic strain ('//SOURCE_damage_isoDuctile_LABEL//')')
|
||||||
|
endif myPhase
|
||||||
|
enddo sanityChecks
|
||||||
|
|
||||||
|
initializeInstances: do phase = 1_pInt, material_Nphase
|
||||||
|
if (any(phase_source(:,phase) == SOURCE_damage_isoDuctile_ID)) then
|
||||||
|
NofMyPhase=count(material_phase==phase)
|
||||||
|
instance = source_damage_isoDuctile_instance(phase)
|
||||||
|
sourceOffset = source_damage_isoDuctile_offset(phase)
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,source_damage_isoDuctile_Noutput(instance)
|
||||||
|
select case(source_damage_isoDuctile_outputID(o,instance))
|
||||||
|
case(damage_drivingforce_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
source_damage_isoDuctile_sizePostResult(o,instance) = mySize
|
||||||
|
source_damage_isoDuctile_sizePostResults(instance) = source_damage_isoDuctile_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
! Determine size of state array
|
||||||
|
sizeDotState = 0_pInt
|
||||||
|
sizeState = 1_pInt
|
||||||
|
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeState = sizeState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeDotState = sizeDotState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizePostResults = source_damage_isoDuctile_sizePostResults(instance)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%aTolState (sizeState), &
|
||||||
|
source=source_damage_isoDuctile_aTol(instance))
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state0 (sizeState,NofMyPhase), source=.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 1_pInt)) then
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
endif
|
||||||
|
if (any(numerics_integrator == 4_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 5_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine source_damage_isoDuctile_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates derived quantities from state
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_isoDuctile_dotState(ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
plasticState, &
|
||||||
|
sourceState, &
|
||||||
|
material_homog, &
|
||||||
|
damage, &
|
||||||
|
damageMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, constituent, instance, homog, sourceOffset, damageOffset
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_damage_isoDuctile_instance(phase)
|
||||||
|
sourceOffset = source_damage_isoDuctile_offset(phase)
|
||||||
|
homog = material_homog(ip,el)
|
||||||
|
damageOffset = damageMapping(homog)%p(ip,el)
|
||||||
|
|
||||||
|
sourceState(phase)%p(sourceOffset)%dotState(1,constituent) = &
|
||||||
|
sum(plasticState(phase)%slipRate(:,constituent))/ &
|
||||||
|
((damage(homog)%p(damageOffset))**source_damage_isoDuctile_N(instance))/ &
|
||||||
|
source_damage_isoDuctile_critPlasticStrain(instance)
|
||||||
|
|
||||||
|
end subroutine source_damage_isoDuctile_dotState
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns local part of nonlocal damage driving force
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_damage_isoDuctile_getRateAndItsTangent(localphiDot, dLocalphiDot_dPhi, phi, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
phi
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
localphiDot, &
|
||||||
|
dLocalphiDot_dPhi
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, constituent, sourceOffset
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
sourceOffset = source_damage_isoDuctile_offset(phase)
|
||||||
|
|
||||||
|
localphiDot = 1.0_pReal - &
|
||||||
|
max(1.0_pReal,sourceState(phase)%p(sourceOffset)%state(1,constituent))* &
|
||||||
|
phi
|
||||||
|
|
||||||
|
dLocalphiDot_dPhi = -max(1.0_pReal,sourceState(phase)%p(sourceOffset)%state(1,constituent))
|
||||||
|
|
||||||
|
end subroutine source_damage_isoDuctile_getRateAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of local damage results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function source_damage_isoDuctile_postResults(ipc,ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(source_damage_isoDuctile_sizePostResults( &
|
||||||
|
source_damage_isoDuctile_instance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
||||||
|
source_damage_isoDuctile_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, phase, constituent, sourceOffset, o, c
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_damage_isoDuctile_instance(phase)
|
||||||
|
sourceOffset = source_damage_isoDuctile_offset(phase)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
source_damage_isoDuctile_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,source_damage_isoDuctile_Noutput(instance)
|
||||||
|
select case(source_damage_isoDuctile_outputID(o,instance))
|
||||||
|
case (damage_drivingforce_ID)
|
||||||
|
source_damage_isoDuctile_postResults(c+1_pInt) = sourceState(phase)%p(sourceOffset)%state(1,constituent)
|
||||||
|
c = c + 1
|
||||||
|
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function source_damage_isoDuctile_postResults
|
||||||
|
|
||||||
|
end module source_damage_isoDuctile
|
|
@ -0,0 +1,217 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for thermal source due to plastic dissipation
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module source_thermal_dissipation
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
source_thermal_dissipation_sizePostResults, & !< cumulative size of post results
|
||||||
|
source_thermal_dissipation_offset, & !< which source is my current thermal dissipation mechanism?
|
||||||
|
source_thermal_dissipation_instance !< instance of thermal dissipation source mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_thermal_dissipation_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_thermal_dissipation_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
source_thermal_dissipation_Noutput !< number of outputs per instance of this source
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
source_thermal_dissipation_coldworkCoeff
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
source_thermal_dissipation_init, &
|
||||||
|
source_thermal_dissipation_getRateAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_thermal_dissipation_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
phase_Noutput, &
|
||||||
|
SOURCE_thermal_dissipation_label, &
|
||||||
|
SOURCE_thermal_dissipation_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
material_phase, &
|
||||||
|
sourceState, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank, &
|
||||||
|
numerics_integrator
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,phase,instance,source,sourceOffset
|
||||||
|
integer(pInt) :: sizeState, sizeDotState
|
||||||
|
integer(pInt) :: NofMyPhase
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- source_'//SOURCE_thermal_dissipation_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_source == SOURCE_thermal_dissipation_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(source_thermal_dissipation_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(source_thermal_dissipation_instance(material_Nphase), source=0_pInt)
|
||||||
|
do phase = 1, material_Nphase
|
||||||
|
source_thermal_dissipation_instance(phase) = count(phase_source(:,1:phase) == SOURCE_thermal_dissipation_ID)
|
||||||
|
do source = 1, phase_Nsources(phase)
|
||||||
|
if (phase_source(source,phase) == SOURCE_thermal_dissipation_ID) &
|
||||||
|
source_thermal_dissipation_offset(phase) = source
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
allocate(source_thermal_dissipation_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_thermal_dissipation_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(source_thermal_dissipation_output (maxval(phase_Noutput),maxNinstance))
|
||||||
|
source_thermal_dissipation_output = ''
|
||||||
|
allocate(source_thermal_dissipation_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_thermal_dissipation_coldworkCoeff(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_source(:,phase) == SOURCE_thermal_dissipation_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = source_thermal_dissipation_instance(phase) ! which instance of my source is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('dissipation_coldworkcoeff')
|
||||||
|
source_thermal_dissipation_coldworkCoeff(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
initializeInstances: do phase = 1_pInt, material_Nphase
|
||||||
|
if (any(phase_source(:,phase) == SOURCE_thermal_dissipation_ID)) then
|
||||||
|
NofMyPhase=count(material_phase==phase)
|
||||||
|
instance = source_thermal_dissipation_instance(phase)
|
||||||
|
sourceOffset = source_thermal_dissipation_offset(phase)
|
||||||
|
|
||||||
|
sizeDotState = 0_pInt
|
||||||
|
sizeState = 0_pInt
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeState = sizeState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeDotState = sizeDotState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizePostResults = source_thermal_dissipation_sizePostResults(instance)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%aTolState (sizeState), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 1_pInt)) then
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
endif
|
||||||
|
if (any(numerics_integrator == 4_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 5_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine source_thermal_dissipation_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns local vacancy generation rate
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_thermal_dissipation_getRateAndItsTangent(TDot, dTDOT_dT, Tstar_v, Lp, ipc, ip, el)
|
||||||
|
use math, only: &
|
||||||
|
math_Mandel6to33
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in), dimension(6) :: &
|
||||||
|
Tstar_v !< 2nd Piola Kirchhoff stress tensor (Mandel)
|
||||||
|
real(pReal), intent(in), dimension(3,3) :: &
|
||||||
|
Lp
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
TDot, &
|
||||||
|
dTDOT_dT
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, phase, constituent
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_thermal_dissipation_instance(phase)
|
||||||
|
|
||||||
|
TDot = source_thermal_dissipation_coldworkCoeff(instance)* &
|
||||||
|
sum(abs(math_Mandel6to33(Tstar_v)*Lp))
|
||||||
|
dTDOT_dT = 0.0_pReal
|
||||||
|
|
||||||
|
end subroutine source_thermal_dissipation_getRateAndItsTangent
|
||||||
|
|
||||||
|
end module source_thermal_dissipation
|
|
@ -0,0 +1,250 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for vacancy generation due to irradiation
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module source_vacancy_irradiation
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
source_vacancy_irradiation_sizePostResults, & !< cumulative size of post results
|
||||||
|
source_vacancy_irradiation_offset, & !< which source is my current damage mechanism?
|
||||||
|
source_vacancy_irradiation_instance !< instance of damage source mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_vacancy_irradiation_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_vacancy_irradiation_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
source_vacancy_irradiation_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
source_vacancy_irradiation_cascadeProb, &
|
||||||
|
source_vacancy_irradiation_cascadeVolume
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
source_vacancy_irradiation_init, &
|
||||||
|
source_vacancy_irradiation_deltaState, &
|
||||||
|
source_vacancy_irradiation_getRateAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_vacancy_irradiation_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
phase_Noutput, &
|
||||||
|
SOURCE_vacancy_irradiation_label, &
|
||||||
|
SOURCE_vacancy_irradiation_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
material_phase, &
|
||||||
|
sourceState, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank, &
|
||||||
|
numerics_integrator
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,phase,instance,source,sourceOffset
|
||||||
|
integer(pInt) :: sizeState, sizeDotState
|
||||||
|
integer(pInt) :: NofMyPhase
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- source_'//SOURCE_vacancy_irradiation_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_source == SOURCE_vacancy_irradiation_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(source_vacancy_irradiation_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(source_vacancy_irradiation_instance(material_Nphase), source=0_pInt)
|
||||||
|
do phase = 1, material_Nphase
|
||||||
|
source_vacancy_irradiation_instance(phase) = count(phase_source(:,1:phase) == source_vacancy_irradiation_ID)
|
||||||
|
do source = 1, phase_Nsources(phase)
|
||||||
|
if (phase_source(source,phase) == source_vacancy_irradiation_ID) &
|
||||||
|
source_vacancy_irradiation_offset(phase) = source
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
allocate(source_vacancy_irradiation_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_vacancy_irradiation_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(source_vacancy_irradiation_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
source_vacancy_irradiation_output = ''
|
||||||
|
allocate(source_vacancy_irradiation_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_vacancy_irradiation_cascadeProb(maxNinstance), source=0.0_pReal)
|
||||||
|
allocate(source_vacancy_irradiation_cascadeVolume(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_source(:,phase) == SOURCE_vacancy_irradiation_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = source_vacancy_irradiation_instance(phase) ! which instance of my vacancy is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('irradiation_cascadeprobability')
|
||||||
|
source_vacancy_irradiation_cascadeProb(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('irradiation_cascadevolume')
|
||||||
|
source_vacancy_irradiation_cascadeVolume(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
initializeInstances: do phase = 1_pInt, material_Nphase
|
||||||
|
if (any(phase_source(:,phase) == SOURCE_vacancy_irradiation_ID)) then
|
||||||
|
NofMyPhase=count(material_phase==phase)
|
||||||
|
instance = source_vacancy_irradiation_instance(phase)
|
||||||
|
sourceOffset = source_vacancy_irradiation_offset(phase)
|
||||||
|
|
||||||
|
sizeDotState = 2_pInt
|
||||||
|
sizeState = 2_pInt
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeState = sizeState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeDotState = sizeDotState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizePostResults = source_vacancy_irradiation_sizePostResults(instance)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%aTolState (sizeState), source=0.1_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 1_pInt)) then
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
endif
|
||||||
|
if (any(numerics_integrator == 4_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 5_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine source_vacancy_irradiation_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates derived quantities from state
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_vacancy_irradiation_deltaState(ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, constituent, sourceOffset
|
||||||
|
real(pReal) :: &
|
||||||
|
randNo
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
sourceOffset = source_vacancy_irradiation_offset(phase)
|
||||||
|
|
||||||
|
call random_number(randNo)
|
||||||
|
sourceState(phase)%p(sourceOffset)%deltaState(1,constituent) = &
|
||||||
|
randNo - sourceState(phase)%p(sourceOffset)%state(1,constituent)
|
||||||
|
call random_number(randNo)
|
||||||
|
sourceState(phase)%p(sourceOffset)%deltaState(2,constituent) = &
|
||||||
|
randNo - sourceState(phase)%p(sourceOffset)%state(2,constituent)
|
||||||
|
|
||||||
|
end subroutine source_vacancy_irradiation_deltaState
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns local vacancy generation rate
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_vacancy_irradiation_getRateAndItsTangent(CvDot, dCvDot_dCv, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
CvDot, dCvDot_dCv
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, phase, constituent, sourceOffset
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_vacancy_irradiation_instance(phase)
|
||||||
|
sourceOffset = source_vacancy_irradiation_offset(phase)
|
||||||
|
|
||||||
|
CvDot = 0.0_pReal
|
||||||
|
dCvDot_dCv = 0.0_pReal
|
||||||
|
if (sourceState(phase)%p(sourceOffset)%state0(1,constituent) < source_vacancy_irradiation_cascadeProb(instance)) &
|
||||||
|
CvDot = sourceState(phase)%p(sourceOffset)%state0(2,constituent)*source_vacancy_irradiation_cascadeVolume(instance)
|
||||||
|
|
||||||
|
end subroutine source_vacancy_irradiation_getRateAndItsTangent
|
||||||
|
|
||||||
|
end module source_vacancy_irradiation
|
|
@ -0,0 +1,212 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for vacancy generation due to plasticity
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module source_vacancy_phenoplasticity
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
source_vacancy_phenoplasticity_sizePostResults, & !< cumulative size of post results
|
||||||
|
source_vacancy_phenoplasticity_offset, & !< which source is my current damage mechanism?
|
||||||
|
source_vacancy_phenoplasticity_instance !< instance of damage source mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_vacancy_phenoplasticity_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_vacancy_phenoplasticity_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
source_vacancy_phenoplasticity_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
source_vacancy_phenoplasticity_rateCoeff
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
source_vacancy_phenoplasticity_init, &
|
||||||
|
source_vacancy_phenoplasticity_getRateAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_vacancy_phenoplasticity_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
phase_Noutput, &
|
||||||
|
SOURCE_vacancy_phenoplasticity_label, &
|
||||||
|
SOURCE_vacancy_phenoplasticity_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
material_phase, &
|
||||||
|
sourceState, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank, &
|
||||||
|
numerics_integrator
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,phase,instance,source,sourceOffset
|
||||||
|
integer(pInt) :: sizeState, sizeDotState
|
||||||
|
integer(pInt) :: NofMyPhase
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- source_'//SOURCE_vacancy_phenoplasticity_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_source == SOURCE_vacancy_phenoplasticity_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(source_vacancy_phenoplasticity_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(source_vacancy_phenoplasticity_instance(material_Nphase), source=0_pInt)
|
||||||
|
do phase = 1, material_Nphase
|
||||||
|
source_vacancy_phenoplasticity_instance(phase) = count(phase_source(:,1:phase) == source_vacancy_phenoplasticity_ID)
|
||||||
|
do source = 1, phase_Nsources(phase)
|
||||||
|
if (phase_source(source,phase) == source_vacancy_phenoplasticity_ID) &
|
||||||
|
source_vacancy_phenoplasticity_offset(phase) = source
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
allocate(source_vacancy_phenoplasticity_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_vacancy_phenoplasticity_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(source_vacancy_phenoplasticity_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
source_vacancy_phenoplasticity_output = ''
|
||||||
|
allocate(source_vacancy_phenoplasticity_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_vacancy_phenoplasticity_rateCoeff(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_source(:,phase) == SOURCE_vacancy_phenoplasticity_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = source_vacancy_phenoplasticity_instance(phase) ! which instance of my vacancy is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('phenoplasticity_ratecoeff')
|
||||||
|
source_vacancy_phenoplasticity_rateCoeff(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
initializeInstances: do phase = 1_pInt, material_Nphase
|
||||||
|
if (any(phase_source(:,phase) == SOURCE_vacancy_phenoplasticity_ID)) then
|
||||||
|
NofMyPhase=count(material_phase==phase)
|
||||||
|
instance = source_vacancy_phenoplasticity_instance(phase)
|
||||||
|
sourceOffset = source_vacancy_phenoplasticity_offset(phase)
|
||||||
|
|
||||||
|
sizeDotState = 0_pInt
|
||||||
|
sizeState = 0_pInt
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeState = sizeState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeDotState = sizeDotState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizePostResults = source_vacancy_phenoplasticity_sizePostResults(instance)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%aTolState (sizeState), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 1_pInt)) then
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
endif
|
||||||
|
if (any(numerics_integrator == 4_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 5_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine source_vacancy_phenoplasticity_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns local vacancy generation rate
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_vacancy_phenoplasticity_getRateAndItsTangent(CvDot, dCvDot_dCv, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
plasticState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
CvDot, dCvDot_dCv
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, phase, constituent
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_vacancy_phenoplasticity_instance(phase)
|
||||||
|
|
||||||
|
CvDot = &
|
||||||
|
source_vacancy_phenoplasticity_rateCoeff(instance)* &
|
||||||
|
sum(plasticState(phase)%slipRate(:,constituent))
|
||||||
|
dCvDot_dCv = 0.0_pReal
|
||||||
|
|
||||||
|
end subroutine source_vacancy_phenoplasticity_getRateAndItsTangent
|
||||||
|
|
||||||
|
end module source_vacancy_phenoplasticity
|
|
@ -0,0 +1,240 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for vacancy generation due to thermal fluctuations
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module source_vacancy_thermalfluc
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
source_vacancy_thermalfluc_sizePostResults, & !< cumulative size of post results
|
||||||
|
source_vacancy_thermalfluc_offset, & !< which source is my current damage mechanism?
|
||||||
|
source_vacancy_thermalfluc_instance !< instance of damage source mechanism
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_vacancy_thermalfluc_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
source_vacancy_thermalfluc_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
source_vacancy_thermalfluc_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
source_vacancy_thermalfluc_amplitude
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
source_vacancy_thermalfluc_init, &
|
||||||
|
source_vacancy_thermalfluc_deltaState, &
|
||||||
|
source_vacancy_thermalfluc_getRateAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_vacancy_thermalfluc_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use debug, only: &
|
||||||
|
debug_level,&
|
||||||
|
debug_constitutive,&
|
||||||
|
debug_levelBasic
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
phase_Noutput, &
|
||||||
|
SOURCE_vacancy_thermalfluc_label, &
|
||||||
|
SOURCE_vacancy_thermalfluc_ID, &
|
||||||
|
material_Nphase, &
|
||||||
|
material_phase, &
|
||||||
|
sourceState, &
|
||||||
|
MATERIAL_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank, &
|
||||||
|
numerics_integrator
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,phase,instance,source,sourceOffset
|
||||||
|
integer(pInt) :: sizeState, sizeDotState
|
||||||
|
integer(pInt) :: NofMyPhase
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- source_'//SOURCE_vacancy_thermalfluc_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(phase_source == SOURCE_vacancy_thermalfluc_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||||
|
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||||
|
|
||||||
|
allocate(source_vacancy_thermalfluc_offset(material_Nphase), source=0_pInt)
|
||||||
|
allocate(source_vacancy_thermalfluc_instance(material_Nphase), source=0_pInt)
|
||||||
|
do phase = 1, material_Nphase
|
||||||
|
source_vacancy_thermalfluc_instance(phase) = count(phase_source(:,1:phase) == source_vacancy_thermalfluc_ID)
|
||||||
|
do source = 1, phase_Nsources(phase)
|
||||||
|
if (phase_source(source,phase) == source_vacancy_thermalfluc_ID) &
|
||||||
|
source_vacancy_thermalfluc_offset(phase) = source
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
allocate(source_vacancy_thermalfluc_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_vacancy_thermalfluc_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(source_vacancy_thermalfluc_output(maxval(phase_Noutput),maxNinstance))
|
||||||
|
source_vacancy_thermalfluc_output = ''
|
||||||
|
allocate(source_vacancy_thermalfluc_Noutput(maxNinstance), source=0_pInt)
|
||||||
|
allocate(source_vacancy_thermalfluc_amplitude(maxNinstance), source=0.0_pReal)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
phase = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
||||||
|
phase = phase + 1_pInt ! advance phase section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (phase > 0_pInt ) then; if (any(phase_source(:,phase) == SOURCE_vacancy_thermalfluc_ID)) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = source_vacancy_thermalfluc_instance(phase) ! which instance of my vacancy is present phase
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('thermalfluctuation_amplitude')
|
||||||
|
source_vacancy_thermalfluc_amplitude(instance) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
initializeInstances: do phase = 1_pInt, material_Nphase
|
||||||
|
if (any(phase_source(:,phase) == SOURCE_vacancy_thermalfluc_ID)) then
|
||||||
|
NofMyPhase=count(material_phase==phase)
|
||||||
|
instance = source_vacancy_thermalfluc_instance(phase)
|
||||||
|
sourceOffset = source_vacancy_thermalfluc_offset(phase)
|
||||||
|
|
||||||
|
sizeDotState = 1_pInt
|
||||||
|
sizeState = 1_pInt
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeState = sizeState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizeDotState = sizeDotState
|
||||||
|
sourceState(phase)%p(sourceOffset)%sizePostResults = source_vacancy_thermalfluc_sizePostResults(instance)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%aTolState (sizeState), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
||||||
|
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 1_pInt)) then
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
endif
|
||||||
|
if (any(numerics_integrator == 4_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||||
|
if (any(numerics_integrator == 5_pInt)) &
|
||||||
|
allocate(sourceState(phase)%p(sourceOffset)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine source_vacancy_thermalfluc_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates derived quantities from state
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_vacancy_thermalfluc_deltaState(ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< component-ID of integration point
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, constituent, sourceOffset
|
||||||
|
real(pReal) :: &
|
||||||
|
randNo
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
sourceOffset = source_vacancy_thermalfluc_offset(phase)
|
||||||
|
|
||||||
|
call random_number(randNo)
|
||||||
|
sourceState(phase)%p(sourceOffset)%deltaState(1,constituent) = &
|
||||||
|
randNo - sourceState(phase)%p(sourceOffset)%state(1,constituent)
|
||||||
|
|
||||||
|
end subroutine source_vacancy_thermalfluc_deltaState
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns local vacancy generation rate
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine source_vacancy_thermalfluc_getRateAndItsTangent(CvDot, dCvDot_dCv, ipc, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
mappingConstitutive, &
|
||||||
|
sourceState
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ipc, & !< grain number
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
CvDot, dCvDot_dCv
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, phase, constituent, sourceOffset
|
||||||
|
|
||||||
|
phase = mappingConstitutive(2,ipc,ip,el)
|
||||||
|
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||||
|
instance = source_vacancy_thermalfluc_instance(phase)
|
||||||
|
sourceOffset = source_vacancy_thermalfluc_offset(phase)
|
||||||
|
|
||||||
|
CvDot = source_vacancy_thermalfluc_amplitude(instance)*(sourceState(phase)%p(sourceOffset)%state0(2,constituent) - 0.5_pReal)
|
||||||
|
dCvDot_dCv = 0.0_pReal
|
||||||
|
|
||||||
|
end subroutine source_vacancy_thermalfluc_getRateAndItsTangent
|
||||||
|
|
||||||
|
end module source_vacancy_thermalfluc
|
|
@ -2,7 +2,7 @@
|
||||||
! $Id$
|
! $Id$
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @brief material subroutine incoprorating local heat generation due to plastic dissipation
|
!> @brief material subroutine for adiabatic temperature evolution
|
||||||
!> @details to be done
|
!> @details to be done
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module thermal_adiabatic
|
module thermal_adiabatic
|
||||||
|
@ -22,10 +22,7 @@ module thermal_adiabatic
|
||||||
thermal_adiabatic_output !< name of each post result output
|
thermal_adiabatic_output !< name of each post result output
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, target, public :: &
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
thermal_adiabatic_Noutput !< number of outputs per instance of this damage
|
thermal_adiabatic_Noutput !< number of outputs per instance of this thermal model
|
||||||
|
|
||||||
real(pReal), dimension(:), allocatable, public :: &
|
|
||||||
thermal_adiabatic_aTol
|
|
||||||
|
|
||||||
enum, bind(c)
|
enum, bind(c)
|
||||||
enumerator :: undefined_ID, &
|
enumerator :: undefined_ID, &
|
||||||
|
@ -37,14 +34,10 @@ module thermal_adiabatic
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
thermal_adiabatic_init, &
|
thermal_adiabatic_init, &
|
||||||
thermal_adiabatic_stateInit, &
|
thermal_adiabatic_updateState, &
|
||||||
thermal_adiabatic_aTolState, &
|
thermal_adiabatic_getSourceAndItsTangent, &
|
||||||
thermal_adiabatic_microstructure, &
|
thermal_adiabatic_getSpecificHeat, &
|
||||||
thermal_adiabatic_LTAndItsTangent, &
|
thermal_adiabatic_getMassDensity, &
|
||||||
thermal_adiabatic_getTemperature, &
|
|
||||||
thermal_adiabatic_getLocalTemperature, &
|
|
||||||
thermal_adiabatic_putLocalTemperature, &
|
|
||||||
thermal_adiabatic_getHeatGeneration, &
|
|
||||||
thermal_adiabatic_postResults
|
thermal_adiabatic_postResults
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
@ -56,10 +49,6 @@ contains
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine thermal_adiabatic_init(fileUnit,temperature_init)
|
subroutine thermal_adiabatic_init(fileUnit,temperature_init)
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
use debug, only: &
|
|
||||||
debug_level,&
|
|
||||||
debug_constitutive,&
|
|
||||||
debug_levelBasic
|
|
||||||
use IO, only: &
|
use IO, only: &
|
||||||
IO_read, &
|
IO_read, &
|
||||||
IO_lc, &
|
IO_lc, &
|
||||||
|
@ -74,17 +63,20 @@ subroutine thermal_adiabatic_init(fileUnit,temperature_init)
|
||||||
IO_timeStamp, &
|
IO_timeStamp, &
|
||||||
IO_EOF
|
IO_EOF
|
||||||
use material, only: &
|
use material, only: &
|
||||||
phase_thermal, &
|
thermal_type, &
|
||||||
phase_thermalInstance, &
|
thermal_typeInstance, &
|
||||||
phase_Noutput, &
|
homogenization_Noutput, &
|
||||||
LOCAL_THERMAL_ADIABATIC_label, &
|
THERMAL_ADIABATIC_label, &
|
||||||
LOCAL_THERMAL_adiabatic_ID, &
|
THERMAL_adiabatic_ID, &
|
||||||
material_phase, &
|
material_homog, &
|
||||||
|
mappingHomogenization, &
|
||||||
thermalState, &
|
thermalState, &
|
||||||
MATERIAL_partPhase
|
thermalMapping, &
|
||||||
|
temperature, &
|
||||||
|
temperatureRate, &
|
||||||
|
material_partHomogenization
|
||||||
use numerics,only: &
|
use numerics,only: &
|
||||||
worldrank, &
|
worldrank
|
||||||
numerics_integrator
|
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
real(pReal), intent(in) :: temperature_init !< initial temperature
|
real(pReal), intent(in) :: temperature_init !< initial temperature
|
||||||
|
@ -92,54 +84,51 @@ subroutine thermal_adiabatic_init(fileUnit,temperature_init)
|
||||||
|
|
||||||
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,o
|
integer(pInt) :: maxNinstance,mySize=0_pInt,section,instance,o
|
||||||
integer(pInt) :: sizeState, sizeDotState
|
integer(pInt) :: sizeState
|
||||||
integer(pInt) :: NofMyPhase
|
integer(pInt) :: NofMyHomog
|
||||||
character(len=65536) :: &
|
character(len=65536) :: &
|
||||||
tag = '', &
|
tag = '', &
|
||||||
line = ''
|
line = ''
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
mainProcess: if (worldrank == 0) then
|
||||||
write(6,'(/,a)') ' <<<+- thermal_'//LOCAL_THERMAL_ADIABATIC_label//' init -+>>>'
|
write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_ADIABATIC_label//' init -+>>>'
|
||||||
write(6,'(a)') ' $Id$'
|
write(6,'(a)') ' $Id$'
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
#include "compilation_info.f90"
|
#include "compilation_info.f90"
|
||||||
endif mainProcess
|
endif mainProcess
|
||||||
|
|
||||||
maxNinstance = int(count(phase_thermal == LOCAL_THERMAL_adiabatic_ID),pInt)
|
maxNinstance = int(count(thermal_type == THERMAL_adiabatic_ID),pInt)
|
||||||
if (maxNinstance == 0_pInt) return
|
if (maxNinstance == 0_pInt) return
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
|
||||||
|
|
||||||
allocate(thermal_adiabatic_sizePostResults(maxNinstance), source=0_pInt)
|
allocate(thermal_adiabatic_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
allocate(thermal_adiabatic_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
allocate(thermal_adiabatic_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0_pInt)
|
||||||
allocate(thermal_adiabatic_output(maxval(phase_Noutput),maxNinstance))
|
allocate(thermal_adiabatic_output (maxval(homogenization_Noutput),maxNinstance))
|
||||||
thermal_adiabatic_output = ''
|
thermal_adiabatic_output = ''
|
||||||
allocate(thermal_adiabatic_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
allocate(thermal_adiabatic_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID)
|
||||||
allocate(thermal_adiabatic_Noutput(maxNinstance), source=0_pInt)
|
allocate(thermal_adiabatic_Noutput (maxNinstance), source=0_pInt)
|
||||||
allocate(thermal_adiabatic_aTol(maxNinstance), source=0.0_pReal)
|
|
||||||
|
|
||||||
rewind(fileUnit)
|
rewind(fileUnit)
|
||||||
phase = 0_pInt
|
section = 0_pInt
|
||||||
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partHomogenization)! wind forward to <homogenization>
|
||||||
line = IO_read(fileUnit)
|
line = IO_read(fileUnit)
|
||||||
enddo
|
enddo
|
||||||
|
|
||||||
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
line = IO_read(fileUnit)
|
line = IO_read(fileUnit)
|
||||||
if (IO_isBlank(line)) cycle ! skip empty lines
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
line = IO_read(fileUnit, .true.) ! reset IO_read
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
exit
|
exit
|
||||||
endif
|
endif
|
||||||
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
phase = phase + 1_pInt ! advance phase section counter
|
section = section + 1_pInt ! advance homog section counter
|
||||||
cycle ! skip to next line
|
cycle ! skip to next line
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if (phase > 0_pInt ) then; if (phase_thermal(phase) == LOCAL_THERMAL_adiabatic_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
if (section > 0_pInt ) then; if (thermal_type(section) == THERMAL_adiabatic_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
instance = phase_thermalInstance(phase) ! which instance of my thermal is present phase
|
instance = thermal_typeInstance(section) ! which instance of my thermal is present homog
|
||||||
positions = IO_stringPos(line,MAXNCHUNKS)
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
select case(tag)
|
select case(tag)
|
||||||
|
@ -152,17 +141,14 @@ subroutine thermal_adiabatic_init(fileUnit,temperature_init)
|
||||||
IO_lc(IO_stringValue(line,positions,2_pInt))
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
end select
|
end select
|
||||||
|
|
||||||
case ('atol_adiabatic')
|
|
||||||
thermal_adiabatic_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
end select
|
end select
|
||||||
endif; endif
|
endif; endif
|
||||||
enddo parsingFile
|
enddo parsingFile
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_thermal)
|
initializeInstances: do section = 1_pInt, size(thermal_type)
|
||||||
if (phase_thermal(phase) == LOCAL_THERMAL_adiabatic_ID) then
|
if (thermal_type(section) == THERMAL_adiabatic_ID) then
|
||||||
NofMyPhase=count(material_phase==phase)
|
NofMyHomog=count(material_homog==section)
|
||||||
instance = phase_thermalInstance(phase)
|
instance = thermal_typeInstance(section)
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! Determine size of postResults array
|
! Determine size of postResults array
|
||||||
|
@ -177,280 +163,243 @@ subroutine thermal_adiabatic_init(fileUnit,temperature_init)
|
||||||
thermal_adiabatic_sizePostResults(instance) = thermal_adiabatic_sizePostResults(instance) + mySize
|
thermal_adiabatic_sizePostResults(instance) = thermal_adiabatic_sizePostResults(instance) + mySize
|
||||||
endif
|
endif
|
||||||
enddo outputsLoop
|
enddo outputsLoop
|
||||||
! Determine size of state array
|
|
||||||
sizeDotState = 0_pInt
|
|
||||||
sizeState = 1_pInt
|
|
||||||
thermalState(phase)%sizeState = sizeState
|
|
||||||
thermalState(phase)%sizeDotState = sizeDotState
|
|
||||||
thermalState(phase)%sizePostResults = thermal_adiabatic_sizePostResults(instance)
|
|
||||||
allocate(thermalState(phase)%aTolState (sizeState), source=0.0_pReal)
|
|
||||||
allocate(thermalState(phase)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(thermalState(phase)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(thermalState(phase)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(thermalState(phase)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(thermalState(phase)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
|
|
||||||
allocate(thermalState(phase)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
! allocate state arrays
|
||||||
allocate(thermalState(phase)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
sizeState = 1_pInt
|
||||||
allocate(thermalState(phase)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
thermalState(section)%sizeState = sizeState
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
thermalState(section)%sizePostResults = thermal_adiabatic_sizePostResults(instance)
|
||||||
allocate(thermalState(phase)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
allocate(thermalState(section)%state0 (sizeState,NofMyHomog), source=temperature_init)
|
||||||
allocate(thermalState(phase)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
allocate(thermalState(section)%subState0(sizeState,NofMyHomog), source=temperature_init)
|
||||||
endif
|
allocate(thermalState(section)%state (sizeState,NofMyHomog), source=temperature_init)
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(thermalState(phase)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
nullify(thermalMapping(section)%p)
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
thermalMapping(section)%p => mappingHomogenization(1,:,:)
|
||||||
allocate(thermalState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
deallocate(temperature(section)%p)
|
||||||
|
temperature(section)%p => thermalState(section)%state(1,:)
|
||||||
|
deallocate(temperatureRate(section)%p)
|
||||||
|
allocate (temperatureRate(section)%p(NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
call thermal_adiabatic_stateInit(phase,temperature_init)
|
|
||||||
call thermal_adiabatic_aTolState(phase,instance)
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
enddo initializeInstances
|
enddo initializeInstances
|
||||||
end subroutine thermal_adiabatic_init
|
end subroutine thermal_adiabatic_init
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief sets the relevant NEW state values for a given instance of this thermal
|
!> @brief calculates adiabatic change in temperature based on local heat generation model
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine thermal_adiabatic_stateInit(phase,temperature_init)
|
function thermal_adiabatic_updateState(subdt, ip, el)
|
||||||
use material, only: &
|
use numerics, only: &
|
||||||
thermalState
|
err_thermal_tolAbs, &
|
||||||
|
err_thermal_tolRel
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: phase !< number specifying the phase of the thermal
|
|
||||||
real(pReal), intent(in) :: temperature_init !< initial temperature
|
|
||||||
|
|
||||||
real(pReal), dimension(thermalState(phase)%sizeState) :: tempState
|
|
||||||
|
|
||||||
tempState(1) = temperature_init
|
|
||||||
thermalState(phase)%state = spread(tempState,2,size(thermalState(phase)%state(1,:)))
|
|
||||||
thermalState(phase)%state0 = thermalState(phase)%state
|
|
||||||
thermalState(phase)%partionedState0 = thermalState(phase)%state
|
|
||||||
end subroutine thermal_adiabatic_stateInit
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this thermal
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine thermal_adiabatic_aTolState(phase,instance)
|
|
||||||
use material, only: &
|
|
||||||
thermalState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
phase, &
|
|
||||||
instance ! number specifying the current instance of the thermal
|
|
||||||
real(pReal), dimension(thermalState(phase)%sizeState) :: tempTol
|
|
||||||
|
|
||||||
tempTol = thermal_adiabatic_aTol(instance)
|
|
||||||
thermalState(phase)%aTolState = tempTol
|
|
||||||
end subroutine thermal_adiabatic_aTolState
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief calculates derived quantities from state
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine thermal_adiabatic_microstructure(Tstar_v, Lp, subdt, ipc, ip, el)
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_massDensity, &
|
|
||||||
lattice_specificHeat
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
thermalState
|
|
||||||
use math, only: &
|
|
||||||
math_Mandel6to33
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in), dimension(6) :: &
|
|
||||||
Tstar_v !< 2nd Piola-Kirchhoff stress
|
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
|
||||||
Lp !< plastic velocity gradient
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
subdt
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, &
|
|
||||||
constituent
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
|
|
||||||
thermalState(phase)%state(1,constituent) = &
|
|
||||||
thermalState(phase)%subState0(1,constituent) + &
|
|
||||||
subdt* &
|
|
||||||
0.95_pReal*sum(abs(math_Mandel6to33(Tstar_v))*Lp)/ &
|
|
||||||
(lattice_massDensity(phase)*lattice_specificHeat(phase))
|
|
||||||
|
|
||||||
end subroutine thermal_adiabatic_microstructure
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief contains the constitutive equation for calculating the velocity gradient
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine thermal_adiabatic_LTAndItsTangent(LT, dLT_dTstar3333, Tstar_v, Lp, ipc, ip, el)
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_massDensity, &
|
|
||||||
lattice_specificHeat, &
|
|
||||||
lattice_thermalExpansion33
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive
|
|
||||||
use math, only: &
|
|
||||||
math_Plain3333to99, &
|
|
||||||
math_Mandel6to33
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in), dimension(6) :: &
|
|
||||||
Tstar_v !< 2nd Piola-Kirchhoff stress
|
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
|
||||||
Lp !< plastic velocity gradient
|
|
||||||
real(pReal), intent(out), dimension(3,3) :: &
|
|
||||||
LT !< thermal velocity gradient
|
|
||||||
real(pReal), intent(out), dimension(3,3,3,3) :: &
|
|
||||||
dLT_dTstar3333 !< derivative of LT with respect to Tstar (4th-order tensor)
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, &
|
|
||||||
constituent, &
|
|
||||||
i, j, k, l
|
|
||||||
real(pReal) :: &
|
|
||||||
Tdot
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
|
|
||||||
Tdot = 0.95_pReal &
|
|
||||||
* sum(abs(math_Mandel6to33(Tstar_v))*Lp) &
|
|
||||||
/ (lattice_massDensity(phase)*lattice_specificHeat(phase))
|
|
||||||
|
|
||||||
LT = Tdot*lattice_thermalExpansion33(1:3,1:3,phase)
|
|
||||||
dLT_dTstar3333 = 0.0_pReal
|
|
||||||
forall (i=1_pInt:3_pInt,j=1_pInt:3_pInt,k=1_pInt:3_pInt,l=1_pInt:3_pInt) &
|
|
||||||
dLT_dTstar3333(i,j,k,l) = Lp(k,l)*lattice_thermalExpansion33(i,j,phase)
|
|
||||||
|
|
||||||
dLT_dTstar3333 = 0.95_pReal*dLT_dTstar3333/(lattice_massDensity(phase)*lattice_specificHeat(phase))
|
|
||||||
|
|
||||||
end subroutine thermal_adiabatic_LTAndItsTangent
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns temperature based on local damage model state layout
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function thermal_adiabatic_getTemperature(ipc, ip, el)
|
|
||||||
use material, only: &
|
use material, only: &
|
||||||
mappingHomogenization, &
|
mappingHomogenization, &
|
||||||
fieldThermal, &
|
thermalState, &
|
||||||
field_thermal_type, &
|
temperature, &
|
||||||
FIELD_THERMAL_nonlocal_ID, &
|
temperatureRate, &
|
||||||
material_homog, &
|
thermalMapping
|
||||||
mappingConstitutive, &
|
|
||||||
thermalState
|
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
integer(pInt), intent(in) :: &
|
integer(pInt), intent(in) :: &
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: thermal_adiabatic_getTemperature
|
|
||||||
|
|
||||||
select case(field_thermal_type(material_homog(ip,el)))
|
|
||||||
case (FIELD_THERMAL_nonlocal_ID)
|
|
||||||
thermal_adiabatic_getTemperature = fieldThermal(material_homog(ip,el))% &
|
|
||||||
field(1,mappingHomogenization(1,ip,el)) ! Taylor type
|
|
||||||
|
|
||||||
case default
|
|
||||||
thermal_adiabatic_getTemperature = thermalState(mappingConstitutive(2,ipc,ip,el))% &
|
|
||||||
state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
end select
|
|
||||||
|
|
||||||
end function thermal_adiabatic_getTemperature
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns temperature based on local damage model state layout
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function thermal_adiabatic_getLocalTemperature(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
ThermalState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: &
|
|
||||||
thermal_adiabatic_getLocalTemperature
|
|
||||||
|
|
||||||
thermal_adiabatic_getLocalTemperature = &
|
|
||||||
thermalState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
end function thermal_adiabatic_getLocalTemperature
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns temperature based on local damage model state layout
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine thermal_adiabatic_putLocalTemperature(ipc, ip, el, localTemperature)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
ThermalState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
ip, & !< integration point number
|
||||||
el !< element number
|
el !< element number
|
||||||
real(pReal), intent(in) :: &
|
real(pReal), intent(in) :: &
|
||||||
localTemperature
|
subdt
|
||||||
|
logical, dimension(2) :: &
|
||||||
|
thermal_adiabatic_updateState
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
offset
|
||||||
|
real(pReal) :: &
|
||||||
|
T, Tdot, dTdot_dT
|
||||||
|
|
||||||
thermalState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))= &
|
homog = mappingHomogenization(2,ip,el)
|
||||||
localTemperature
|
offset = mappingHomogenization(1,ip,el)
|
||||||
|
|
||||||
end subroutine thermal_adiabatic_putLocalTemperature
|
T = thermalState(homog)%subState0(1,offset)
|
||||||
|
call thermal_adiabatic_getSourceAndItsTangent(Tdot, dTdot_dT, T, ip, el)
|
||||||
|
T = T + subdt*thermal_adiabatic_getSpecificHeat(ip,el)*thermal_adiabatic_getMassDensity(ip,el)*Tdot
|
||||||
|
|
||||||
|
thermal_adiabatic_updateState = [ abs(T - thermalState(homog)%state(1,offset)) &
|
||||||
|
<= err_thermal_tolAbs &
|
||||||
|
.or. abs(T - thermalState(homog)%state(1,offset)) &
|
||||||
|
<= err_thermal_tolRel*abs(thermalState(homog)%state(1,offset)), &
|
||||||
|
.true.]
|
||||||
|
|
||||||
|
temperature (homog)%p(thermalMapping(homog)%p(ip,el)) = T
|
||||||
|
temperatureRate(homog)%p(thermalMapping(homog)%p(ip,el)) = &
|
||||||
|
(thermalState(homog)%state(1,offset) - thermalState(homog)%subState0(1,offset))/subdt
|
||||||
|
|
||||||
|
end function thermal_adiabatic_updateState
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief returns heat generation rate
|
!> @brief returns heat generation rate
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
pure function thermal_adiabatic_getHeatGeneration(Tstar_v, Lp)
|
subroutine thermal_adiabatic_getSourceAndItsTangent(Tdot, dTdot_dT, T, ip, el)
|
||||||
use math, only: &
|
use math, only: &
|
||||||
math_Mandel6to33
|
math_Mandel6to33
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
mappingConstitutive, &
|
||||||
|
thermal_typeInstance, &
|
||||||
|
phase_Nsources, &
|
||||||
|
phase_source, &
|
||||||
|
SOURCE_thermal_dissipation_ID
|
||||||
|
use source_thermal_dissipation, only: &
|
||||||
|
source_thermal_dissipation_getRateAndItsTangent
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_Tstar_v, &
|
||||||
|
crystallite_Lp
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
real(pReal), intent(in), dimension(6) :: &
|
integer(pInt), intent(in) :: &
|
||||||
Tstar_v !< 2nd Piola-Kirchhoff stress
|
ip, & !< integration point number
|
||||||
real(pReal), intent(in), dimension(3,3) :: &
|
el !< element number
|
||||||
Lp !< plastic velocity gradient
|
real(pReal), intent(in) :: &
|
||||||
real(pReal) :: thermal_adiabatic_getHeatGeneration
|
T
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
Tdot, dTdot_dT
|
||||||
|
real(pReal) :: &
|
||||||
|
my_Tdot, my_dTdot_dT
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
homog, &
|
||||||
|
offset, &
|
||||||
|
instance, &
|
||||||
|
grain, &
|
||||||
|
source
|
||||||
|
|
||||||
thermal_adiabatic_getHeatGeneration = 0.95_pReal &
|
homog = mappingHomogenization(2,ip,el)
|
||||||
* sum(abs(math_Mandel6to33(Tstar_v))*Lp)
|
offset = mappingHomogenization(1,ip,el)
|
||||||
|
instance = thermal_typeInstance(homog)
|
||||||
|
|
||||||
end function thermal_adiabatic_getHeatGeneration
|
Tdot = 0.0_pReal
|
||||||
|
dTdot_dT = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(homog)
|
||||||
|
phase = mappingConstitutive(2,grain,ip,el)
|
||||||
|
do source = 1, phase_Nsources(phase)
|
||||||
|
select case(phase_source(source,phase))
|
||||||
|
case (SOURCE_thermal_dissipation_ID)
|
||||||
|
call source_thermal_dissipation_getRateAndItsTangent(my_Tdot, my_dTdot_dT, &
|
||||||
|
crystallite_Tstar_v(1:6,grain,ip,el), &
|
||||||
|
crystallite_Lp(1:3,1:3,grain,ip,el), &
|
||||||
|
grain, ip, el)
|
||||||
|
|
||||||
|
case default
|
||||||
|
my_Tdot = 0.0_pReal
|
||||||
|
my_dTdot_dT = 0.0_pReal
|
||||||
|
end select
|
||||||
|
Tdot = Tdot + my_Tdot
|
||||||
|
dTdot_dT = dTdot_dT + my_dTdot_dT
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
Tdot = Tdot/homogenization_Ngrains(homog)
|
||||||
|
dTdot_dT = dTdot_dT/homogenization_Ngrains(homog)
|
||||||
|
|
||||||
|
end subroutine thermal_adiabatic_getSourceAndItsTangent
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief return array of constitutive results
|
!> @brief returns homogenized specific heat capacity
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
function thermal_adiabatic_postResults(ipc,ip,el)
|
function thermal_adiabatic_getSpecificHeat(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_specificHeat
|
||||||
use material, only: &
|
use material, only: &
|
||||||
mappingConstitutive, &
|
homogenization_Ngrains, &
|
||||||
phase_thermalInstance, &
|
mappingHomogenization, &
|
||||||
thermalState
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal) :: &
|
||||||
|
thermal_adiabatic_getSpecificHeat
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, grain
|
||||||
|
|
||||||
|
thermal_adiabatic_getSpecificHeat = 0.0_pReal
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
thermal_adiabatic_getSpecificHeat = thermal_adiabatic_getSpecificHeat + &
|
||||||
|
lattice_specificHeat(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
thermal_adiabatic_getSpecificHeat = &
|
||||||
|
thermal_adiabatic_getSpecificHeat/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function thermal_adiabatic_getSpecificHeat
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized mass density
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function thermal_adiabatic_getMassDensity(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_massDensity
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal) :: &
|
||||||
|
thermal_adiabatic_getMassDensity
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, grain
|
||||||
|
|
||||||
|
thermal_adiabatic_getMassDensity = 0.0_pReal
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
thermal_adiabatic_getMassDensity = thermal_adiabatic_getMassDensity + &
|
||||||
|
lattice_massDensity(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
thermal_adiabatic_getMassDensity = &
|
||||||
|
thermal_adiabatic_getMassDensity/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function thermal_adiabatic_getMassDensity
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of thermal results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function thermal_adiabatic_postResults(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
thermal_typeInstance, &
|
||||||
|
thermalMapping, &
|
||||||
|
temperature
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
integer(pInt), intent(in) :: &
|
integer(pInt), intent(in) :: &
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
ip, & !< integration point
|
||||||
el !< element
|
el !< element
|
||||||
real(pReal), dimension(thermal_adiabatic_sizePostResults(phase_thermalInstance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
real(pReal), dimension(thermal_adiabatic_sizePostResults(thermal_typeInstance(mappingHomogenization(2,ip,el)))) :: &
|
||||||
thermal_adiabatic_postResults
|
thermal_adiabatic_postResults
|
||||||
|
|
||||||
integer(pInt) :: &
|
integer(pInt) :: &
|
||||||
instance, phase, constituent, o, c
|
instance, homog, offset, o, c
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
homog = mappingHomogenization(2,ip,el)
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
offset = thermalMapping(homog)%p(ip,el)
|
||||||
instance = phase_thermalInstance(phase)
|
instance = thermal_typeInstance(homog)
|
||||||
|
|
||||||
c = 0_pInt
|
c = 0_pInt
|
||||||
thermal_adiabatic_postResults = 0.0_pReal
|
thermal_adiabatic_postResults = 0.0_pReal
|
||||||
|
@ -459,7 +408,7 @@ function thermal_adiabatic_postResults(ipc,ip,el)
|
||||||
select case(thermal_adiabatic_outputID(o,instance))
|
select case(thermal_adiabatic_outputID(o,instance))
|
||||||
|
|
||||||
case (temperature_ID)
|
case (temperature_ID)
|
||||||
thermal_adiabatic_postResults(c+1_pInt) = thermalState(phase)%state(1,constituent)
|
thermal_adiabatic_postResults(c+1_pInt) = temperature(homog)%p(offset)
|
||||||
c = c + 1
|
c = c + 1
|
||||||
end select
|
end select
|
||||||
enddo
|
enddo
|
||||||
|
|
|
@ -0,0 +1,439 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for temperature evolution from heat conduction
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module thermal_conduction
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
thermal_conduction_sizePostResults !< cumulative size of post results
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
thermal_conduction_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
thermal_conduction_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
thermal_conduction_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
temperature_ID
|
||||||
|
end enum
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
thermal_conduction_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
thermal_conduction_init, &
|
||||||
|
thermal_conduction_getSourceAndItsTangent, &
|
||||||
|
thermal_conduction_getConductivity33, &
|
||||||
|
thermal_conduction_getSpecificHeat, &
|
||||||
|
thermal_conduction_getMassDensity, &
|
||||||
|
thermal_conduction_putTemperatureAndItsRate, &
|
||||||
|
thermal_conduction_postResults
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine thermal_conduction_init(fileUnit,temperature_init)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
thermal_type, &
|
||||||
|
thermal_typeInstance, &
|
||||||
|
homogenization_Noutput, &
|
||||||
|
THERMAL_conduction_label, &
|
||||||
|
THERMAL_conduction_ID, &
|
||||||
|
material_homog, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
thermalState, &
|
||||||
|
thermalMapping, &
|
||||||
|
temperature, &
|
||||||
|
temperatureRate, &
|
||||||
|
material_partHomogenization
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
real(pReal), intent(in) :: temperature_init !< initial temperature
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,section,instance,o
|
||||||
|
integer(pInt) :: sizeState
|
||||||
|
integer(pInt) :: NofMyHomog
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_CONDUCTION_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(thermal_type == THERMAL_conduction_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
allocate(thermal_conduction_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(thermal_conduction_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(thermal_conduction_output (maxval(homogenization_Noutput),maxNinstance))
|
||||||
|
thermal_conduction_output = ''
|
||||||
|
allocate(thermal_conduction_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID)
|
||||||
|
allocate(thermal_conduction_Noutput (maxNinstance), source=0_pInt)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
section = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partHomogenization)! wind forward to <homogenization>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
|
section = section + 1_pInt ! advance homog section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (section > 0_pInt ) then; if (thermal_type(section) == THERMAL_conduction_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = thermal_typeInstance(section) ! which instance of my thermal is present homog
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('temperature')
|
||||||
|
thermal_conduction_Noutput(instance) = thermal_conduction_Noutput(instance) + 1_pInt
|
||||||
|
thermal_conduction_outputID(thermal_conduction_Noutput(instance),instance) = temperature_ID
|
||||||
|
thermal_conduction_output(thermal_conduction_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
initializeInstances: do section = 1_pInt, size(thermal_type)
|
||||||
|
if (thermal_type(section) == THERMAL_conduction_ID) then
|
||||||
|
NofMyHomog=count(material_homog==section)
|
||||||
|
instance = thermal_typeInstance(section)
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,thermal_conduction_Noutput(instance)
|
||||||
|
select case(thermal_conduction_outputID(o,instance))
|
||||||
|
case(temperature_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
thermal_conduction_sizePostResult(o,instance) = mySize
|
||||||
|
thermal_conduction_sizePostResults(instance) = thermal_conduction_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
|
||||||
|
! allocate state arrays
|
||||||
|
sizeState = 0_pInt
|
||||||
|
thermalState(section)%sizeState = sizeState
|
||||||
|
thermalState(section)%sizePostResults = thermal_conduction_sizePostResults(instance)
|
||||||
|
allocate(thermalState(section)%state0 (sizeState,NofMyHomog))
|
||||||
|
allocate(thermalState(section)%subState0(sizeState,NofMyHomog))
|
||||||
|
allocate(thermalState(section)%state (sizeState,NofMyHomog))
|
||||||
|
|
||||||
|
nullify(thermalMapping(section)%p)
|
||||||
|
thermalMapping(section)%p => mappingHomogenization(1,:,:)
|
||||||
|
deallocate(temperature (section)%p)
|
||||||
|
allocate (temperature (section)%p(NofMyHomog), source=temperature_init)
|
||||||
|
deallocate(temperatureRate(section)%p)
|
||||||
|
allocate (temperatureRate(section)%p(NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine thermal_conduction_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns heat generation rate
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine thermal_conduction_getSourceAndItsTangent(Tdot, dTdot_dT, T, ip, el)
|
||||||
|
use math, only: &
|
||||||
|
math_Mandel6to33
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
mappingConstitutive, &
|
||||||
|
thermal_typeInstance, &
|
||||||
|
phase_Nsources, &
|
||||||
|
phase_source, &
|
||||||
|
SOURCE_thermal_dissipation_ID
|
||||||
|
use source_thermal_dissipation, only: &
|
||||||
|
source_thermal_dissipation_getRateAndItsTangent
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_Tstar_v, &
|
||||||
|
crystallite_Lp
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
T
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
Tdot, dTdot_dT
|
||||||
|
real(pReal) :: &
|
||||||
|
my_Tdot, my_dTdot_dT
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
homog, &
|
||||||
|
offset, &
|
||||||
|
instance, &
|
||||||
|
grain, &
|
||||||
|
source
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = mappingHomogenization(1,ip,el)
|
||||||
|
instance = thermal_typeInstance(homog)
|
||||||
|
|
||||||
|
Tdot = 0.0_pReal
|
||||||
|
dTdot_dT = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(homog)
|
||||||
|
phase = mappingConstitutive(2,grain,ip,el)
|
||||||
|
do source = 1, phase_Nsources(phase)
|
||||||
|
select case(phase_source(source,phase))
|
||||||
|
case (SOURCE_thermal_dissipation_ID)
|
||||||
|
call source_thermal_dissipation_getRateAndItsTangent(my_Tdot, my_dTdot_dT, &
|
||||||
|
crystallite_Tstar_v(1:6,grain,ip,el), &
|
||||||
|
crystallite_Lp(1:3,1:3,grain,ip,el), &
|
||||||
|
grain, ip, el)
|
||||||
|
|
||||||
|
case default
|
||||||
|
my_Tdot = 0.0_pReal
|
||||||
|
my_dTdot_dT = 0.0_pReal
|
||||||
|
|
||||||
|
end select
|
||||||
|
Tdot = Tdot + my_Tdot
|
||||||
|
dTdot_dT = dTdot_dT + my_dTdot_dT
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
Tdot = Tdot/homogenization_Ngrains(homog)
|
||||||
|
dTdot_dT = dTdot_dT/homogenization_Ngrains(homog)
|
||||||
|
|
||||||
|
end subroutine thermal_conduction_getSourceAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized thermal conductivity in reference configuration
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function thermal_conduction_getConductivity33(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_thermalConductivity33
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), dimension(3,3) :: &
|
||||||
|
thermal_conduction_getConductivity33
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
grain
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
|
||||||
|
thermal_conduction_getConductivity33 = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
thermal_conduction_getConductivity33 = thermal_conduction_getConductivity33 + &
|
||||||
|
crystallite_push33ToRef(grain,ip,el,lattice_thermalConductivity33(:,:,material_phase(grain,ip,el)))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
thermal_conduction_getConductivity33 = &
|
||||||
|
thermal_conduction_getConductivity33/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function thermal_conduction_getConductivity33
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized specific heat capacity
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function thermal_conduction_getSpecificHeat(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_specificHeat
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal) :: &
|
||||||
|
thermal_conduction_getSpecificHeat
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, grain
|
||||||
|
|
||||||
|
thermal_conduction_getSpecificHeat = 0.0_pReal
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
thermal_conduction_getSpecificHeat = thermal_conduction_getSpecificHeat + &
|
||||||
|
lattice_specificHeat(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
thermal_conduction_getSpecificHeat = &
|
||||||
|
thermal_conduction_getSpecificHeat/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function thermal_conduction_getSpecificHeat
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized mass density
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function thermal_conduction_getMassDensity(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_massDensity
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal) :: &
|
||||||
|
thermal_conduction_getMassDensity
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, grain
|
||||||
|
|
||||||
|
thermal_conduction_getMassDensity = 0.0_pReal
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
thermal_conduction_getMassDensity = thermal_conduction_getMassDensity + &
|
||||||
|
lattice_massDensity(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
thermal_conduction_getMassDensity = &
|
||||||
|
thermal_conduction_getMassDensity/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function thermal_conduction_getMassDensity
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief updates thermal state with solution from heat conduction PDE
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine thermal_conduction_putTemperatureAndItsRate(T,Tdot,ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
temperature, &
|
||||||
|
temperatureRate, &
|
||||||
|
thermalMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
T, &
|
||||||
|
Tdot
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
offset
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = thermalMapping(homog)%p(ip,el)
|
||||||
|
temperature (homog)%p(offset) = T
|
||||||
|
temperatureRate(homog)%p(offset) = Tdot
|
||||||
|
|
||||||
|
end subroutine thermal_conduction_putTemperatureAndItsRate
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of thermal results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function thermal_conduction_postResults(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
thermal_typeInstance, &
|
||||||
|
temperature, &
|
||||||
|
thermalMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(thermal_conduction_sizePostResults(thermal_typeInstance(mappingHomogenization(2,ip,el)))) :: &
|
||||||
|
thermal_conduction_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, homog, offset, o, c
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = thermalMapping(homog)%p(ip,el)
|
||||||
|
instance = thermal_typeInstance(homog)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
thermal_conduction_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,thermal_conduction_Noutput(instance)
|
||||||
|
select case(thermal_conduction_outputID(o,instance))
|
||||||
|
|
||||||
|
case (temperature_ID)
|
||||||
|
thermal_conduction_postResults(c+1_pInt) = temperature(homog)%p(offset)
|
||||||
|
c = c + 1
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function thermal_conduction_postResults
|
||||||
|
|
||||||
|
end module thermal_conduction
|
|
@ -1,107 +1,66 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
! $Id$
|
! $Id$
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
!> @brief material subroutine for isothermal temperature field
|
||||||
!> @brief material subroutine for purely elastic material
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
module thermal_isothermal
|
module thermal_isothermal
|
||||||
use prec, only: &
|
|
||||||
pInt, &
|
|
||||||
pReal
|
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
private
|
private
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
|
||||||
thermal_isothermal_sizePostResults
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
|
||||||
thermal_isothermal_sizePostResult !< size of each post result output
|
|
||||||
|
|
||||||
real(pReal), dimension(:), allocatable, public :: &
|
|
||||||
thermal_isothermal_temperature
|
|
||||||
|
|
||||||
public :: &
|
public :: &
|
||||||
thermal_isothermal_init
|
thermal_isothermal_init
|
||||||
|
|
||||||
contains
|
contains
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
!> @brief module initialization
|
!> @brief allocates all neccessary fields, reads information from material configuration file
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
!--------------------------------------------------------------------------------------------------
|
||||||
subroutine thermal_isothermal_init(temperature_init)
|
subroutine thermal_isothermal_init(temperature_init)
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
use debug, only: &
|
use prec, only: &
|
||||||
debug_level, &
|
pReal, &
|
||||||
debug_constitutive, &
|
pInt
|
||||||
debug_levelBasic
|
|
||||||
use IO, only: &
|
use IO, only: &
|
||||||
IO_timeStamp
|
IO_timeStamp
|
||||||
|
use material
|
||||||
use numerics, only: &
|
use numerics, only: &
|
||||||
worldrank, &
|
worldrank
|
||||||
numerics_integrator
|
|
||||||
use material, only: &
|
|
||||||
phase_thermal, &
|
|
||||||
LOCAL_THERMAL_ISOTHERMAL_label, &
|
|
||||||
LOCAL_THERMAL_ISOTHERMAL_ID, &
|
|
||||||
material_phase, &
|
|
||||||
thermalState, &
|
|
||||||
MATERIAL_partPhase
|
|
||||||
|
|
||||||
implicit none
|
implicit none
|
||||||
|
|
||||||
real(pReal), intent(in) :: temperature_init !< initial temperature
|
real(pReal), intent(in) :: temperature_init !< initial temperature
|
||||||
integer(pInt) :: &
|
integer(pInt) :: &
|
||||||
maxNinstance, &
|
homog, &
|
||||||
phase, &
|
NofMyHomog, &
|
||||||
NofMyPhase, &
|
sizeState
|
||||||
sizeState, &
|
|
||||||
sizeDotState
|
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
mainProcess: if (worldrank == 0) then
|
||||||
write(6,'(/,a)') ' <<<+- thermal_'//LOCAL_THERMAL_ISOTHERMAL_label//' init -+>>>'
|
write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_isothermal_label//' init -+>>>'
|
||||||
write(6,'(a)') ' $Id$'
|
write(6,'(a)') ' $Id$'
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
#include "compilation_info.f90"
|
#include "compilation_info.f90"
|
||||||
endif mainProcess
|
endif mainProcess
|
||||||
|
|
||||||
maxNinstance = int(count(phase_thermal == LOCAL_THERMAL_ISOTHERMAL_ID),pInt)
|
initializeInstances: do homog = 1_pInt, material_Nhomogenization
|
||||||
if (maxNinstance == 0_pInt) return
|
|
||||||
|
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
myhomog: if (thermal_type(homog) == THERMAL_isothermal_ID) then
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
NofMyHomog = count(material_homog == homog)
|
||||||
|
sizeState = 0_pInt
|
||||||
|
thermalState(homog)%sizeState = sizeState
|
||||||
|
thermalState(homog)%sizePostResults = sizeState
|
||||||
|
allocate(thermalState(homog)%state0 (sizeState,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(thermalState(homog)%subState0(sizeState,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(thermalState(homog)%state (sizeState,NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_thermal)
|
deallocate(temperature (homog)%p)
|
||||||
NofMyPhase=count(material_phase==phase)
|
allocate (temperature (homog)%p(1), source=temperature_init)
|
||||||
|
deallocate(temperatureRate(homog)%p)
|
||||||
|
allocate (temperatureRate(homog)%p(1), source=0.0_pReal)
|
||||||
|
|
||||||
if (phase_thermal(phase) == LOCAL_THERMAL_ISOTHERMAL_ID) then
|
endif myhomog
|
||||||
sizeState = 0_pInt
|
|
||||||
thermalState(phase)%sizeState = sizeState
|
|
||||||
sizeDotState = sizeState
|
|
||||||
thermalState(phase)%sizeDotState = sizeDotState
|
|
||||||
thermalState(phase)%sizePostResults = 0_pInt
|
|
||||||
allocate(thermalState(phase)%state0 (sizeState,NofMyPhase))
|
|
||||||
allocate(thermalState(phase)%partionedState0(sizeState,NofMyPhase))
|
|
||||||
allocate(thermalState(phase)%subState0 (sizeState,NofMyPhase))
|
|
||||||
allocate(thermalState(phase)%state (sizeState,NofMyPhase))
|
|
||||||
allocate(thermalState(phase)%state_backup (sizeState,NofMyPhase))
|
|
||||||
allocate(thermalState(phase)%aTolState (NofMyPhase))
|
|
||||||
allocate(thermalState(phase)%dotState (sizeDotState,NofMyPhase))
|
|
||||||
allocate(thermalState(phase)%dotState_backup(sizeDotState,NofMyPhase))
|
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
|
||||||
allocate(thermalState(phase)%previousDotState (sizeDotState,NofMyPhase))
|
|
||||||
allocate(thermalState(phase)%previousDotState2 (sizeDotState,NofMyPhase))
|
|
||||||
endif
|
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(thermalState(phase)%RK4dotState (sizeDotState,NofMyPhase))
|
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
|
||||||
allocate(thermalState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase))
|
|
||||||
endif
|
|
||||||
enddo initializeInstances
|
enddo initializeInstances
|
||||||
allocate(thermal_isothermal_sizePostResults(maxNinstance), source=0_pInt)
|
|
||||||
allocate(thermal_isothermal_temperature(maxNinstance), source=temperature_init)
|
|
||||||
|
|
||||||
end subroutine thermal_isothermal_init
|
end subroutine thermal_isothermal_init
|
||||||
|
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! $Id$
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @brief material subroutine for constant vacancy concentration
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module vacancy_constant
|
|
||||||
use prec, only: &
|
|
||||||
pInt
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
private
|
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
|
||||||
vacancy_constant_sizePostResults
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
|
||||||
vacancy_constant_sizePostResult !< size of each post result output
|
|
||||||
|
|
||||||
public :: &
|
|
||||||
vacancy_constant_init
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief module initialization
|
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine vacancy_constant_init
|
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
|
||||||
use debug, only: &
|
|
||||||
debug_level, &
|
|
||||||
debug_constitutive, &
|
|
||||||
debug_levelBasic
|
|
||||||
use IO, only: &
|
|
||||||
IO_timeStamp
|
|
||||||
use numerics, only: &
|
|
||||||
worldrank, &
|
|
||||||
numerics_integrator
|
|
||||||
use material, only: &
|
|
||||||
phase_vacancy, &
|
|
||||||
LOCAL_VACANCY_CONSTANT_label, &
|
|
||||||
LOCAL_VACANCY_CONSTANT_ID, &
|
|
||||||
material_phase, &
|
|
||||||
vacancyState, &
|
|
||||||
MATERIAL_partPhase
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
|
|
||||||
integer(pInt) :: &
|
|
||||||
maxNinstance, &
|
|
||||||
phase, &
|
|
||||||
NofMyPhase, &
|
|
||||||
sizeState, &
|
|
||||||
sizeDotState
|
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
|
||||||
write(6,'(/,a)') ' <<<+- vacancy_'//LOCAL_VACANCY_CONSTANT_label//' init -+>>>'
|
|
||||||
write(6,'(a)') ' $Id$'
|
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
|
||||||
#include "compilation_info.f90"
|
|
||||||
endif mainProcess
|
|
||||||
|
|
||||||
maxNinstance = int(count(phase_vacancy == LOCAL_VACANCY_CONSTANT_ID),pInt)
|
|
||||||
if (maxNinstance == 0_pInt) return
|
|
||||||
|
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_vacancy)
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
|
|
||||||
if (phase_vacancy(phase) == LOCAL_VACANCY_CONSTANT_ID) then
|
|
||||||
sizeState = 0_pInt
|
|
||||||
vacancyState(phase)%sizeState = sizeState
|
|
||||||
sizeDotState = sizeState
|
|
||||||
vacancyState(phase)%sizeDotState = sizeDotState
|
|
||||||
vacancyState(phase)%sizePostResults = 0_pInt
|
|
||||||
allocate(vacancyState(phase)%state0 (sizeState,NofMyPhase))
|
|
||||||
allocate(vacancyState(phase)%partionedState0(sizeState,NofMyPhase))
|
|
||||||
allocate(vacancyState(phase)%subState0 (sizeState,NofMyPhase))
|
|
||||||
allocate(vacancyState(phase)%state (sizeState,NofMyPhase))
|
|
||||||
allocate(vacancyState(phase)%state_backup (sizeState,NofMyPhase))
|
|
||||||
allocate(vacancyState(phase)%aTolState (NofMyPhase))
|
|
||||||
allocate(vacancyState(phase)%dotState (sizeDotState,NofMyPhase))
|
|
||||||
allocate(vacancyState(phase)%dotState_backup(sizeDotState,NofMyPhase))
|
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
|
||||||
allocate(vacancyState(phase)%previousDotState (sizeDotState,NofMyPhase))
|
|
||||||
allocate(vacancyState(phase)%previousDotState2 (sizeDotState,NofMyPhase))
|
|
||||||
endif
|
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(vacancyState(phase)%RK4dotState (sizeDotState,NofMyPhase))
|
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
|
||||||
allocate(vacancyState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase))
|
|
||||||
endif
|
|
||||||
enddo initializeInstances
|
|
||||||
allocate(vacancy_constant_sizePostResults(maxNinstance), source=0_pInt)
|
|
||||||
|
|
||||||
end subroutine vacancy_constant_init
|
|
||||||
|
|
||||||
end module vacancy_constant
|
|
|
@ -1,534 +0,0 @@
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! $Id$
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
|
||||||
!> @brief material subroutine for plastically generated vacancy concentrations
|
|
||||||
!> @details to be done
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
module vacancy_generation
|
|
||||||
use prec, only: &
|
|
||||||
pReal, &
|
|
||||||
pInt
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
private
|
|
||||||
integer(pInt), dimension(:), allocatable, public, protected :: &
|
|
||||||
vacancy_generation_sizePostResults !< cumulative size of post results
|
|
||||||
|
|
||||||
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
|
||||||
vacancy_generation_sizePostResult !< size of each post result output
|
|
||||||
|
|
||||||
character(len=64), dimension(:,:), allocatable, target, public :: &
|
|
||||||
vacancy_generation_output !< name of each post result output
|
|
||||||
|
|
||||||
integer(pInt), dimension(:), allocatable, target, public :: &
|
|
||||||
vacancy_generation_Noutput !< number of outputs per instance of this damage
|
|
||||||
|
|
||||||
real(pReal), dimension(:), allocatable, private :: &
|
|
||||||
vacancy_generation_aTol, &
|
|
||||||
vacancy_generation_freq, &
|
|
||||||
vacancy_generation_formationEnergy, &
|
|
||||||
vacancy_generation_specificFormationEnergy, &
|
|
||||||
vacancy_generation_migrationEnergy, &
|
|
||||||
vacancy_generation_diffusionCoeff0, & !< the temperature-independent diffusion coefficient D_0
|
|
||||||
vacancy_generation_atomicVol, &
|
|
||||||
vacancy_generation_surfaceEnergy, &
|
|
||||||
vacancy_generation_plasticityCoeff, &
|
|
||||||
vacancy_generation_kBCoeff
|
|
||||||
|
|
||||||
real(pReal), parameter, private :: &
|
|
||||||
kB = 1.3806488e-23_pReal !< Boltzmann constant in J/Kelvin
|
|
||||||
|
|
||||||
enum, bind(c)
|
|
||||||
enumerator :: undefined_ID, &
|
|
||||||
vacancy_concentration_ID
|
|
||||||
end enum
|
|
||||||
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
|
||||||
vacancy_generation_outputID !< ID of each post result output
|
|
||||||
|
|
||||||
|
|
||||||
public :: &
|
|
||||||
vacancy_generation_init, &
|
|
||||||
vacancy_generation_stateInit, &
|
|
||||||
vacancy_generation_aTolState, &
|
|
||||||
vacancy_generation_microstructure, &
|
|
||||||
vacancy_generation_getLocalConcentration, &
|
|
||||||
vacancy_generation_putLocalConcentration, &
|
|
||||||
vacancy_generation_getConcentration, &
|
|
||||||
vacancy_generation_getVacancyDiffusion33, &
|
|
||||||
vacancy_generation_getVacancyMobility33, &
|
|
||||||
vacancy_generation_getVacancyEnergy, &
|
|
||||||
vacancy_generation_postResults
|
|
||||||
|
|
||||||
contains
|
|
||||||
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief module initialization
|
|
||||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine vacancy_generation_init(fileUnit)
|
|
||||||
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
|
||||||
use debug, only: &
|
|
||||||
debug_level,&
|
|
||||||
debug_constitutive,&
|
|
||||||
debug_levelBasic
|
|
||||||
use mesh, only: &
|
|
||||||
mesh_maxNips, &
|
|
||||||
mesh_NcpElems
|
|
||||||
use IO, only: &
|
|
||||||
IO_read, &
|
|
||||||
IO_lc, &
|
|
||||||
IO_getTag, &
|
|
||||||
IO_isBlank, &
|
|
||||||
IO_stringPos, &
|
|
||||||
IO_stringValue, &
|
|
||||||
IO_floatValue, &
|
|
||||||
IO_intValue, &
|
|
||||||
IO_warning, &
|
|
||||||
IO_error, &
|
|
||||||
IO_timeStamp, &
|
|
||||||
IO_EOF
|
|
||||||
use material, only: &
|
|
||||||
homogenization_maxNgrains, &
|
|
||||||
phase_vacancy, &
|
|
||||||
phase_vacancyInstance, &
|
|
||||||
phase_Noutput, &
|
|
||||||
LOCAL_VACANCY_GENERATION_label, &
|
|
||||||
LOCAL_VACANCY_generation_ID, &
|
|
||||||
material_phase, &
|
|
||||||
vacancyState, &
|
|
||||||
MATERIAL_partPhase
|
|
||||||
use numerics,only: &
|
|
||||||
worldrank, &
|
|
||||||
numerics_integrator
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: fileUnit
|
|
||||||
|
|
||||||
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
|
||||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
|
||||||
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,o
|
|
||||||
integer(pInt) :: sizeState, sizeDotState
|
|
||||||
integer(pInt) :: NofMyPhase
|
|
||||||
character(len=65536) :: &
|
|
||||||
tag = '', &
|
|
||||||
line = ''
|
|
||||||
|
|
||||||
mainProcess: if (worldrank == 0) then
|
|
||||||
write(6,'(/,a)') ' <<<+- vacancy_'//LOCAL_VACANCY_GENERATION_label//' init -+>>>'
|
|
||||||
write(6,'(a)') ' $Id$'
|
|
||||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
|
||||||
#include "compilation_info.f90"
|
|
||||||
endif mainProcess
|
|
||||||
|
|
||||||
maxNinstance = int(count(phase_vacancy == LOCAL_VACANCY_generation_ID),pInt)
|
|
||||||
if (maxNinstance == 0_pInt) return
|
|
||||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
|
||||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
|
||||||
|
|
||||||
allocate(vacancy_generation_sizePostResults(maxNinstance), source=0_pInt)
|
|
||||||
allocate(vacancy_generation_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
|
||||||
allocate(vacancy_generation_output(maxval(phase_Noutput),maxNinstance))
|
|
||||||
vacancy_generation_output = ''
|
|
||||||
allocate(vacancy_generation_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
|
||||||
allocate(vacancy_generation_Noutput(maxNinstance), source=0_pInt)
|
|
||||||
allocate(vacancy_generation_aTol(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(vacancy_generation_freq(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(vacancy_generation_formationEnergy(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(vacancy_generation_specificFormationEnergy(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(vacancy_generation_migrationEnergy(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(vacancy_generation_diffusionCoeff0(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(vacancy_generation_atomicVol(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(vacancy_generation_surfaceEnergy(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(vacancy_generation_plasticityCoeff(maxNinstance), source=0.0_pReal)
|
|
||||||
allocate(vacancy_generation_kBCoeff(maxNinstance), source=0.0_pReal)
|
|
||||||
|
|
||||||
rewind(fileUnit)
|
|
||||||
phase = 0_pInt
|
|
||||||
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
enddo
|
|
||||||
|
|
||||||
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of phase part
|
|
||||||
line = IO_read(fileUnit)
|
|
||||||
if (IO_isBlank(line)) cycle ! skip empty lines
|
|
||||||
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
|
||||||
line = IO_read(fileUnit, .true.) ! reset IO_read
|
|
||||||
exit
|
|
||||||
endif
|
|
||||||
if (IO_getTag(line,'[',']') /= '') then ! next phase section
|
|
||||||
phase = phase + 1_pInt ! advance phase section counter
|
|
||||||
cycle ! skip to next line
|
|
||||||
endif
|
|
||||||
|
|
||||||
if (phase > 0_pInt ) then; if (phase_vacancy(phase) == LOCAL_VACANCY_generation_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
|
||||||
|
|
||||||
instance = phase_vacancyInstance(phase) ! which instance of my vacancy is present phase
|
|
||||||
positions = IO_stringPos(line,MAXNCHUNKS)
|
|
||||||
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
|
||||||
select case(tag)
|
|
||||||
case ('(output)')
|
|
||||||
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
|
||||||
case ('vacancy_concentration')
|
|
||||||
vacancy_generation_Noutput(instance) = vacancy_generation_Noutput(instance) + 1_pInt
|
|
||||||
vacancy_generation_outputID(vacancy_generation_Noutput(instance),instance) = vacancy_concentration_ID
|
|
||||||
vacancy_generation_output(vacancy_generation_Noutput(instance),instance) = &
|
|
||||||
IO_lc(IO_stringValue(line,positions,2_pInt))
|
|
||||||
end select
|
|
||||||
|
|
||||||
case ('atolvacancygeneration')
|
|
||||||
vacancy_generation_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('vacancyformationfreq')
|
|
||||||
vacancy_generation_freq(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('vacancyformationenergy')
|
|
||||||
vacancy_generation_formationEnergy(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('vacancymigrationenergy')
|
|
||||||
vacancy_generation_migrationEnergy(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('vacancydiffusioncoeff0')
|
|
||||||
vacancy_generation_diffusionCoeff0(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('atomicvolume')
|
|
||||||
vacancy_generation_atomicVol(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('surfaceenergy')
|
|
||||||
vacancy_generation_surfaceEnergy(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
case ('vacancyplasticitycoeff')
|
|
||||||
vacancy_generation_plasticityCoeff(instance) = IO_floatValue(line,positions,2_pInt)
|
|
||||||
|
|
||||||
end select
|
|
||||||
endif; endif
|
|
||||||
enddo parsingFile
|
|
||||||
|
|
||||||
initializeInstances: do phase = 1_pInt, size(phase_vacancy)
|
|
||||||
if (phase_vacancy(phase) == LOCAL_VACANCY_generation_ID) then
|
|
||||||
NofMyPhase=count(material_phase==phase)
|
|
||||||
instance = phase_vacancyInstance(phase)
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! pre-calculating derived material parameters
|
|
||||||
vacancy_generation_kBCoeff(instance) = kB/vacancy_generation_atomicVol(instance)
|
|
||||||
vacancy_generation_specificFormationEnergy(instance) = &
|
|
||||||
vacancy_generation_formationEnergy(instance)/vacancy_generation_atomicVol(instance)
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
! Determine size of postResults array
|
|
||||||
outputsLoop: do o = 1_pInt,vacancy_generation_Noutput(instance)
|
|
||||||
select case(vacancy_generation_outputID(o,instance))
|
|
||||||
case(vacancy_concentration_ID)
|
|
||||||
mySize = 1_pInt
|
|
||||||
end select
|
|
||||||
|
|
||||||
if (mySize > 0_pInt) then ! any meaningful output found
|
|
||||||
vacancy_generation_sizePostResult(o,instance) = mySize
|
|
||||||
vacancy_generation_sizePostResults(instance) = vacancy_generation_sizePostResults(instance) + mySize
|
|
||||||
endif
|
|
||||||
enddo outputsLoop
|
|
||||||
! Determine size of state array
|
|
||||||
sizeDotState = 0_pInt
|
|
||||||
sizeState = 1_pInt
|
|
||||||
vacancyState(phase)%sizeState = sizeState
|
|
||||||
vacancyState(phase)%sizeDotState = sizeDotState
|
|
||||||
vacancyState(phase)%sizePostResults = vacancy_generation_sizePostResults(instance)
|
|
||||||
allocate(vacancyState(phase)%aTolState (sizeState), source=0.0_pReal)
|
|
||||||
allocate(vacancyState(phase)%state0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(vacancyState(phase)%partionedState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(vacancyState(phase)%subState0 (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(vacancyState(phase)%state (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(vacancyState(phase)%state_backup (sizeState,NofMyPhase), source=0.0_pReal)
|
|
||||||
|
|
||||||
allocate(vacancyState(phase)%dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(vacancyState(phase)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(vacancyState(phase)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 1_pInt)) then
|
|
||||||
allocate(vacancyState(phase)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
allocate(vacancyState(phase)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
endif
|
|
||||||
if (any(numerics_integrator == 4_pInt)) &
|
|
||||||
allocate(vacancyState(phase)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
|
||||||
if (any(numerics_integrator == 5_pInt)) &
|
|
||||||
allocate(vacancyState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
|
||||||
|
|
||||||
call vacancy_generation_stateInit(phase)
|
|
||||||
call vacancy_generation_aTolState(phase,instance)
|
|
||||||
endif
|
|
||||||
|
|
||||||
enddo initializeInstances
|
|
||||||
end subroutine vacancy_generation_init
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant NEW state values for a given instance of this vacancy model
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine vacancy_generation_stateInit(phase)
|
|
||||||
use material, only: &
|
|
||||||
vacancyState
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_equilibriumVacancyConcentration
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: phase !< number specifying the phase of the vacancy
|
|
||||||
real(pReal), dimension(vacancyState(phase)%sizeState) :: tempState
|
|
||||||
|
|
||||||
tempState(1) = lattice_equilibriumVacancyConcentration(phase)
|
|
||||||
vacancyState(phase)%state0 = spread(tempState,2,size(vacancyState(phase)%state(1,:)))
|
|
||||||
|
|
||||||
end subroutine vacancy_generation_stateInit
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief sets the relevant state values for a given instance of this vacancy model
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine vacancy_generation_aTolState(phase,instance)
|
|
||||||
use material, only: &
|
|
||||||
vacancyState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
phase, &
|
|
||||||
instance ! number specifying the current instance of the vacancy
|
|
||||||
real(pReal), dimension(vacancyState(phase)%sizeState) :: tempTol
|
|
||||||
|
|
||||||
tempTol = vacancy_generation_aTol(instance)
|
|
||||||
vacancyState(phase)%aTolState = tempTol
|
|
||||||
end subroutine vacancy_generation_aTolState
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief calculates derived quantities from state
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine vacancy_generation_microstructure(Tstar_v, temperature, damage, subdt, &
|
|
||||||
ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_vacancyInstance, &
|
|
||||||
plasticState, &
|
|
||||||
vacancyState
|
|
||||||
use math, only : &
|
|
||||||
math_Mandel6to33, &
|
|
||||||
math_trace33
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
Tstar_v(6), &
|
|
||||||
temperature, & !< 2nd Piola Kirchhoff stress tensor (Mandel)
|
|
||||||
damage, &
|
|
||||||
subdt
|
|
||||||
real(pReal) :: &
|
|
||||||
pressure, &
|
|
||||||
stressBarrier
|
|
||||||
integer(pInt) :: &
|
|
||||||
instance, phase, constituent
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_vacancyInstance(phase)
|
|
||||||
|
|
||||||
pressure = math_trace33(math_Mandel6to33(Tstar_v))/3.0_pReal
|
|
||||||
stressBarrier = max(0.0_pReal, &
|
|
||||||
vacancy_generation_specificFormationEnergy(instance) - &
|
|
||||||
pressure - &
|
|
||||||
vacancy_generation_plasticityCoeff(instance)* &
|
|
||||||
sum(plasticState(phase)%accumulatedSlip(:,constituent)))
|
|
||||||
|
|
||||||
vacancyState(phase)%state(1,constituent) = &
|
|
||||||
vacancyState(phase)%subState0(1,constituent) + &
|
|
||||||
subdt* &
|
|
||||||
damage*damage* &
|
|
||||||
vacancy_generation_freq(instance)* &
|
|
||||||
exp(-stressBarrier/(vacancy_generation_kBCoeff(instance)*temperature))
|
|
||||||
|
|
||||||
end subroutine vacancy_generation_microstructure
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns vacancy concentration based on state layout
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function vacancy_generation_getLocalConcentration(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
vacancyState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: vacancy_generation_getLocalConcentration
|
|
||||||
|
|
||||||
vacancy_generation_getLocalConcentration = &
|
|
||||||
vacancyState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))
|
|
||||||
|
|
||||||
end function vacancy_generation_getLocalConcentration
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns temperature based on local damage model state layout
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
subroutine vacancy_generation_putLocalConcentration(ipc, ip, el, localVacancyConcentration)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
vacancyState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
localVacancyConcentration
|
|
||||||
|
|
||||||
vacancyState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))= &
|
|
||||||
localVacancyConcentration
|
|
||||||
|
|
||||||
end subroutine vacancy_generation_putLocalConcentration
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns vacancy concentration based on state layout
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function vacancy_generation_getConcentration(ipc, ip, el)
|
|
||||||
use material, only: &
|
|
||||||
mappingHomogenization, &
|
|
||||||
material_phase, &
|
|
||||||
fieldVacancy, &
|
|
||||||
field_vacancy_type, &
|
|
||||||
FIELD_VACANCY_local_ID, &
|
|
||||||
FIELD_VACANCY_nonlocal_ID, &
|
|
||||||
material_homog
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal) :: vacancy_generation_getConcentration
|
|
||||||
|
|
||||||
select case(field_vacancy_type(material_homog(ip,el)))
|
|
||||||
case (FIELD_VACANCY_local_ID)
|
|
||||||
vacancy_generation_getConcentration = vacancy_generation_getLocalConcentration(ipc, ip, el)
|
|
||||||
|
|
||||||
case (FIELD_VACANCY_nonlocal_ID)
|
|
||||||
vacancy_generation_getConcentration = fieldVacancy(material_homog(ip,el))% &
|
|
||||||
field(1,mappingHomogenization(1,ip,el)) ! Taylor type
|
|
||||||
end select
|
|
||||||
|
|
||||||
end function vacancy_generation_getConcentration
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns generation vacancy diffusion tensor
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function vacancy_generation_getVacancyDiffusion33(ipc,ip,el)
|
|
||||||
use lattice, only: &
|
|
||||||
lattice_VacancyDiffusion33
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), dimension(3,3) :: &
|
|
||||||
vacancy_generation_getVacancyDiffusion33
|
|
||||||
|
|
||||||
vacancy_generation_getVacancyDiffusion33 = &
|
|
||||||
lattice_VacancyDiffusion33(1:3,1:3,mappingConstitutive(2,ipc,ip,el))
|
|
||||||
|
|
||||||
end function vacancy_generation_getVacancyDiffusion33
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns generation vacancy mobility tensor
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure function vacancy_generation_getVacancyMobility33(temperature,ipc,ip,el)
|
|
||||||
use math, only: &
|
|
||||||
math_I3
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_vacancyInstance, &
|
|
||||||
plasticState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
real(pReal), dimension(3,3) :: &
|
|
||||||
vacancy_generation_getVacancyMobility33
|
|
||||||
real(pReal), intent(in) :: &
|
|
||||||
temperature
|
|
||||||
integer(pInt) :: &
|
|
||||||
phase, constituent, instance
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_vacancyInstance(phase)
|
|
||||||
|
|
||||||
vacancy_generation_getVacancyMobility33 = &
|
|
||||||
math_I3*(1.0_pReal + sum(plasticState(phase)%accumulatedSlip(:,constituent)))
|
|
||||||
|
|
||||||
end function vacancy_generation_getVacancyMobility33
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief returns generation vacancy mobility tensor
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
pure real(pReal) function vacancy_generation_getVacancyEnergy(ipc,ip,el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_vacancyInstance
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< grain number
|
|
||||||
ip, & !< integration point number
|
|
||||||
el !< element number
|
|
||||||
integer(pInt) :: &
|
|
||||||
instance
|
|
||||||
|
|
||||||
instance = phase_vacancyInstance(mappingConstitutive(2,ipc,ip,el))
|
|
||||||
vacancy_generation_getVacancyEnergy = &
|
|
||||||
vacancy_generation_specificFormationEnergy(instance)/vacancy_generation_surfaceEnergy(instance)
|
|
||||||
|
|
||||||
end function vacancy_generation_getVacancyEnergy
|
|
||||||
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
!> @brief return array of constitutive results
|
|
||||||
!--------------------------------------------------------------------------------------------------
|
|
||||||
function vacancy_generation_postResults(ipc,ip,el)
|
|
||||||
use material, only: &
|
|
||||||
mappingConstitutive, &
|
|
||||||
phase_vacancyInstance, &
|
|
||||||
vacancyState
|
|
||||||
|
|
||||||
implicit none
|
|
||||||
integer(pInt), intent(in) :: &
|
|
||||||
ipc, & !< component-ID of integration point
|
|
||||||
ip, & !< integration point
|
|
||||||
el !< element
|
|
||||||
real(pReal), dimension(vacancy_generation_sizePostResults(phase_vacancyInstance(mappingConstitutive(2,ipc,ip,el)))) :: &
|
|
||||||
vacancy_generation_postResults
|
|
||||||
|
|
||||||
integer(pInt) :: &
|
|
||||||
instance, phase, constituent, o, c
|
|
||||||
|
|
||||||
phase = mappingConstitutive(2,ipc,ip,el)
|
|
||||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
|
||||||
instance = phase_vacancyInstance(phase)
|
|
||||||
|
|
||||||
c = 0_pInt
|
|
||||||
vacancy_generation_postResults = 0.0_pReal
|
|
||||||
|
|
||||||
do o = 1_pInt,vacancy_generation_Noutput(instance)
|
|
||||||
select case(vacancy_generation_outputID(o,instance))
|
|
||||||
|
|
||||||
case (vacancy_concentration_ID)
|
|
||||||
vacancy_generation_postResults(c+1_pInt) = vacancyState(phase)%state(1,constituent)
|
|
||||||
c = c + 1
|
|
||||||
end select
|
|
||||||
enddo
|
|
||||||
end function vacancy_generation_postResults
|
|
||||||
|
|
||||||
end module vacancy_generation
|
|
|
@ -0,0 +1,637 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for conservative transport of vacancy concentration field
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module vacancyflux_cahnhilliard
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt, &
|
||||||
|
p_vec
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
vacancyflux_cahnhilliard_sizePostResults !< cumulative size of post results
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
vacancyflux_cahnhilliard_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
vacancyflux_cahnhilliard_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
vacancyflux_cahnhilliard_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
real(pReal), dimension(:), allocatable, private :: &
|
||||||
|
vacancyflux_cahnhilliard_formationEnergyCoeff, &
|
||||||
|
vacancyflux_cahnhilliard_surfaceEnergy, &
|
||||||
|
vacancyflux_cahnhilliard_kBCoeff
|
||||||
|
|
||||||
|
type(p_vec), dimension(:), allocatable, private :: &
|
||||||
|
vacancyflux_cahnhilliard_thermalFluc
|
||||||
|
|
||||||
|
real(pReal), parameter, private :: &
|
||||||
|
kB = 1.3806488e-23_pReal !< Boltzmann constant in J/Kelvin
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
vacancyConc_ID
|
||||||
|
end enum
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
vacancyflux_cahnhilliard_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
vacancyflux_cahnhilliard_init, &
|
||||||
|
vacancyflux_cahnhilliard_getSourceAndItsTangent, &
|
||||||
|
vacancyflux_cahnhilliard_getMobility33, &
|
||||||
|
vacancyflux_cahnhilliard_getDiffusion33, &
|
||||||
|
vacancyflux_cahnhilliard_getChemPotAndItsTangent, &
|
||||||
|
vacancyflux_cahnhilliard_putVacancyConcAndItsRate, &
|
||||||
|
vacancyflux_cahnhilliard_postResults
|
||||||
|
private :: &
|
||||||
|
vacancyflux_cahnhilliard_getFormationEnergy, &
|
||||||
|
vacancyflux_cahnhilliard_getEntropicCoeff, &
|
||||||
|
vacancyflux_cahnhilliard_KinematicChemPotAndItsTangent
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine vacancyflux_cahnhilliard_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_vacancyVol
|
||||||
|
use material, only: &
|
||||||
|
vacancyflux_type, &
|
||||||
|
vacancyflux_typeInstance, &
|
||||||
|
homogenization_Noutput, &
|
||||||
|
VACANCYFLUX_cahnhilliard_label, &
|
||||||
|
VACANCYFLUX_cahnhilliard_ID, &
|
||||||
|
material_homog, &
|
||||||
|
material_Nphase, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
vacancyfluxState, &
|
||||||
|
vacancyfluxMapping, &
|
||||||
|
vacancyConc, &
|
||||||
|
vacancyConcRate, &
|
||||||
|
material_partHomogenization, &
|
||||||
|
material_partPhase
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,section,instance,o,offset
|
||||||
|
integer(pInt) :: sizeState
|
||||||
|
integer(pInt) :: NofMyHomog
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- vacancyflux_'//VACANCYFLUX_cahnhilliard_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(vacancyflux_type == VACANCYFLUX_cahnhilliard_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
allocate(vacancyflux_cahnhilliard_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(vacancyflux_cahnhilliard_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(vacancyflux_cahnhilliard_output (maxval(homogenization_Noutput),maxNinstance))
|
||||||
|
vacancyflux_cahnhilliard_output = ''
|
||||||
|
allocate(vacancyflux_cahnhilliard_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID)
|
||||||
|
allocate(vacancyflux_cahnhilliard_Noutput (maxNinstance), source=0_pInt)
|
||||||
|
|
||||||
|
allocate(vacancyflux_cahnhilliard_formationEnergyCoeff(material_Nphase), source=0.0_pReal)
|
||||||
|
allocate(vacancyflux_cahnhilliard_kBCoeff (material_Nphase), source=0.0_pReal)
|
||||||
|
allocate(vacancyflux_cahnhilliard_surfaceEnergy (material_Nphase), source=0.0_pReal)
|
||||||
|
|
||||||
|
allocate(vacancyflux_cahnhilliard_thermalFluc(maxNinstance))
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
section = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partHomogenization)! wind forward to <homogenization>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingHomog: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
|
section = section + 1_pInt ! advance homog section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (section > 0_pInt ) then; if (vacancyflux_type(section) == VACANCYFLUX_cahnhilliard_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = vacancyflux_typeInstance(section) ! which instance of my vacancyflux is present homog
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('vacancyconc')
|
||||||
|
vacancyflux_cahnhilliard_Noutput(instance) = vacancyflux_cahnhilliard_Noutput(instance) + 1_pInt
|
||||||
|
vacancyflux_cahnhilliard_outputID(vacancyflux_cahnhilliard_Noutput(instance),instance) = vacancyConc_ID
|
||||||
|
vacancyflux_cahnhilliard_output(vacancyflux_cahnhilliard_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingHomog
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
section = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partPhase) ! wind forward to <homogenization>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingPhase: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
|
section = section + 1_pInt ! advance homog section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (section > 0_pInt ) then; if (vacancyflux_type(section) == VACANCYFLUX_cahnhilliard_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('vacancyformationenergy')
|
||||||
|
vacancyflux_cahnhilliard_formationEnergyCoeff(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
case ('voidsurfaceenergy')
|
||||||
|
vacancyflux_cahnhilliard_surfaceEnergy(section) = IO_floatValue(line,positions,2_pInt)
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingPhase
|
||||||
|
|
||||||
|
initializeInstances: do section = 1_pInt, size(vacancyflux_type)
|
||||||
|
if (vacancyflux_type(section) == VACANCYFLUX_cahnhilliard_ID) then
|
||||||
|
NofMyHomog=count(material_homog==section)
|
||||||
|
instance = vacancyflux_typeInstance(section)
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,vacancyflux_cahnhilliard_Noutput(instance)
|
||||||
|
select case(vacancyflux_cahnhilliard_outputID(o,instance))
|
||||||
|
case(vacancyConc_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
vacancyflux_cahnhilliard_sizePostResult(o,instance) = mySize
|
||||||
|
vacancyflux_cahnhilliard_sizePostResults(instance) = vacancyflux_cahnhilliard_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
|
||||||
|
! allocate state arrays
|
||||||
|
sizeState = 0_pInt
|
||||||
|
vacancyfluxState(section)%sizeState = sizeState
|
||||||
|
vacancyfluxState(section)%sizePostResults = vacancyflux_cahnhilliard_sizePostResults(instance)
|
||||||
|
allocate(vacancyfluxState(section)%state0 (sizeState,NofMyHomog))
|
||||||
|
allocate(vacancyfluxState(section)%subState0(sizeState,NofMyHomog))
|
||||||
|
allocate(vacancyfluxState(section)%state (sizeState,NofMyHomog))
|
||||||
|
|
||||||
|
allocate(vacancyflux_cahnhilliard_thermalFluc(instance)%p(NofMyHomog))
|
||||||
|
do offset = 1_pInt, NofMyHomog
|
||||||
|
call random_number(vacancyflux_cahnhilliard_thermalFluc(instance)%p(offset))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
nullify(vacancyfluxMapping(section)%p)
|
||||||
|
vacancyfluxMapping(section)%p => mappingHomogenization(1,:,:)
|
||||||
|
deallocate(vacancyConc (section)%p)
|
||||||
|
allocate (vacancyConc (section)%p(NofMyHomog), source=0.0_pReal)
|
||||||
|
deallocate(vacancyConcRate(section)%p)
|
||||||
|
allocate (vacancyConcRate(section)%p(NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
|
||||||
|
initializeParams: do section = 1_pInt, material_Nphase
|
||||||
|
vacancyflux_cahnhilliard_formationEnergyCoeff(section) = &
|
||||||
|
vacancyflux_cahnhilliard_formationEnergyCoeff(section)/ &
|
||||||
|
lattice_vacancyVol(section)/ &
|
||||||
|
vacancyflux_cahnhilliard_surfaceEnergy(section)
|
||||||
|
vacancyflux_cahnhilliard_kBCoeff(section) = &
|
||||||
|
kB/ &
|
||||||
|
lattice_vacancyVol(section)/ &
|
||||||
|
vacancyflux_cahnhilliard_surfaceEnergy(section)
|
||||||
|
enddo initializeParams
|
||||||
|
|
||||||
|
end subroutine vacancyflux_cahnhilliard_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates homogenized vacancy driving forces
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine vacancyflux_cahnhilliard_getSourceAndItsTangent(CvDot, dCvDot_dCv, Cv, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
mappingConstitutive, &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
SOURCE_vacancy_phenoplasticity_ID, &
|
||||||
|
SOURCE_vacancy_irradiation_ID, &
|
||||||
|
SOURCE_vacancy_thermalfluc_ID
|
||||||
|
use source_vacancy_phenoplasticity, only: &
|
||||||
|
source_vacancy_phenoplasticity_getRateAndItsTangent
|
||||||
|
use source_vacancy_irradiation, only: &
|
||||||
|
source_vacancy_irradiation_getRateAndItsTangent
|
||||||
|
use source_vacancy_thermalfluc, only: &
|
||||||
|
source_vacancy_thermalfluc_getRateAndItsTangent
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
Cv
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
grain, &
|
||||||
|
source
|
||||||
|
real(pReal) :: &
|
||||||
|
CvDot, dCvDot_dCv, localCvDot, dLocalCvDot_dCv
|
||||||
|
|
||||||
|
CvDot = 0.0_pReal
|
||||||
|
dCvDot_dCv = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
phase = mappingConstitutive(2,grain,ip,el)
|
||||||
|
do source = 1_pInt, phase_Nsources(phase)
|
||||||
|
select case(phase_source(source,phase))
|
||||||
|
case (SOURCE_vacancy_phenoplasticity_ID)
|
||||||
|
call source_vacancy_phenoplasticity_getRateAndItsTangent (localCvDot, dLocalCvDot_dCv, grain, ip, el)
|
||||||
|
|
||||||
|
case (SOURCE_vacancy_irradiation_ID)
|
||||||
|
call source_vacancy_irradiation_getRateAndItsTangent (localCvDot, dLocalCvDot_dCv, grain, ip, el)
|
||||||
|
|
||||||
|
case (SOURCE_vacancy_thermalfluc_ID)
|
||||||
|
call source_vacancy_thermalfluc_getRateAndItsTangent(localCvDot, dLocalCvDot_dCv, grain, ip, el)
|
||||||
|
|
||||||
|
end select
|
||||||
|
CvDot = CvDot + localCvDot
|
||||||
|
dCvDot_dCv = dCvDot_dCv + dLocalCvDot_dCv
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
CvDot = CvDot/homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
dCvDot_dCv = dCvDot_dCv/homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
|
||||||
|
end subroutine vacancyflux_cahnhilliard_getSourceAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized vacancy mobility tensor in reference configuration
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function vacancyflux_cahnhilliard_getMobility33(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_vacancyfluxMobility33
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), dimension(3,3) :: &
|
||||||
|
vacancyflux_cahnhilliard_getMobility33
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain
|
||||||
|
|
||||||
|
vacancyflux_cahnhilliard_getMobility33 = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
vacancyflux_cahnhilliard_getMobility33 = vacancyflux_cahnhilliard_getMobility33 + &
|
||||||
|
crystallite_push33ToRef(grain,ip,el,lattice_vacancyfluxMobility33(:,:,material_phase(grain,ip,el)))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
vacancyflux_cahnhilliard_getMobility33 = &
|
||||||
|
vacancyflux_cahnhilliard_getMobility33/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function vacancyflux_cahnhilliard_getMobility33
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized vacancy diffusion tensor in reference configuration
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function vacancyflux_cahnhilliard_getDiffusion33(ip,el)
|
||||||
|
use lattice, only: &
|
||||||
|
lattice_vacancyfluxDiffusion33
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_push33ToRef
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), dimension(3,3) :: &
|
||||||
|
vacancyflux_cahnhilliard_getDiffusion33
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain
|
||||||
|
|
||||||
|
vacancyflux_cahnhilliard_getDiffusion33 = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
vacancyflux_cahnhilliard_getDiffusion33 = vacancyflux_cahnhilliard_getDiffusion33 + &
|
||||||
|
crystallite_push33ToRef(grain,ip,el,lattice_vacancyfluxDiffusion33(:,:,material_phase(grain,ip,el)))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
vacancyflux_cahnhilliard_getDiffusion33 = &
|
||||||
|
vacancyflux_cahnhilliard_getDiffusion33/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function vacancyflux_cahnhilliard_getDiffusion33
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized vacancy formation energy
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function vacancyflux_cahnhilliard_getFormationEnergy(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_phase
|
||||||
|
use mesh, only: &
|
||||||
|
mesh_element
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal) :: &
|
||||||
|
vacancyflux_cahnhilliard_getFormationEnergy
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain
|
||||||
|
|
||||||
|
vacancyflux_cahnhilliard_getFormationEnergy = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
vacancyflux_cahnhilliard_getFormationEnergy = vacancyflux_cahnhilliard_getFormationEnergy + &
|
||||||
|
vacancyflux_cahnhilliard_formationEnergyCoeff(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
vacancyflux_cahnhilliard_getFormationEnergy = &
|
||||||
|
vacancyflux_cahnhilliard_getFormationEnergy/ &
|
||||||
|
homogenization_Ngrains(mesh_element(3,el))
|
||||||
|
|
||||||
|
end function vacancyflux_cahnhilliard_getFormationEnergy
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized vacancy entropy coefficient
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function vacancyflux_cahnhilliard_getEntropicCoeff(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_homog, &
|
||||||
|
material_phase, &
|
||||||
|
temperature, &
|
||||||
|
thermalMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal) :: &
|
||||||
|
vacancyflux_cahnhilliard_getEntropicCoeff
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain
|
||||||
|
|
||||||
|
vacancyflux_cahnhilliard_getEntropicCoeff = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(material_homog(ip,el))
|
||||||
|
vacancyflux_cahnhilliard_getEntropicCoeff = vacancyflux_cahnhilliard_getEntropicCoeff + &
|
||||||
|
vacancyflux_cahnhilliard_kBCoeff(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
vacancyflux_cahnhilliard_getEntropicCoeff = &
|
||||||
|
vacancyflux_cahnhilliard_getEntropicCoeff* &
|
||||||
|
temperature(material_homog(ip,el))%p(thermalMapping(material_homog(ip,el))%p(ip,el))/ &
|
||||||
|
homogenization_Ngrains(material_homog(ip,el))
|
||||||
|
|
||||||
|
end function vacancyflux_cahnhilliard_getEntropicCoeff
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized kinematic contribution to chemical potential
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine vacancyflux_cahnhilliard_KinematicChemPotAndItsTangent(KPot, dKPot_dCv, Cv, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
material_homog, &
|
||||||
|
phase_kinematics, &
|
||||||
|
phase_Nkinematics, &
|
||||||
|
material_phase, &
|
||||||
|
KINEMATICS_vacancy_strain_ID
|
||||||
|
use crystallite, only: &
|
||||||
|
crystallite_Tstar_v, &
|
||||||
|
crystallite_Fi0, &
|
||||||
|
crystallite_Fi
|
||||||
|
use kinematics_vacancy_strain, only: &
|
||||||
|
kinematics_vacancy_strain_ChemPotAndItsTangent
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
Cv
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
KPot, dKPot_dCv
|
||||||
|
real(pReal) :: &
|
||||||
|
my_KPot, my_dKPot_dCv
|
||||||
|
integer(pInt) :: &
|
||||||
|
grain, kinematics
|
||||||
|
|
||||||
|
KPot = 0.0_pReal
|
||||||
|
dKPot_dCv = 0.0_pReal
|
||||||
|
do grain = 1_pInt,homogenization_Ngrains(material_homog(ip,el))
|
||||||
|
do kinematics = 1_pInt, phase_Nkinematics(material_phase(grain,ip,el))
|
||||||
|
select case (phase_kinematics(kinematics,material_phase(grain,ip,el)))
|
||||||
|
case (KINEMATICS_vacancy_strain_ID)
|
||||||
|
call kinematics_vacancy_strain_ChemPotAndItsTangent(my_KPot, my_dKPot_dCv, &
|
||||||
|
crystallite_Tstar_v(1:6,grain,ip,el), &
|
||||||
|
crystallite_Fi0(1:3,1:3,grain,ip,el), &
|
||||||
|
crystallite_Fi (1:3,1:3,grain,ip,el), &
|
||||||
|
grain,ip, el)
|
||||||
|
|
||||||
|
case default
|
||||||
|
my_KPot = 0.0_pReal
|
||||||
|
my_dKPot_dCv = 0.0_pReal
|
||||||
|
|
||||||
|
end select
|
||||||
|
KPot = KPot + my_KPot/vacancyflux_cahnhilliard_surfaceEnergy(material_phase(grain,ip,el))
|
||||||
|
dKPot_dCv = dKPot_dCv + my_dKPot_dCv/vacancyflux_cahnhilliard_surfaceEnergy(material_phase(grain,ip,el))
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
KPot = KPot/homogenization_Ngrains(material_homog(ip,el))
|
||||||
|
dKPot_dCv = dKPot_dCv/homogenization_Ngrains(material_homog(ip,el))
|
||||||
|
|
||||||
|
end subroutine vacancyflux_cahnhilliard_KinematicChemPotAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief returns homogenized chemical potential and its tangent
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine vacancyflux_cahnhilliard_getChemPotAndItsTangent(ChemPot,dChemPot_dCv,Cv,ip,el)
|
||||||
|
use numerics, only: &
|
||||||
|
vacancyBoundPenalty, &
|
||||||
|
vacancyPolyOrder
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
porosity, &
|
||||||
|
porosityMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
Cv
|
||||||
|
real(pReal), intent(out) :: &
|
||||||
|
ChemPot, &
|
||||||
|
dChemPot_dCv
|
||||||
|
real(pReal) :: &
|
||||||
|
VoidPhaseFrac, kBT, KPot, dKPot_dCv
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, o
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
VoidPhaseFrac = porosity(homog)%p(porosityMapping(homog)%p(ip,el))
|
||||||
|
kBT = vacancyflux_cahnhilliard_getEntropicCoeff(ip,el)
|
||||||
|
|
||||||
|
ChemPot = vacancyflux_cahnhilliard_getFormationEnergy(ip,el)
|
||||||
|
dChemPot_dCv = 0.0_pReal
|
||||||
|
do o = 1_pInt, vacancyPolyOrder
|
||||||
|
ChemPot = ChemPot + kBT*((2.0_pReal*Cv - 1.0_pReal)**real(2_pInt*o-1_pInt,pReal))/ &
|
||||||
|
real(2_pInt*o-1_pInt,pReal)
|
||||||
|
dChemPot_dCv = dChemPot_dCv + 2.0_pReal*kBT*(2.0_pReal*Cv - 1.0_pReal)**real(2_pInt*o-2_pInt,pReal)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
ChemPot = VoidPhaseFrac*VoidPhaseFrac*ChemPot &
|
||||||
|
- 2.0_pReal*(1.0_pReal - Cv)*(1.0_pReal - VoidPhaseFrac)*(1.0_pReal - VoidPhaseFrac)
|
||||||
|
|
||||||
|
dChemPot_dCv = VoidPhaseFrac*VoidPhaseFrac*dChemPot_dCv &
|
||||||
|
+ 2.0_pReal*(1.0_pReal - VoidPhaseFrac)*(1.0_pReal - VoidPhaseFrac)
|
||||||
|
|
||||||
|
call vacancyflux_cahnhilliard_KinematicChemPotAndItsTangent(KPot, dKPot_dCv, Cv, ip, el)
|
||||||
|
ChemPot = ChemPot + KPot
|
||||||
|
dChemPot_dCv = dChemPot_dCv + dKPot_dCv
|
||||||
|
|
||||||
|
if (Cv < 0.0_pReal) then
|
||||||
|
ChemPot = ChemPot - 3.0_pReal*vacancyBoundPenalty*Cv*Cv
|
||||||
|
dChemPot_dCv = dChemPot_dCv - 6.0_pReal*vacancyBoundPenalty*Cv
|
||||||
|
elseif (Cv > 1.0_pReal) then
|
||||||
|
ChemPot = ChemPot + 3.0_pReal*vacancyBoundPenalty*(1.0_pReal - Cv)*(1.0_pReal - Cv)
|
||||||
|
dChemPot_dCv = dChemPot_dCv - 6.0_pReal*vacancyBoundPenalty*(1.0_pReal - Cv)
|
||||||
|
endif
|
||||||
|
|
||||||
|
end subroutine vacancyflux_cahnhilliard_getChemPotAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief updated vacancy concentration and its rate with solution from transport PDE
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine vacancyflux_cahnhilliard_putVacancyConcAndItsRate(Cv,Cvdot,ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
vacancyConc, &
|
||||||
|
vacancyConcRate, &
|
||||||
|
vacancyfluxMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
Cv, &
|
||||||
|
Cvdot
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
offset
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = vacancyfluxMapping(homog)%p(ip,el)
|
||||||
|
vacancyConc (homog)%p(offset) = Cv
|
||||||
|
vacancyConcRate(homog)%p(offset) = Cvdot
|
||||||
|
|
||||||
|
end subroutine vacancyflux_cahnhilliard_putVacancyConcAndItsRate
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of vacancy transport results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function vacancyflux_cahnhilliard_postResults(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
vacancyflux_typeInstance, &
|
||||||
|
vacancyConc, &
|
||||||
|
vacancyfluxMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(vacancyflux_cahnhilliard_sizePostResults(vacancyflux_typeInstance(mappingHomogenization(2,ip,el)))) :: &
|
||||||
|
vacancyflux_cahnhilliard_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, homog, offset, o, c
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = vacancyfluxMapping(homog)%p(ip,el)
|
||||||
|
instance = vacancyflux_typeInstance(homog)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
vacancyflux_cahnhilliard_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,vacancyflux_cahnhilliard_Noutput(instance)
|
||||||
|
select case(vacancyflux_cahnhilliard_outputID(o,instance))
|
||||||
|
|
||||||
|
case (vacancyConc_ID)
|
||||||
|
vacancyflux_cahnhilliard_postResults(c+1_pInt) = vacancyConc(homog)%p(offset)
|
||||||
|
c = c + 1
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function vacancyflux_cahnhilliard_postResults
|
||||||
|
|
||||||
|
end module vacancyflux_cahnhilliard
|
|
@ -0,0 +1,330 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for locally evolving vacancy concentration
|
||||||
|
!> @details to be done
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module vacancyflux_isochempot
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
integer(pInt), dimension(:), allocatable, public, protected :: &
|
||||||
|
vacancyflux_isochempot_sizePostResults !< cumulative size of post results
|
||||||
|
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target, public :: &
|
||||||
|
vacancyflux_isochempot_sizePostResult !< size of each post result output
|
||||||
|
|
||||||
|
character(len=64), dimension(:,:), allocatable, target, public :: &
|
||||||
|
vacancyflux_isochempot_output !< name of each post result output
|
||||||
|
|
||||||
|
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||||
|
vacancyflux_isochempot_Noutput !< number of outputs per instance of this damage
|
||||||
|
|
||||||
|
enum, bind(c)
|
||||||
|
enumerator :: undefined_ID, &
|
||||||
|
vacancyconc_ID
|
||||||
|
end enum
|
||||||
|
integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
|
||||||
|
vacancyflux_isochempot_outputID !< ID of each post result output
|
||||||
|
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
vacancyflux_isochempot_init, &
|
||||||
|
vacancyflux_isochempot_updateState, &
|
||||||
|
vacancyflux_isochempot_getSourceAndItsTangent, &
|
||||||
|
vacancyflux_isochempot_postResults
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief module initialization
|
||||||
|
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine vacancyflux_isochempot_init(fileUnit)
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use IO, only: &
|
||||||
|
IO_read, &
|
||||||
|
IO_lc, &
|
||||||
|
IO_getTag, &
|
||||||
|
IO_isBlank, &
|
||||||
|
IO_stringPos, &
|
||||||
|
IO_stringValue, &
|
||||||
|
IO_floatValue, &
|
||||||
|
IO_intValue, &
|
||||||
|
IO_warning, &
|
||||||
|
IO_error, &
|
||||||
|
IO_timeStamp, &
|
||||||
|
IO_EOF
|
||||||
|
use material, only: &
|
||||||
|
vacancyflux_type, &
|
||||||
|
vacancyflux_typeInstance, &
|
||||||
|
homogenization_Noutput, &
|
||||||
|
VACANCYFLUX_isochempot_label, &
|
||||||
|
VACANCYFLUX_isochempot_ID, &
|
||||||
|
material_homog, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
vacancyfluxState, &
|
||||||
|
vacancyfluxMapping, &
|
||||||
|
vacancyConc, &
|
||||||
|
vacancyConcRate, &
|
||||||
|
material_partHomogenization
|
||||||
|
use numerics,only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: fileUnit
|
||||||
|
|
||||||
|
integer(pInt), parameter :: MAXNCHUNKS = 7_pInt
|
||||||
|
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||||
|
integer(pInt) :: maxNinstance,mySize=0_pInt,section,instance,o
|
||||||
|
integer(pInt) :: sizeState
|
||||||
|
integer(pInt) :: NofMyHomog
|
||||||
|
character(len=65536) :: &
|
||||||
|
tag = '', &
|
||||||
|
line = ''
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- vacancyflux_'//VACANCYFLUX_isochempot_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
maxNinstance = int(count(vacancyflux_type == VACANCYFLUX_isochempot_ID),pInt)
|
||||||
|
if (maxNinstance == 0_pInt) return
|
||||||
|
|
||||||
|
allocate(vacancyflux_isochempot_sizePostResults(maxNinstance), source=0_pInt)
|
||||||
|
allocate(vacancyflux_isochempot_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0_pInt)
|
||||||
|
allocate(vacancyflux_isochempot_output (maxval(homogenization_Noutput),maxNinstance))
|
||||||
|
vacancyflux_isochempot_output = ''
|
||||||
|
allocate(vacancyflux_isochempot_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID)
|
||||||
|
allocate(vacancyflux_isochempot_Noutput (maxNinstance), source=0_pInt)
|
||||||
|
|
||||||
|
rewind(fileUnit)
|
||||||
|
section = 0_pInt
|
||||||
|
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partHomogenization)! wind forward to <homogenization>
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of homog part
|
||||||
|
line = IO_read(fileUnit)
|
||||||
|
if (IO_isBlank(line)) cycle ! skip empty lines
|
||||||
|
if (IO_getTag(line,'<','>') /= '') then ! stop at next part
|
||||||
|
line = IO_read(fileUnit, .true.) ! reset IO_read
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||||
|
section = section + 1_pInt ! advance homog section counter
|
||||||
|
cycle ! skip to next line
|
||||||
|
endif
|
||||||
|
|
||||||
|
if (section > 0_pInt ) then; if (vacancyflux_type(section) == VACANCYFLUX_isochempot_ID) then ! do not short-circuit here (.and. with next if statemen). It's not safe in Fortran
|
||||||
|
|
||||||
|
instance = vacancyflux_typeInstance(section) ! which instance of my vacancyflux is present homog
|
||||||
|
positions = IO_stringPos(line,MAXNCHUNKS)
|
||||||
|
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||||
|
select case(tag)
|
||||||
|
case ('(output)')
|
||||||
|
select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||||
|
case ('vacancyconc')
|
||||||
|
vacancyflux_isochempot_Noutput(instance) = vacancyflux_isochempot_Noutput(instance) + 1_pInt
|
||||||
|
vacancyflux_isochempot_outputID(vacancyflux_isochempot_Noutput(instance),instance) = vacancyconc_ID
|
||||||
|
vacancyflux_isochempot_output(vacancyflux_isochempot_Noutput(instance),instance) = &
|
||||||
|
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||||
|
end select
|
||||||
|
|
||||||
|
end select
|
||||||
|
endif; endif
|
||||||
|
enddo parsingFile
|
||||||
|
|
||||||
|
initializeInstances: do section = 1_pInt, size(vacancyflux_type)
|
||||||
|
if (vacancyflux_type(section) == VACANCYFLUX_isochempot_ID) then
|
||||||
|
NofMyHomog=count(material_homog==section)
|
||||||
|
instance = vacancyflux_typeInstance(section)
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! Determine size of postResults array
|
||||||
|
outputsLoop: do o = 1_pInt,vacancyflux_isochempot_Noutput(instance)
|
||||||
|
select case(vacancyflux_isochempot_outputID(o,instance))
|
||||||
|
case(vacancyconc_ID)
|
||||||
|
mySize = 1_pInt
|
||||||
|
end select
|
||||||
|
|
||||||
|
if (mySize > 0_pInt) then ! any meaningful output found
|
||||||
|
vacancyflux_isochempot_sizePostResult(o,instance) = mySize
|
||||||
|
vacancyflux_isochempot_sizePostResults(instance) = vacancyflux_isochempot_sizePostResults(instance) + mySize
|
||||||
|
endif
|
||||||
|
enddo outputsLoop
|
||||||
|
|
||||||
|
! allocate state arrays
|
||||||
|
sizeState = 1_pInt
|
||||||
|
vacancyfluxState(section)%sizeState = sizeState
|
||||||
|
vacancyfluxState(section)%sizePostResults = vacancyflux_isochempot_sizePostResults(instance)
|
||||||
|
allocate(vacancyfluxState(section)%state0 (sizeState,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(vacancyfluxState(section)%subState0(sizeState,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(vacancyfluxState(section)%state (sizeState,NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
|
nullify(vacancyfluxMapping(section)%p)
|
||||||
|
vacancyfluxMapping(section)%p => mappingHomogenization(1,:,:)
|
||||||
|
deallocate(vacancyConc(section)%p)
|
||||||
|
vacancyConc(section)%p => vacancyfluxState(section)%state(1,:)
|
||||||
|
deallocate(vacancyConcRate(section)%p)
|
||||||
|
allocate(vacancyConcRate(section)%p(NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
enddo initializeInstances
|
||||||
|
end subroutine vacancyflux_isochempot_init
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates change in vacancy concentration based on local vacancy generation model
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function vacancyflux_isochempot_updateState(subdt, ip, el)
|
||||||
|
use numerics, only: &
|
||||||
|
err_vacancyflux_tolAbs, &
|
||||||
|
err_vacancyflux_tolRel
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
vacancyflux_typeInstance, &
|
||||||
|
vacancyfluxState, &
|
||||||
|
vacancyConc, &
|
||||||
|
vacancyConcRate, &
|
||||||
|
vacancyfluxMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
subdt
|
||||||
|
logical, dimension(2) :: &
|
||||||
|
vacancyflux_isochempot_updateState
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
offset, &
|
||||||
|
instance
|
||||||
|
real(pReal) :: &
|
||||||
|
Cv, Cvdot, dCvDot_dCv
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = mappingHomogenization(1,ip,el)
|
||||||
|
instance = vacancyflux_typeInstance(homog)
|
||||||
|
|
||||||
|
Cv = vacancyfluxState(homog)%subState0(1,offset)
|
||||||
|
call vacancyflux_isochempot_getSourceAndItsTangent(CvDot, dCvDot_dCv, Cv, ip, el)
|
||||||
|
Cv = Cv + subdt*Cvdot
|
||||||
|
|
||||||
|
vacancyflux_isochempot_updateState = [ abs(Cv - vacancyfluxState(homog)%state(1,offset)) &
|
||||||
|
<= err_vacancyflux_tolAbs &
|
||||||
|
.or. abs(Cv - vacancyfluxState(homog)%state(1,offset)) &
|
||||||
|
<= err_vacancyflux_tolRel*abs(vacancyfluxState(homog)%state(1,offset)), &
|
||||||
|
.true.]
|
||||||
|
|
||||||
|
vacancyConc (homog)%p(vacancyfluxMapping(homog)%p(ip,el)) = Cv
|
||||||
|
vacancyConcRate(homog)%p(vacancyfluxMapping(homog)%p(ip,el)) = &
|
||||||
|
(vacancyfluxState(homog)%state(1,offset) - vacancyfluxState(homog)%subState0(1,offset))/subdt
|
||||||
|
|
||||||
|
end function vacancyflux_isochempot_updateState
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief calculates homogenized vacancy driving forces
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine vacancyflux_isochempot_getSourceAndItsTangent(CvDot, dCvDot_dCv, Cv, ip, el)
|
||||||
|
use material, only: &
|
||||||
|
homogenization_Ngrains, &
|
||||||
|
mappingHomogenization, &
|
||||||
|
mappingConstitutive, &
|
||||||
|
phase_source, &
|
||||||
|
phase_Nsources, &
|
||||||
|
SOURCE_vacancy_phenoplasticity_ID, &
|
||||||
|
SOURCE_vacancy_irradiation_ID, &
|
||||||
|
SOURCE_vacancy_thermalfluc_ID
|
||||||
|
use source_vacancy_phenoplasticity, only: &
|
||||||
|
source_vacancy_phenoplasticity_getRateAndItsTangent
|
||||||
|
use source_vacancy_irradiation, only: &
|
||||||
|
source_vacancy_irradiation_getRateAndItsTangent
|
||||||
|
use source_vacancy_thermalfluc, only: &
|
||||||
|
source_vacancy_thermalfluc_getRateAndItsTangent
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point number
|
||||||
|
el !< element number
|
||||||
|
real(pReal), intent(in) :: &
|
||||||
|
Cv
|
||||||
|
integer(pInt) :: &
|
||||||
|
phase, &
|
||||||
|
grain, &
|
||||||
|
source
|
||||||
|
real(pReal) :: &
|
||||||
|
CvDot, dCvDot_dCv, localCvDot, dLocalCvDot_dCv
|
||||||
|
|
||||||
|
CvDot = 0.0_pReal
|
||||||
|
dCvDot_dCv = 0.0_pReal
|
||||||
|
do grain = 1, homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
phase = mappingConstitutive(2,grain,ip,el)
|
||||||
|
do source = 1_pInt, phase_Nsources(phase)
|
||||||
|
select case(phase_source(source,phase))
|
||||||
|
case (SOURCE_vacancy_phenoplasticity_ID)
|
||||||
|
call source_vacancy_phenoplasticity_getRateAndItsTangent (localCvDot, dLocalCvDot_dCv, grain, ip, el)
|
||||||
|
|
||||||
|
case (SOURCE_vacancy_irradiation_ID)
|
||||||
|
call source_vacancy_irradiation_getRateAndItsTangent (localCvDot, dLocalCvDot_dCv, grain, ip, el)
|
||||||
|
|
||||||
|
case (SOURCE_vacancy_thermalfluc_ID)
|
||||||
|
call source_vacancy_thermalfluc_getRateAndItsTangent(localCvDot, dLocalCvDot_dCv, grain, ip, el)
|
||||||
|
|
||||||
|
end select
|
||||||
|
CvDot = CvDot + localCvDot
|
||||||
|
dCvDot_dCv = dCvDot_dCv + dLocalCvDot_dCv
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
CvDot = CvDot/homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
dCvDot_dCv = dCvDot_dCv/homogenization_Ngrains(mappingHomogenization(2,ip,el))
|
||||||
|
|
||||||
|
end subroutine vacancyflux_isochempot_getSourceAndItsTangent
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief return array of vacancy transport results
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
function vacancyflux_isochempot_postResults(ip,el)
|
||||||
|
use material, only: &
|
||||||
|
mappingHomogenization, &
|
||||||
|
vacancyflux_typeInstance, &
|
||||||
|
vacancyConc, &
|
||||||
|
vacancyfluxMapping
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt), intent(in) :: &
|
||||||
|
ip, & !< integration point
|
||||||
|
el !< element
|
||||||
|
real(pReal), dimension(vacancyflux_isochempot_sizePostResults(vacancyflux_typeInstance(mappingHomogenization(2,ip,el)))) :: &
|
||||||
|
vacancyflux_isochempot_postResults
|
||||||
|
|
||||||
|
integer(pInt) :: &
|
||||||
|
instance, homog, offset, o, c
|
||||||
|
|
||||||
|
homog = mappingHomogenization(2,ip,el)
|
||||||
|
offset = vacancyfluxMapping(homog)%p(ip,el)
|
||||||
|
instance = vacancyflux_typeInstance(homog)
|
||||||
|
|
||||||
|
c = 0_pInt
|
||||||
|
vacancyflux_isochempot_postResults = 0.0_pReal
|
||||||
|
|
||||||
|
do o = 1_pInt,vacancyflux_isochempot_Noutput(instance)
|
||||||
|
select case(vacancyflux_isochempot_outputID(o,instance))
|
||||||
|
|
||||||
|
case (vacancyconc_ID)
|
||||||
|
vacancyflux_isochempot_postResults(c+1_pInt) = vacancyConc(homog)%p(offset)
|
||||||
|
c = c + 1
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
end function vacancyflux_isochempot_postResults
|
||||||
|
|
||||||
|
end module vacancyflux_isochempot
|
|
@ -0,0 +1,64 @@
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
! $Id$
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||||
|
!> @brief material subroutine for constant vacancy concentration
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
module vacancyflux_isoconc
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
private
|
||||||
|
|
||||||
|
public :: &
|
||||||
|
vacancyflux_isoconc_init
|
||||||
|
|
||||||
|
contains
|
||||||
|
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
!> @brief allocates all neccessary fields, reads information from material configuration file
|
||||||
|
!--------------------------------------------------------------------------------------------------
|
||||||
|
subroutine vacancyflux_isoconc_init()
|
||||||
|
use, intrinsic :: iso_fortran_env ! to get compiler_version and compiler_options (at least for gfortran 4.6 at the moment)
|
||||||
|
use prec, only: &
|
||||||
|
pReal, &
|
||||||
|
pInt
|
||||||
|
use IO, only: &
|
||||||
|
IO_timeStamp
|
||||||
|
use material
|
||||||
|
use numerics, only: &
|
||||||
|
worldrank
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
integer(pInt) :: &
|
||||||
|
homog, &
|
||||||
|
NofMyHomog
|
||||||
|
|
||||||
|
mainProcess: if (worldrank == 0) then
|
||||||
|
write(6,'(/,a)') ' <<<+- vacancyflux_'//VACANCYFLUX_isoconc_label//' init -+>>>'
|
||||||
|
write(6,'(a)') ' $Id$'
|
||||||
|
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||||
|
#include "compilation_info.f90"
|
||||||
|
endif mainProcess
|
||||||
|
|
||||||
|
initializeInstances: do homog = 1_pInt, material_Nhomogenization
|
||||||
|
|
||||||
|
myhomog: if (vacancyflux_type(homog) == VACANCYFLUX_isoconc_ID) then
|
||||||
|
NofMyHomog = count(material_homog == homog)
|
||||||
|
vacancyfluxState(homog)%sizeState = 0_pInt
|
||||||
|
vacancyfluxState(homog)%sizePostResults = 0_pInt
|
||||||
|
allocate(vacancyfluxState(homog)%state0 (0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(vacancyfluxState(homog)%subState0(0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
allocate(vacancyfluxState(homog)%state (0_pInt,NofMyHomog), source=0.0_pReal)
|
||||||
|
|
||||||
|
deallocate(vacancyConc (homog)%p)
|
||||||
|
allocate (vacancyConc (homog)%p(1), source=0.0_pReal)
|
||||||
|
deallocate(vacancyConcRate(homog)%p)
|
||||||
|
allocate (vacancyConcRate(homog)%p(1), source=0.0_pReal)
|
||||||
|
|
||||||
|
endif myhomog
|
||||||
|
enddo initializeInstances
|
||||||
|
|
||||||
|
|
||||||
|
end subroutine vacancyflux_isoconc_init
|
||||||
|
|
||||||
|
end module vacancyflux_isoconc
|
Loading…
Reference in New Issue