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
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
subroutine CPFEM_initAll(temperature,el,ip)
|
||||
subroutine CPFEM_initAll(temperature_inp,el,ip)
|
||||
use prec, only: &
|
||||
prec_init
|
||||
use numerics, only: &
|
||||
|
@ -79,7 +79,7 @@ subroutine CPFEM_initAll(temperature,el,ip)
|
|||
implicit none
|
||||
integer(pInt), intent(in) :: el, & !< FE el number
|
||||
ip !< FE integration point number
|
||||
real(pReal), intent(in) :: temperature !< temperature
|
||||
real(pReal), intent(in) :: temperature_inp !< temperature
|
||||
|
||||
!$OMP CRITICAL (init)
|
||||
if (.not. CPFEM_init_done) then
|
||||
|
@ -97,10 +97,10 @@ subroutine CPFEM_initAll(temperature,el,ip)
|
|||
call FE_init
|
||||
call mesh_init(ip, el) ! pass on coordinates to alter calcMode of first ip
|
||||
call lattice_init
|
||||
call material_init(temperature)
|
||||
call constitutive_init(temperature)
|
||||
call material_init
|
||||
call constitutive_init
|
||||
call crystallite_init
|
||||
call homogenization_init
|
||||
call homogenization_init(temperature_inp)
|
||||
call CPFEM_init
|
||||
#if defined(Marc4DAMASK) || defined(Abaqus)
|
||||
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
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
#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
|
||||
subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
||||
subroutine CPFEM_general(mode, ffn, ffn1, temperature_inp, dt, elFE, ip)
|
||||
#endif
|
||||
use numerics, only: &
|
||||
defgradTolerance, &
|
||||
|
@ -316,13 +316,19 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
|||
use material, only: &
|
||||
microstructure_elemhomo, &
|
||||
plasticState, &
|
||||
damageState, &
|
||||
sourceState, &
|
||||
homogState, &
|
||||
thermalState, &
|
||||
vacancyState,&
|
||||
damageState, &
|
||||
vacancyfluxState, &
|
||||
hydrogenfluxState, &
|
||||
mappingConstitutive, &
|
||||
material_phase, &
|
||||
phase_plasticity, &
|
||||
temperature, &
|
||||
thermalMapping, &
|
||||
phase_Nsources, &
|
||||
material_homog, &
|
||||
material_Nhomogenization
|
||||
use crystallite, only: &
|
||||
crystallite_partionedF,&
|
||||
|
@ -349,8 +355,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
|||
materialpoint_sizeResults, &
|
||||
#endif
|
||||
materialpoint_stressAndItsTangent, &
|
||||
materialpoint_postResults, &
|
||||
field_putFieldTemperature
|
||||
materialpoint_postResults
|
||||
use IO, only: &
|
||||
IO_write_jobRealFile, &
|
||||
IO_warning
|
||||
|
@ -359,7 +364,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
|||
implicit none
|
||||
integer(pInt), intent(in) :: elFE, & !< FE element 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), dimension (3,3), intent(in) :: ffn, & !< deformation gradient for t=t0
|
||||
ffn1 !< deformation gradient for t=t1
|
||||
|
@ -381,7 +386,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
|||
#endif
|
||||
|
||||
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
|
||||
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_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(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
|
||||
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
|
||||
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
|
||||
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
|
||||
do i = 1, size(sourceState)
|
||||
do mySource = 1,phase_Nsources(i)
|
||||
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
|
||||
write(6,'(a)') '<< CPFEM >> aging states'
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
@ -523,7 +533,8 @@ subroutine CPFEM_general(mode, ffn, ffn1, temperature, dt, elFE, ip)
|
|||
|
||||
if (.not. parallelExecution) then
|
||||
#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
|
||||
materialpoint_F0(1:3,1:3,ip,elCP) = ffn
|
||||
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)
|
||||
#endif
|
||||
#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
|
||||
materialpoint_F0(1:3,1:3,ip,elCP) = ffn
|
||||
materialpoint_F(1:3,1:3,ip,elCP) = ffn1
|
||||
|
|
|
@ -140,7 +140,7 @@ program DAMASK_spectral_Driver
|
|||
external :: quit
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! 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
|
||||
write(6,'(/,a)') ' <<<+- DAMASK_spectral_driver init -+>>>'
|
||||
write(6,'(a)') ' $Id$'
|
||||
|
|
|
@ -205,7 +205,7 @@ subroutine basicPETSc_init(temperature)
|
|||
call Utilities_updateIPcoords(F)
|
||||
call Utilities_constitutiveResponse(F_lastInc, F, &
|
||||
temperature, &
|
||||
0.0_pReal, &
|
||||
1.0_pReal, &
|
||||
P, &
|
||||
C_volAvg,C_minMaxAvg, & ! global average of stiffness and (min+max)/2
|
||||
temp33_Real, &
|
||||
|
|
|
@ -395,10 +395,13 @@ subroutine utilities_FFTforward()
|
|||
use numerics, only: &
|
||||
worldrank
|
||||
use mesh, only: &
|
||||
gridOffset, &
|
||||
gridLocal
|
||||
|
||||
implicit none
|
||||
external :: &
|
||||
MPI_Bcast, &
|
||||
MPI_reduce
|
||||
|
||||
integer(pInt) :: row, column ! if debug FFTW, compare 3D array field of row and column
|
||||
real(pReal), dimension(2) :: myRand, maxScalarField ! random numbers
|
||||
integer(pInt) :: i, j, k
|
||||
|
@ -433,7 +436,7 @@ subroutine utilities_FFTforward()
|
|||
field_fourierMPI(row,column,1:grid1Red,1:gridLocal(2),1:gridLocal(3)))/&
|
||||
scalarField_fourierMPI(1:grid1Red,1:gridLocal(2),1:gridLocal(3))
|
||||
else where
|
||||
scalarField_realMPI = cmplx(0.0,0.0,pReal)
|
||||
scalarField_fourierMPI = cmplx(0.0,0.0,pReal)
|
||||
end where
|
||||
maxScalarField(1) = maxval(real (scalarField_fourierMPI(1:grid1Red,1:gridLocal(2), &
|
||||
1:gridLocal(3))))
|
||||
|
@ -451,7 +454,7 @@ subroutine utilities_FFTforward()
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! applying filter
|
||||
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)
|
||||
enddo; enddo; enddo
|
||||
|
||||
|
@ -473,6 +476,10 @@ subroutine utilities_FFTbackward()
|
|||
gridLocal
|
||||
|
||||
implicit none
|
||||
external :: &
|
||||
MPI_Bcast, &
|
||||
MPI_reduce
|
||||
|
||||
integer(pInt) :: row, column !< if debug FFTW, compare 3D array field of row and column
|
||||
real(pReal), dimension(2) :: myRand
|
||||
real(pReal) :: maxScalarField
|
||||
|
@ -506,7 +513,7 @@ subroutine utilities_FFTbackward()
|
|||
- field_realMPI (row,column,1:gridLocal(1),1:gridLocal(2),1:gridLocal(3)))/ &
|
||||
scalarField_realMPI(1:gridLocal(1),1:gridLocal(2),1:gridLocal(3))
|
||||
else where
|
||||
scalarField_realMPI = cmplx(0.0,0.0,pReal)
|
||||
scalarField_realMPI = 0.0_pReal
|
||||
end where
|
||||
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)
|
||||
|
@ -627,6 +634,10 @@ real(pReal) function utilities_divergenceRMS()
|
|||
gridGlobal
|
||||
|
||||
implicit none
|
||||
external :: &
|
||||
MPI_reduce, &
|
||||
MPI_Allreduce
|
||||
|
||||
integer(pInt) :: i, j, k
|
||||
real(pReal) :: &
|
||||
err_real_div_RMS, & !< RMS of divergence in real space
|
||||
|
@ -714,6 +725,9 @@ real(pReal) function utilities_curlRMS()
|
|||
gridGlobal
|
||||
|
||||
implicit none
|
||||
external :: &
|
||||
MPI_Allreduce
|
||||
|
||||
integer(pInt) :: i, j, k, l
|
||||
complex(pReal), dimension(3,3) :: curl_fourier
|
||||
PetscErrorCode :: ierr
|
||||
|
@ -898,10 +912,14 @@ subroutine utilities_constitutiveResponse(F_lastInc,F,temperature,timeinc,&
|
|||
materialpoint_F, &
|
||||
materialpoint_P, &
|
||||
materialpoint_dPdF
|
||||
use thermal_isothermal, only: &
|
||||
thermal_isothermal_temperature
|
||||
! use thermal_isothermal, only: &
|
||||
! thermal_isothermal_temperature
|
||||
|
||||
implicit none
|
||||
external :: &
|
||||
MPI_reduce, &
|
||||
MPI_Allreduce
|
||||
|
||||
real(pReal), intent(in) :: temperature !< temperature (no field)
|
||||
real(pReal), intent(in), dimension(3,3,gridLocal(1),gridLocal(2),gridLocal(3)) :: &
|
||||
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), &
|
||||
temperature,timeinc,1_pInt,1_pInt)
|
||||
thermal_isothermal_temperature(:) = temperature
|
||||
! thermal_isothermal_temperature(:) = temperature
|
||||
materialpoint_F = reshape(F,[3,3,1,product(gridLocal)])
|
||||
|
||||
call debug_reset()
|
||||
|
@ -1044,6 +1062,9 @@ function utilities_forwardField(timeinc,field_lastInc,rate,aim)
|
|||
gridLocal
|
||||
|
||||
implicit none
|
||||
external :: &
|
||||
MPI_Allreduce
|
||||
|
||||
real(pReal), intent(in) :: &
|
||||
timeinc !< timeinc of current step
|
||||
real(pReal), intent(in), dimension(3,3,gridLocal(1),gridLocal(2),gridLocal(3)) :: &
|
||||
|
@ -1143,6 +1164,8 @@ subroutine utilities_updateIPcoords(F)
|
|||
geomSizeGlobal, &
|
||||
mesh_ipCoordinates
|
||||
implicit none
|
||||
external :: &
|
||||
MPI_Bcast
|
||||
|
||||
real(pReal), dimension(3,3,gridLocal(1),gridLocal(2),gridLocal(3)), intent(in) :: F
|
||||
integer(pInt) :: i, j, k, m
|
||||
|
|
210
code/Makefile
210
code/Makefile
|
@ -187,7 +187,8 @@ COMPILE_OPTIONS_gfortran +=-ffree-line-length-132\
|
|||
-Wsuggest-attribute=pure\
|
||||
-Wsuggest-attribute=noreturn\
|
||||
-Wconversion-extra\
|
||||
-Wimplicit-procedure
|
||||
-Wimplicit-procedure\
|
||||
-Wno-unused-parameter
|
||||
endif
|
||||
###################################################################################################
|
||||
#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_MAXOPTI =$(OPENMP_FLAG_$(F90)) $(COMPILE_OPTIONS_$(F90)) $(STANDARD_CHECK_$(F90)) $(OPTIMIZATION_$(MAXOPTI)_$(F90)) $(INCLUDE_DIRS) $(PRECISION_$(F90))
|
||||
###################################################################################################
|
||||
DAMAGE_FILES = \
|
||||
damage_none.o damage_isoBrittle.o damage_isoDuctile.o damage_gurson.o damage_anisoBrittle.o damage_anisoDuctile.o damage_phaseField.o
|
||||
|
||||
THERMAL_FILES = \
|
||||
thermal_isothermal.o thermal_adiabatic.o
|
||||
|
||||
VACANCY_FILES = \
|
||||
vacancy_constant.o vacancy_generation.o
|
||||
|
||||
SOURCE_FILES = \
|
||||
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
|
||||
|
||||
KINEMATICS_FILES = \
|
||||
kinematics_cleavage_opening.o kinematics_slipplane_opening.o \
|
||||
kinematics_thermal_expansion.o \
|
||||
kinematics_vacancy_strain.o kinematics_hydrogen_strain.o
|
||||
|
||||
PLASTIC_FILES = \
|
||||
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_RGC.o homogenization_isostrain.o homogenization_none.o homogenization.o
|
||||
homogenization_RGC.o homogenization_isostrain.o homogenization_none.o
|
||||
|
||||
#####################
|
||||
# Spectral Solver
|
||||
|
@ -332,12 +348,17 @@ DAMASK_spectral.exe: MESHNAME := mesh.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 \
|
||||
FEsolving.o mesh.o material.o lattice.o constitutive.o \
|
||||
$(DAMAGE_FILES) $(THERMAL_FILES) $(VACANCY_FILES) $(PLASTIC_FILES) \
|
||||
crystallite.o $(HOMOGENIZATION_FILES) CPFEM.o \
|
||||
FEsolving.o mesh.o material.o lattice.o \
|
||||
$(SOURCE_FILES) $(KINEMATICS_FILES) $(PLASTIC_FILES) constitutive.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_solverAL.o DAMASK_spectral_solverBasicPETSc.o DAMASK_spectral_solverPolarisation.o
|
||||
$(SPECTRAL_SOLVER_FILES)
|
||||
|
||||
DAMASK_spectral.exe: DAMASK_spectral_driver.o
|
||||
$(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_solverAL.o \
|
||||
DAMASK_spectral_solverBasicPETSc.o \
|
||||
DAMASK_spectral_solverPolarisation.o
|
||||
$(SPECTRAL_SOLVER_FILES)
|
||||
$(PREFIX) $(COMPILERNAME) $(COMPILE_MAXOPTI) -c DAMASK_spectral_driver.f90 $(SUFFIX)
|
||||
|
||||
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: 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 \
|
||||
FEsolving.o mesh.o material.o lattice.o \
|
||||
$(DAMAGE_FILES) $(THERMAL_FILES) $(VACANCY_FILES) $(PLASTIC_FILES) \
|
||||
crystallite.o $(HOMOGENIZATION_FILES) CPFEM.o \
|
||||
FEM_utilities.o FEM_mech.o FEM_thermal.o FEM_damage.o FEM_vacancyDiffusion.o
|
||||
$(SOURCE_FILES) $(KINEMATICS_FILES) $(PLASTIC_FILES) constitutive.o \
|
||||
crystallite.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
|
||||
$(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 \
|
||||
$(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)
|
||||
|
||||
FEM_mech.o: FEM_mech.f90 \
|
||||
|
@ -396,7 +420,13 @@ FEM_thermal.o: FEM_thermal.f90 \
|
|||
FEM_damage.o: FEM_damage.f90 \
|
||||
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.f90 \
|
||||
|
@ -411,9 +441,54 @@ CPFEM.o: CPFEM.f90\
|
|||
homogenization.o
|
||||
|
||||
homogenization.o: homogenization.f90\
|
||||
homogenization_none.o \
|
||||
homogenization_RGC.o \
|
||||
homogenization_isostrain.o
|
||||
$(THERMAL_FILES) \
|
||||
$(DAMAGE_FILES) \
|
||||
$(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 \
|
||||
crystallite.o
|
||||
|
@ -428,11 +503,49 @@ crystallite.o: crystallite.f90 \
|
|||
constitutive.o
|
||||
|
||||
constitutive.o: constitutive.f90 \
|
||||
$(PLASTIC_FILES) \
|
||||
$(DAMAGE_FILES) \
|
||||
$(THERMAL_FILES) \
|
||||
$(VACANCY_FILES)
|
||||
$(SOURCE_FILES) \
|
||||
$(KINEMATICS_FILES) \
|
||||
$(PLASTIC_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 \
|
||||
lattice.o
|
||||
|
||||
|
@ -457,39 +570,6 @@ plastic_j2.o: plastic_j2.f90 \
|
|||
plastic_none.o: plastic_none.f90 \
|
||||
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 \
|
||||
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
|
||||
!> @brief all DAMASK files without solver
|
||||
|
@ -14,17 +14,19 @@
|
|||
#include "mesh.f90"
|
||||
#include "material.f90"
|
||||
#include "lattice.f90"
|
||||
#include "damage_none.f90"
|
||||
#include "damage_isoBrittle.f90"
|
||||
#include "damage_isoDuctile.f90"
|
||||
#include "damage_anisoBrittle.f90"
|
||||
#include "damage_anisoDuctile.f90"
|
||||
#include "damage_gurson.f90"
|
||||
#include "damage_phaseField.f90"
|
||||
#include "thermal_isothermal.f90"
|
||||
#include "thermal_adiabatic.f90"
|
||||
#include "vacancy_constant.f90"
|
||||
#include "vacancy_generation.f90"
|
||||
#include "source_thermal_dissipation.f90"
|
||||
#include "source_damage_isoBrittle.f90"
|
||||
#include "source_damage_isoDuctile.f90"
|
||||
#include "source_damage_anisoBrittle.f90"
|
||||
#include "source_damage_anisoDuctile.f90"
|
||||
#include "source_vacancy_phenoplasticity.f90"
|
||||
#include "source_vacancy_irradiation.f90"
|
||||
#include "source_vacancy_thermalfluc.f90"
|
||||
#include "kinematics_cleavage_opening.f90"
|
||||
#include "kinematics_slipplane_opening.f90"
|
||||
#include "kinematics_thermal_expansion.f90"
|
||||
#include "kinematics_vacancy_strain.f90"
|
||||
#include "kinematics_hydrogen_strain.f90"
|
||||
#include "plastic_none.f90"
|
||||
#include "plastic_j2.f90"
|
||||
#include "plastic_phenopowerlaw.f90"
|
||||
|
@ -38,5 +40,18 @@
|
|||
#include "homogenization_none.f90"
|
||||
#include "homogenization_isostrain.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 "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$
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @brief material subroutine for purely elastic material
|
||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @brief material subroutine for constant damage field
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
module damage_none
|
||||
use prec, only: &
|
||||
pInt
|
||||
|
||||
implicit none
|
||||
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 :: &
|
||||
damage_none_init
|
||||
|
||||
contains
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief module initialization
|
||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||
!> @brief allocates all neccessary fields, reads information from material configuration file
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
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 debug, only: &
|
||||
debug_level, &
|
||||
debug_constitutive, &
|
||||
debug_levelBasic
|
||||
use prec, only: &
|
||||
pReal, &
|
||||
pInt
|
||||
use IO, only: &
|
||||
IO_timeStamp
|
||||
use material
|
||||
use numerics, only: &
|
||||
worldrank, &
|
||||
numerics_integrator
|
||||
use material, only: &
|
||||
phase_damage, &
|
||||
LOCAL_DAMAGE_NONE_label, &
|
||||
LOCAL_DAMAGE_NONE_ID, &
|
||||
material_phase, &
|
||||
damageState
|
||||
|
||||
worldrank
|
||||
|
||||
implicit none
|
||||
|
||||
integer(pInt) :: &
|
||||
maxNinstance, &
|
||||
phase, &
|
||||
NofMyPhase, &
|
||||
sizeState, &
|
||||
sizeDotState
|
||||
homog, &
|
||||
NofMyHomog
|
||||
|
||||
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,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||
#include "compilation_info.f90"
|
||||
endif mainProcess
|
||||
|
||||
maxNinstance = int(count(phase_damage == LOCAL_DAMAGE_NONE_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_damage)
|
||||
NofMyPhase=count(material_phase==phase)
|
||||
if (phase_damage(phase) == LOCAL_DAMAGE_none_ID) then
|
||||
sizeState = 0_pInt
|
||||
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
|
||||
initializeInstances: do homog = 1_pInt, material_Nhomogenization
|
||||
|
||||
myhomog: if (damage_type(homog) == DAMAGE_none_ID) then
|
||||
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)
|
||||
|
||||
deallocate(damage(homog)%p)
|
||||
allocate (damage(homog)%p(1), source=1.0_pReal)
|
||||
|
||||
endif myhomog
|
||||
enddo initializeInstances
|
||||
|
||||
allocate(damage_none_sizePostResults(maxNinstance), source=0_pInt)
|
||||
|
||||
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: &
|
||||
homogenization_maxNgrains, &
|
||||
homogenization_Ngrains,&
|
||||
mappingHomogenization, &
|
||||
homogenization_typeInstance
|
||||
use FEsolving, only: &
|
||||
theInc,&
|
||||
|
@ -903,7 +902,6 @@ subroutine homogenization_RGC_averageStressAndItsTangent(avgP,dAvgPdAvgF,P,dPdF,
|
|||
use mesh, only: mesh_element
|
||||
use material, only: &
|
||||
homogenization_maxNgrains, &
|
||||
mappingHomogenization, &
|
||||
homogenization_Ngrains, &
|
||||
homogenization_typeInstance
|
||||
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_thermalExpansion33, &
|
||||
lattice_damageDiffusion33, &
|
||||
lattice_vacancyDiffusion33
|
||||
lattice_vacancyfluxDiffusion33, &
|
||||
lattice_vacancyfluxMobility33, &
|
||||
lattice_porosityDiffusion33, &
|
||||
lattice_hydrogenfluxDiffusion33, &
|
||||
lattice_hydrogenfluxMobility33
|
||||
real(pReal), dimension(:), allocatable, public, protected :: &
|
||||
lattice_damageMobility, &
|
||||
lattice_vacancyMobility, &
|
||||
lattice_porosityMobility, &
|
||||
lattice_massDensity, &
|
||||
lattice_specificHeat, &
|
||||
lattice_vacancyVol, &
|
||||
lattice_hydrogenVol, &
|
||||
lattice_referenceTemperature, &
|
||||
lattice_equilibriumVacancyConcentration
|
||||
enum, bind(c)
|
||||
|
@ -1101,15 +1107,21 @@ subroutine lattice_init
|
|||
allocate(lattice_structure(Nphases),source = LATTICE_undefined_ID)
|
||||
allocate(lattice_C66(6,6,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_thermalExpansion33 (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_damageMobility ( Nphases), source=0.0_pReal)
|
||||
allocate(lattice_vacancyMobility ( Nphases), source=0.0_pReal)
|
||||
allocate(lattice_massDensity ( Nphases), source=0.0_pReal)
|
||||
allocate(lattice_specificHeat ( Nphases), source=0.0_pReal)
|
||||
allocate(lattice_referenceTemperature ( 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_damageDiffusion33 (3,3,Nphases), source=0.0_pReal)
|
||||
allocate(lattice_vacancyfluxDiffusion33 (3,3,Nphases), source=0.0_pReal)
|
||||
allocate(lattice_vacancyfluxMobility33 (3,3,Nphases), source=0.0_pReal)
|
||||
allocate(lattice_PorosityDiffusion33 (3,3,Nphases), source=0.0_pReal)
|
||||
allocate(lattice_hydrogenfluxDiffusion33(3,3,Nphases), source=0.0_pReal)
|
||||
allocate(lattice_hydrogenfluxMobility33 (3,3,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_mu(Nphases), source=0.0_pReal)
|
||||
|
@ -1232,6 +1244,10 @@ subroutine lattice_init
|
|||
lattice_thermalExpansion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('specific_heat')
|
||||
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')
|
||||
lattice_massDensity(section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('reference_temperature')
|
||||
|
@ -1244,14 +1260,38 @@ subroutine lattice_init
|
|||
lattice_DamageDiffusion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('damage_mobility')
|
||||
lattice_DamageMobility(section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('vacancy_diffusion11')
|
||||
lattice_VacancyDiffusion33(1,1,section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('vacancy_diffusion22')
|
||||
lattice_VacancyDiffusion33(2,2,section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('vacancy_diffusion33')
|
||||
lattice_VacancyDiffusion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('vacancy_mobility')
|
||||
lattice_VacancyMobility(section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('vacancyflux_diffusion11')
|
||||
lattice_vacancyfluxDiffusion33(1,1,section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('vacancyflux_diffusion22')
|
||||
lattice_vacancyfluxDiffusion33(2,2,section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('vacancyflux_diffusion33')
|
||||
lattice_vacancyfluxDiffusion33(3,3,section) = IO_floatValue(line,positions,2_pInt)
|
||||
case ('vacancyflux_mobility11')
|
||||
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')
|
||||
lattice_equilibriumVacancyConcentration(section) = IO_floatValue(line,positions,2_pInt)
|
||||
end select
|
||||
|
@ -1322,7 +1362,7 @@ subroutine lattice_initializeStructure(myPhase,CoverA,aA,aM,cM)
|
|||
cd, cn, ct
|
||||
integer(pInt) :: &
|
||||
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))
|
||||
|
@ -1347,8 +1387,16 @@ subroutine lattice_initializeStructure(myPhase,CoverA,aA,aM,cM)
|
|||
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_VacancyDiffusion33(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_symmetrize33(lattice_structure(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))
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -14,41 +14,55 @@ module material
|
|||
pInt, &
|
||||
tState, &
|
||||
tPlasticState, &
|
||||
tFieldData, &
|
||||
tSourceState, &
|
||||
tHomogMapping, &
|
||||
tPhaseMapping, &
|
||||
p_vec, &
|
||||
p_intvec
|
||||
|
||||
implicit none
|
||||
private
|
||||
character(len=*), parameter, public :: &
|
||||
ELASTICITY_hooke_label = 'hooke', &
|
||||
PLASTICITY_none_label = 'none', &
|
||||
PLASTICITY_j2_label = 'j2', &
|
||||
PLASTICITY_phenopowerlaw_label = 'phenopowerlaw', &
|
||||
PLASTICITY_dislotwin_label = 'dislotwin', &
|
||||
PLASTICITY_dislokmc_label = 'dislokmc', &
|
||||
PLASTICITY_disloucla_label = 'disloucla', &
|
||||
PLASTICITY_titanmod_label = 'titanmod', &
|
||||
PLASTICITY_nonlocal_label = 'nonlocal', &
|
||||
LOCAL_DAMAGE_none_LABEL = 'none', &
|
||||
LOCAL_DAMAGE_isoBrittle_LABEL = 'isobrittle', &
|
||||
LOCAL_DAMAGE_isoDuctile_LABEL = 'isoductile', &
|
||||
LOCAL_DAMAGE_anisoBrittle_LABEL= 'anisobrittle', &
|
||||
LOCAL_DAMAGE_anisoDuctile_LABEL= 'anisoductile', &
|
||||
LOCAL_DAMAGE_gurson_LABEL = 'gurson', &
|
||||
LOCAL_DAMAGE_phaseField_LABEL = 'phasefield', &
|
||||
LOCAL_THERMAL_isothermal_label = 'isothermal', &
|
||||
LOCAL_THERMAL_adiabatic_label = 'adiabatic', &
|
||||
LOCAL_VACANCY_constant_label = 'constant', &
|
||||
LOCAL_VACANCY_generation_label = 'generation', &
|
||||
FIELD_DAMAGE_local_label = 'local', &
|
||||
FIELD_DAMAGE_nonlocal_label = 'nonlocal', &
|
||||
FIELD_THERMAL_local_label = 'local', &
|
||||
FIELD_THERMAL_nonlocal_label = 'nonlocal', &
|
||||
FIELD_VACANCY_local_label = 'local', &
|
||||
FIELD_VACANCY_nonlocal_label = 'nonlocal', &
|
||||
HOMOGENIZATION_none_label = 'none', &
|
||||
HOMOGENIZATION_isostrain_label = 'isostrain', &
|
||||
HOMOGENIZATION_rgc_label = 'rgc'
|
||||
ELASTICITY_hooke_label = 'hooke', &
|
||||
PLASTICITY_none_label = 'none', &
|
||||
PLASTICITY_j2_label = 'j2', &
|
||||
PLASTICITY_phenopowerlaw_label = 'phenopowerlaw', &
|
||||
PLASTICITY_dislotwin_label = 'dislo&twin', &
|
||||
PLASTICITY_dislokmc_label = 'dislokmc', &
|
||||
PLASTICITY_disloucla_label = 'disloucla', &
|
||||
PLASTICITY_titanmod_label = 'titanmod', &
|
||||
PLASTICITY_nonlocal_label = 'nonlocal', &
|
||||
SOURCE_thermal_dissipation_label = 'thermal_dissipation', &
|
||||
SOURCE_damage_isoBrittle_label = 'damage_isobrittle', &
|
||||
SOURCE_damage_isoDuctile_label = 'damage_isoductile', &
|
||||
SOURCE_damage_anisoBrittle_label = 'damage_anisobrittle', &
|
||||
SOURCE_damage_anisoDuctile_label = 'damage_anisoductile', &
|
||||
SOURCE_vacancy_phenoplasticity_label = 'vacancy_phenoplasticity', &
|
||||
SOURCE_vacancy_irradiation_label = 'vacancy_irradiation', &
|
||||
SOURCE_vacancy_thermalfluc_label = 'vacancy_thermalfluctuation', &
|
||||
KINEMATICS_thermal_expansion_label = 'thermal_expansion', &
|
||||
KINEMATICS_cleavage_opening_label = 'cleavage_opening', &
|
||||
KINEMATICS_slipplane_opening_label = 'slipplane_opening', &
|
||||
KINEMATICS_vacancy_strain_label = 'vacancy_strain', &
|
||||
KINEMATICS_hydrogen_strain_label = 'hydrogen_strain', &
|
||||
STIFFNESS_DEGRADATION_damage_label = 'damage', &
|
||||
STIFFNESS_DEGRADATION_porosity_label = 'porosity', &
|
||||
THERMAL_isothermal_label = 'isothermal', &
|
||||
THERMAL_adiabatic_label = 'adiabatic', &
|
||||
THERMAL_conduction_label = 'conduction', &
|
||||
DAMAGE_none_label = 'none', &
|
||||
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_nonlocal_ID
|
||||
end enum
|
||||
|
||||
enum, bind(c)
|
||||
enumerator :: LOCAL_DAMAGE_none_ID, &
|
||||
LOCAL_DAMAGE_isoBrittle_ID, &
|
||||
LOCAL_DAMAGE_isoDuctile_ID, &
|
||||
LOCAL_DAMAGE_anisoBrittle_ID, &
|
||||
LOCAL_DAMAGE_anisoDuctile_ID, &
|
||||
LOCAL_DAMAGE_gurson_ID, &
|
||||
LOCAL_DAMAGE_phaseField_ID
|
||||
end enum
|
||||
enum, bind(c)
|
||||
enumerator :: LOCAL_THERMAL_isothermal_ID, &
|
||||
LOCAL_THERMAL_adiabatic_ID
|
||||
end enum
|
||||
enum, bind(c)
|
||||
enumerator :: LOCAL_VACANCY_constant_ID, &
|
||||
LOCAL_VACANCY_generation_ID
|
||||
enumerator :: SOURCE_undefined_ID, &
|
||||
SOURCE_thermal_dissipation_ID, &
|
||||
SOURCE_damage_isoBrittle_ID, &
|
||||
SOURCE_damage_isoDuctile_ID, &
|
||||
SOURCE_damage_anisoBrittle_ID, &
|
||||
SOURCE_damage_anisoDuctile_ID, &
|
||||
SOURCE_vacancy_phenoplasticity_ID, &
|
||||
SOURCE_vacancy_irradiation_ID, &
|
||||
SOURCE_vacancy_thermalfluc_ID
|
||||
end enum
|
||||
|
||||
enum, bind(c)
|
||||
enumerator :: FIELD_DAMAGE_local_ID ,&
|
||||
FIELD_DAMAGE_nonlocal_ID
|
||||
|
||||
enumerator :: KINEMATICS_undefined_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
|
||||
enum, bind(c)
|
||||
enumerator :: FIELD_THERMAL_local_ID, &
|
||||
FIELD_THERMAL_nonlocal_ID
|
||||
end enum
|
||||
enum, bind(c)
|
||||
enumerator :: FIELD_VACANCY_local_ID, &
|
||||
FIELD_VACANCY_nonlocal_ID
|
||||
enumerator :: HYDROGENFLUX_isoconc_ID, &
|
||||
HYDROGENFLUX_cahnhilliard_ID
|
||||
end enum
|
||||
|
||||
enum, bind(c)
|
||||
enumerator :: HOMOGENIZATION_undefined_ID, &
|
||||
HOMOGENIZATION_none_ID, &
|
||||
|
@ -118,18 +156,21 @@ module material
|
|||
phase_elasticity !< elasticity of each phase
|
||||
integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable, public, protected :: &
|
||||
phase_plasticity !< plasticity of each phase
|
||||
integer(kind(LOCAL_DAMAGE_none_ID)), dimension(:), allocatable, public, protected :: &
|
||||
phase_damage !< local damage of each phase
|
||||
integer(kind(LOCAL_THERMAL_isothermal_ID)), dimension(:), allocatable, public, protected :: &
|
||||
phase_thermal !< local thermal of each phase
|
||||
integer(kind(LOCAL_VACANCY_constant_ID)), dimension(:), allocatable, public, protected :: &
|
||||
phase_vacancy !< local vacancy model of each phase
|
||||
integer(kind(FIELD_DAMAGE_local_ID)), dimension(:), allocatable, public, protected :: &
|
||||
field_damage_type !< field damage of each phase
|
||||
integer(kind(FIELD_THERMAL_local_ID)), dimension(:), allocatable, public, protected :: &
|
||||
field_thermal_type !< field thermal of each phase
|
||||
integer(kind(FIELD_VACANCY_local_ID)), dimension(:), allocatable, public, protected :: &
|
||||
field_vacancy_type !< field vacancy of each phase
|
||||
integer(kind(THERMAL_isothermal_ID)), dimension(:), allocatable, public, protected :: &
|
||||
thermal_type !< thermal transport model
|
||||
integer(kind(DAMAGE_none_ID)), dimension(:), allocatable, public, protected :: &
|
||||
damage_type !< nonlocal damage model
|
||||
integer(kind(VACANCYFLUX_isoconc_ID)), dimension(:), allocatable, public, protected :: &
|
||||
vacancyflux_type !< vacancy transport model
|
||||
integer(kind(POROSITY_none_ID)), dimension(:), allocatable, public, protected :: &
|
||||
porosity_type !< porosity evolution model
|
||||
integer(kind(HYDROGENFLUX_isoconc_ID)), dimension(:), allocatable, public, protected :: &
|
||||
hydrogenflux_type !< hydrogen transport model
|
||||
|
||||
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 :: &
|
||||
homogenization_type !< type of each homogenization
|
||||
|
@ -146,17 +187,24 @@ module material
|
|||
material_Nmicrostructure, & !< number of microstructures
|
||||
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 :: &
|
||||
homogenization_Ngrains, & !< number of grains in each homogenization
|
||||
homogenization_Noutput, & !< number of '(output)' items per homogenization
|
||||
phase_Noutput, & !< number of '(output)' items per phase
|
||||
phase_elasticityInstance, & !< instance of particular elasticity 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
|
||||
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
|
||||
|
||||
integer(pInt), dimension(:,:,:), allocatable, public :: &
|
||||
|
@ -165,19 +213,15 @@ module material
|
|||
material_homog !< homogenization (index) of each IP,element
|
||||
type(tPlasticState), allocatable, dimension(:), public :: &
|
||||
plasticState
|
||||
type(tState), allocatable, dimension(:), public :: &
|
||||
type(tSourceState), allocatable, dimension(:), public :: &
|
||||
sourceState
|
||||
type(tState), allocatable, dimension(:), public :: &
|
||||
homogState, &
|
||||
thermalState, &
|
||||
damageState, &
|
||||
thermalState,&
|
||||
vacancyState,&
|
||||
homogState
|
||||
|
||||
type(tFieldData), allocatable, dimension(:), public :: &
|
||||
fieldDamage
|
||||
type(tFieldData), allocatable, dimension(:), public :: &
|
||||
fieldThermal
|
||||
type(tFieldData), allocatable, dimension(:), public :: &
|
||||
fieldVacancy
|
||||
|
||||
vacancyfluxState, &
|
||||
porosityState, &
|
||||
hydrogenfluxState
|
||||
|
||||
integer(pInt), dimension(:,:,:), allocatable, public, protected :: &
|
||||
material_texture !< texture (index) of each grain,IP,element
|
||||
|
@ -230,9 +274,27 @@ module material
|
|||
logical, dimension(:), allocatable, private :: &
|
||||
homogenization_active
|
||||
|
||||
integer(pInt), dimension(:,:,:,:), allocatable, public, protected :: mappingConstitutive
|
||||
integer(pInt), dimension(:,:,:), allocatable, public, protected :: mappingCrystallite
|
||||
integer(pInt), dimension(:,:,:), allocatable, public, protected :: mappingHomogenization
|
||||
integer(pInt), dimension(:,:,:,:), allocatable, public, target :: mappingConstitutive
|
||||
integer(pInt), dimension(:,:,:), allocatable, public, target :: mappingCrystallite
|
||||
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 :: &
|
||||
material_init, &
|
||||
|
@ -245,23 +307,34 @@ module material
|
|||
PLASTICITY_disloucla_ID, &
|
||||
PLASTICITY_titanmod_ID, &
|
||||
PLASTICITY_nonlocal_ID, &
|
||||
LOCAL_DAMAGE_none_ID, &
|
||||
LOCAL_DAMAGE_isoBrittle_ID, &
|
||||
LOCAL_DAMAGE_isoDuctile_ID, &
|
||||
LOCAL_DAMAGE_anisoBrittle_ID, &
|
||||
LOCAL_DAMAGE_anisoDuctile_ID, &
|
||||
LOCAL_DAMAGE_gurson_ID, &
|
||||
LOCAL_DAMAGE_phaseField_ID, &
|
||||
LOCAL_THERMAL_isothermal_ID, &
|
||||
LOCAL_THERMAL_adiabatic_ID, &
|
||||
LOCAL_VACANCY_constant_ID, &
|
||||
LOCAL_VACANCY_generation_ID, &
|
||||
FIELD_DAMAGE_local_ID, &
|
||||
FIELD_DAMAGE_nonlocal_ID, &
|
||||
FIELD_THERMAL_local_ID, &
|
||||
FIELD_THERMAL_nonlocal_ID, &
|
||||
FIELD_VACANCY_local_ID, &
|
||||
FIELD_VACANCY_nonlocal_ID, &
|
||||
SOURCE_thermal_dissipation_ID, &
|
||||
SOURCE_damage_isoBrittle_ID, &
|
||||
SOURCE_damage_isoDuctile_ID, &
|
||||
SOURCE_damage_anisoBrittle_ID, &
|
||||
SOURCE_damage_anisoDuctile_ID, &
|
||||
SOURCE_vacancy_phenoplasticity_ID, &
|
||||
SOURCE_vacancy_irradiation_ID, &
|
||||
SOURCE_vacancy_thermalfluc_ID, &
|
||||
KINEMATICS_cleavage_opening_ID, &
|
||||
KINEMATICS_slipplane_opening_ID, &
|
||||
KINEMATICS_thermal_expansion_ID, &
|
||||
KINEMATICS_vacancy_strain_ID, &
|
||||
KINEMATICS_hydrogen_strain_ID, &
|
||||
STIFFNESS_DEGRADATION_damage_ID, &
|
||||
STIFFNESS_DEGRADATION_porosity_ID, &
|
||||
THERMAL_isothermal_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_isostrain_ID, &
|
||||
#ifdef HDF
|
||||
|
@ -285,7 +358,7 @@ contains
|
|||
!> @details figures out if solverJobName.materialConfig is present, if not looks for
|
||||
!> 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 IO, only: &
|
||||
IO_error, &
|
||||
|
@ -307,16 +380,13 @@ subroutine material_init(temperature_init)
|
|||
worldrank
|
||||
|
||||
implicit none
|
||||
real(pReal), intent(in) :: temperature_init !< initial field temperature
|
||||
integer(pInt), parameter :: FILEUNIT = 200_pInt
|
||||
integer(pInt) :: m,c,h, myDebug, myHomog
|
||||
integer(pInt) :: m,c,h, myDebug, myPhase, myHomog
|
||||
integer(pInt) :: &
|
||||
g, & !< grain number
|
||||
i, & !< integration point number
|
||||
e, & !< element number
|
||||
phase, &
|
||||
homog, &
|
||||
NofMyField
|
||||
phase
|
||||
integer(pInt), dimension(:), allocatable :: ConstitutivePosition
|
||||
integer(pInt), dimension(:), allocatable :: CrystallitePosition
|
||||
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)
|
||||
close(FILEUNIT)
|
||||
|
||||
allocate(plasticState(material_Nphase))
|
||||
allocate(damageState (material_Nphase))
|
||||
allocate(thermalState(material_Nphase))
|
||||
allocate(vacancyState(material_Nphase))
|
||||
allocate(homogState (material_Nhomogenization))
|
||||
allocate(fieldDamage (material_Nhomogenization))
|
||||
allocate(fieldThermal(material_Nhomogenization))
|
||||
allocate(fieldVacancy(material_Nhomogenization))
|
||||
allocate(plasticState (material_Nphase))
|
||||
allocate(sourceState (material_Nphase))
|
||||
do myPhase = 1,material_Nphase
|
||||
allocate(sourceState(myPhase)%p(phase_Nsources(myPhase)))
|
||||
enddo
|
||||
|
||||
allocate(homogState (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
|
||||
if(microstructure_crystallite(m) < 1_pInt .or. &
|
||||
microstructure_crystallite(m) > material_Ncrystallite) &
|
||||
|
@ -365,6 +456,7 @@ subroutine material_init(temperature_init)
|
|||
if(microstructure_Nconstituents(m) < 1_pInt) &
|
||||
call IO_error(151_pInt,m)
|
||||
enddo
|
||||
|
||||
debugOut: if (iand(myDebug,debug_levelExtensive) /= 0_pInt) then
|
||||
write(6,'(/,a,/)') ' MATERIAL configuration'
|
||||
write(6,'(a32,1x,a16,1x,a6)') 'homogenization ','type ','grains'
|
||||
|
@ -390,14 +482,14 @@ subroutine material_init(temperature_init)
|
|||
|
||||
call material_populateGrains
|
||||
|
||||
allocate(mappingConstitutive(2,homogenization_maxNgrains,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(ConstitutivePosition(material_Nphase),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(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(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
|
||||
myHomog = mesh_element(3,e)
|
||||
|
@ -412,57 +504,23 @@ subroutine material_init(temperature_init)
|
|||
enddo IPloop
|
||||
enddo ElemLoop
|
||||
|
||||
do homog = 1,material_Nhomogenization
|
||||
NofMyField=count(material_homog==homog)
|
||||
select case(field_damage_type(homog))
|
||||
case (FIELD_DAMAGE_LOCAL_ID)
|
||||
fieldDamage(homog)%sizeField = 0_pInt
|
||||
fieldDamage(homog)%sizePostResults = 0_pInt
|
||||
allocate(fieldDamage(homog)%field(fieldDamage(homog)%sizeField,NofMyField), source = 1.0_pReal)
|
||||
|
||||
case (FIELD_DAMAGE_NONLOCAL_ID)
|
||||
fieldDamage(homog)%sizeField = 1_pInt
|
||||
fieldDamage(homog)%sizePostResults = 1_pInt
|
||||
allocate(fieldDamage(homog)%field(fieldDamage(homog)%sizeField,NofMyField), source = 1.0_pReal)
|
||||
|
||||
end select
|
||||
! hack needed to initialize field values used during constitutive and crystallite initializations
|
||||
do myHomog = 1,material_Nhomogenization
|
||||
thermalMapping (myHomog)%p => mappingHomogenizationConst
|
||||
damageMapping (myHomog)%p => mappingHomogenizationConst
|
||||
vacancyfluxMapping (myHomog)%p => mappingHomogenizationConst
|
||||
porosityMapping (myHomog)%p => mappingHomogenizationConst
|
||||
hydrogenfluxMapping(myHomog)%p => mappingHomogenizationConst
|
||||
allocate(temperature (myHomog)%p(1), source=300.0_pReal)
|
||||
allocate(damage (myHomog)%p(1), source=1.0_pReal)
|
||||
allocate(vacancyConc (myHomog)%p(1), source=0.0_pReal)
|
||||
allocate(porosity (myHomog)%p(1), source=1.0_pReal)
|
||||
allocate(hydrogenConc (myHomog)%p(1), source=0.0_pReal)
|
||||
allocate(temperatureRate (myHomog)%p(1), source=0.0_pReal)
|
||||
allocate(vacancyConcRate (myHomog)%p(1), source=0.0_pReal)
|
||||
allocate(hydrogenConcRate(myHomog)%p(1), source=0.0_pReal)
|
||||
enddo
|
||||
|
||||
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
|
||||
|
||||
end subroutine material_init
|
||||
|
||||
|
||||
|
@ -493,7 +551,7 @@ subroutine material_parseHomogenization(fileUnit,myPart)
|
|||
integer(pInt), parameter :: MAXNCHUNKS = 2_pInt
|
||||
|
||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||
integer(pInt) :: Nsections, section, s
|
||||
integer(pInt) :: Nsections, section, s, p
|
||||
character(len=65536) :: &
|
||||
tag, line
|
||||
logical :: echo
|
||||
|
@ -504,11 +562,18 @@ subroutine material_parseHomogenization(fileUnit,myPart)
|
|||
if (Nsections < 1_pInt) call IO_error(160_pInt,ext_msg=myPart)
|
||||
|
||||
allocate(homogenization_name(Nsections)); homogenization_name = ''
|
||||
allocate(homogenization_type(Nsections), source=HOMOGENIZATION_undefined_ID)
|
||||
allocate(FIELD_DAMAGE_type(Nsections), source=FIELD_DAMAGE_local_ID)
|
||||
allocate(FIELD_THERMAL_type(Nsections), source=FIELD_THERMAL_local_ID)
|
||||
allocate(FIELD_VACANCY_type(Nsections), source=FIELD_VACANCY_local_ID)
|
||||
allocate(homogenization_type(Nsections), source=HOMOGENIZATION_undefined_ID)
|
||||
allocate(thermal_type(Nsections), source=THERMAL_isothermal_ID)
|
||||
allocate(damage_type (Nsections), source=DAMAGE_none_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(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_Noutput(Nsections), source=0_pInt)
|
||||
allocate(homogenization_active(Nsections), source=.false.) !!!!!!!!!!!!!!!
|
||||
|
@ -554,32 +619,58 @@ subroutine material_parseHomogenization(fileUnit,myPart)
|
|||
end select
|
||||
homogenization_typeInstance(section) = &
|
||||
count(homogenization_type==homogenization_type(section)) ! count instances
|
||||
case ('field_damage')
|
||||
case ('thermal')
|
||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||
case(FIELD_DAMAGE_LOCAL_label)
|
||||
FIELD_DAMAGE_type(section) = FIELD_DAMAGE_LOCAL_ID
|
||||
case(FIELD_DAMAGE_NONLOCAL_label)
|
||||
FIELD_DAMAGE_type(section) = FIELD_DAMAGE_NONLOCAL_ID
|
||||
case default
|
||||
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||
end select
|
||||
|
||||
case ('field_thermal')
|
||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||
case(FIELD_THERMAL_local_label)
|
||||
FIELD_THERMAL_type(section) = FIELD_THERMAL_local_ID
|
||||
case(FIELD_THERMAL_nonlocal_label)
|
||||
FIELD_THERMAL_type(section) = FIELD_THERMAL_nonlocal_ID
|
||||
case(THERMAL_isothermal_label)
|
||||
thermal_type(section) = THERMAL_isothermal_ID
|
||||
case(THERMAL_adiabatic_label)
|
||||
thermal_type(section) = THERMAL_adiabatic_ID
|
||||
case(THERMAL_conduction_label)
|
||||
thermal_type(section) = THERMAL_conduction_ID
|
||||
case default
|
||||
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||
end select
|
||||
|
||||
case ('field_vacancy')
|
||||
case ('damage')
|
||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||
case(FIELD_VACANCY_local_label)
|
||||
FIELD_VACANCY_type(section) = FIELD_VACANCY_local_ID
|
||||
case(FIELD_VACANCY_nonlocal_label)
|
||||
FIELD_VACANCY_type(section) = FIELD_VACANCY_nonlocal_ID
|
||||
case(DAMAGE_NONE_label)
|
||||
damage_type(section) = DAMAGE_none_ID
|
||||
case(DAMAGE_LOCAL_label)
|
||||
damage_type(section) = DAMAGE_local_ID
|
||||
case(DAMAGE_NONLOCAL_label)
|
||||
damage_type(section) = DAMAGE_nonlocal_ID
|
||||
case default
|
||||
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||
end select
|
||||
|
||||
case ('vacancyflux')
|
||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||
case(VACANCYFLUX_isoconc_label)
|
||||
vacancyflux_type(section) = VACANCYFLUX_isoconc_ID
|
||||
case(VACANCYFLUX_isochempot_label)
|
||||
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
|
||||
call IO_error(500_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||
end select
|
||||
|
@ -590,6 +681,15 @@ subroutine material_parseHomogenization(fileUnit,myPart)
|
|||
endif
|
||||
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)
|
||||
|
||||
end subroutine material_parseHomogenization
|
||||
|
@ -775,7 +875,7 @@ subroutine material_parsePhase(fileUnit,myPart)
|
|||
integer(pInt), parameter :: MAXNCHUNKS = 2_pInt
|
||||
|
||||
integer(pInt), dimension(1+2*MAXNCHUNKS) :: positions
|
||||
integer(pInt) :: Nsections, section, p
|
||||
integer(pInt) :: Nsections, section, sourceCtr, kinematicsCtr, stiffDegradationCtr, p
|
||||
character(len=65536) :: &
|
||||
tag,line
|
||||
logical :: echo
|
||||
|
@ -791,18 +891,23 @@ subroutine material_parsePhase(fileUnit,myPart)
|
|||
allocate(phase_elasticityInstance(Nsections), source=0_pInt)
|
||||
allocate(phase_plasticity(Nsections) , source=PLASTICITY_undefined_ID)
|
||||
allocate(phase_plasticityInstance(Nsections), source=0_pInt)
|
||||
allocate(phase_damage(Nsections) , source=LOCAL_DAMAGE_none_ID)
|
||||
allocate(phase_damageInstance(Nsections), source=0_pInt)
|
||||
allocate(phase_thermal(Nsections) , source=LOCAL_THERMAL_isothermal_ID)
|
||||
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_Nsources(Nsections), source=0_pInt)
|
||||
allocate(phase_Nkinematics(Nsections), source=0_pInt)
|
||||
allocate(phase_NstiffnessDegradations(Nsections),source=0_pInt)
|
||||
allocate(phase_Noutput(Nsections), source=0_pInt)
|
||||
allocate(phase_localPlasticity(Nsections), source=.false.)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
line = '' ! to have it initialized
|
||||
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 (IO_getTag(line,'[',']') /= '') then ! next section
|
||||
section = section + 1_pInt
|
||||
sourceCtr = 0_pInt
|
||||
kinematicsCtr = 0_pInt
|
||||
stiffDegradationCtr = 0_pInt
|
||||
phase_name(section) = IO_getTag(line,'[',']')
|
||||
endif
|
||||
if (section > 0_pInt) then
|
||||
|
@ -855,42 +963,47 @@ subroutine material_parsePhase(fileUnit,myPart)
|
|||
case default
|
||||
call IO_error(201_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||
end select
|
||||
case ('damage')
|
||||
case ('(source)')
|
||||
sourceCtr = sourceCtr + 1_pInt
|
||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||
case (LOCAL_DAMAGE_none_label)
|
||||
phase_damage(section) = LOCAL_DAMAGE_none_ID
|
||||
case (LOCAL_DAMAGE_isoBrittle_label)
|
||||
phase_damage(section) = LOCAL_DAMAGE_isoBrittle_ID
|
||||
case (LOCAL_DAMAGE_isoDuctile_label)
|
||||
phase_damage(section) = LOCAL_DAMAGE_isoDuctile_ID
|
||||
case (LOCAL_DAMAGE_anisoBrittle_label)
|
||||
phase_damage(section) = LOCAL_DAMAGE_anisoBrittle_ID
|
||||
case (LOCAL_DAMAGE_anisoDuctile_label)
|
||||
phase_damage(section) = LOCAL_DAMAGE_anisoDuctile_ID
|
||||
case (LOCAL_DAMAGE_gurson_label)
|
||||
phase_damage(section) = LOCAL_DAMAGE_gurson_ID
|
||||
case (LOCAL_DAMAGE_phaseField_label)
|
||||
phase_damage(section) = LOCAL_DAMAGE_phaseField_ID
|
||||
case default
|
||||
call IO_error(200_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||
case (SOURCE_thermal_dissipation_label)
|
||||
phase_source(sourceCtr,section) = SOURCE_thermal_dissipation_ID
|
||||
case (SOURCE_damage_isoBrittle_label)
|
||||
phase_source(sourceCtr,section) = SOURCE_damage_isoBrittle_ID
|
||||
case (SOURCE_damage_isoDuctile_label)
|
||||
phase_source(sourceCtr,section) = SOURCE_damage_isoDuctile_ID
|
||||
case (SOURCE_damage_anisoBrittle_label)
|
||||
phase_source(sourceCtr,section) = SOURCE_damage_anisoBrittle_ID
|
||||
case (SOURCE_damage_anisoDuctile_label)
|
||||
phase_source(sourceCtr,section) = SOURCE_damage_anisoDuctile_ID
|
||||
case (SOURCE_vacancy_phenoplasticity_label)
|
||||
phase_source(sourceCtr,section) = SOURCE_vacancy_phenoplasticity_ID
|
||||
case (SOURCE_vacancy_irradiation_label)
|
||||
phase_source(sourceCtr,section) = SOURCE_vacancy_irradiation_ID
|
||||
case (SOURCE_vacancy_thermalfluc_label)
|
||||
phase_source(sourceCtr,section) = SOURCE_vacancy_thermalfluc_ID
|
||||
end select
|
||||
case ('thermal')
|
||||
case ('(kinematics)')
|
||||
kinematicsCtr = kinematicsCtr + 1_pInt
|
||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||
case (LOCAL_THERMAL_ISOTHERMAL_label)
|
||||
phase_thermal(section) = LOCAL_THERMAL_isothermal_ID
|
||||
case (LOCAL_THERMAL_ADIABATIC_label)
|
||||
phase_thermal(section) = LOCAL_THERMAL_adiabatic_ID
|
||||
case default
|
||||
call IO_error(200_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||
case (KINEMATICS_cleavage_opening_label)
|
||||
phase_kinematics(kinematicsCtr,section) = KINEMATICS_cleavage_opening_ID
|
||||
case (KINEMATICS_slipplane_opening_label)
|
||||
phase_kinematics(kinematicsCtr,section) = KINEMATICS_slipplane_opening_ID
|
||||
case (KINEMATICS_thermal_expansion_label)
|
||||
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
|
||||
case ('vacancy')
|
||||
case ('(stiffness_degradation)')
|
||||
stiffDegradationCtr = stiffDegradationCtr + 1_pInt
|
||||
select case (IO_lc(IO_stringValue(line,positions,2_pInt)))
|
||||
case (LOCAL_VACANCY_CONSTANT_label)
|
||||
phase_vacancy(section) = LOCAL_VACANCY_constant_ID
|
||||
case (LOCAL_VACANCY_GENERATION_label)
|
||||
phase_vacancy(section) = LOCAL_VACANCY_generation_ID
|
||||
case default
|
||||
call IO_error(200_pInt,ext_msg=trim(IO_stringValue(line,positions,2_pInt)))
|
||||
case (STIFFNESS_DEGRADATION_damage_label)
|
||||
phase_stiffnessDegradation(stiffDegradationCtr,section) = STIFFNESS_DEGRADATION_damage_ID
|
||||
case (STIFFNESS_DEGRADATION_porosity_label)
|
||||
phase_stiffnessDegradation(stiffDegradationCtr,section) = STIFFNESS_DEGRADATION_porosity_ID
|
||||
end select
|
||||
|
||||
end select
|
||||
|
@ -898,14 +1011,10 @@ subroutine material_parsePhase(fileUnit,myPart)
|
|||
enddo
|
||||
|
||||
do p=1_pInt, Nsections
|
||||
phase_elasticityInstance(p) = count(phase_elasticity(1:p) == phase_elasticity(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))
|
||||
phase_elasticityInstance(p) = count(phase_elasticity(1:p) == phase_elasticity(p))
|
||||
phase_plasticityInstance(p) = count(phase_plasticity(1:p) == phase_plasticity(p))
|
||||
enddo
|
||||
|
||||
|
||||
end subroutine material_parsePhase
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -70,6 +70,31 @@ module numerics
|
|||
usePingPong = .true., &
|
||||
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:
|
||||
#ifdef Spectral
|
||||
|
@ -94,9 +119,6 @@ module numerics
|
|||
&-snes_ngmres_anderson '
|
||||
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
|
||||
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
|
||||
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 :: &
|
||||
|
@ -107,13 +129,16 @@ module numerics
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! FEM parameters:
|
||||
#ifdef FEM
|
||||
real(pReal), protected, public :: &
|
||||
err_struct_tolAbs = 1.0e-10_pReal, & !< absolute tolerance for equilibrium
|
||||
err_struct_tolRel = 1.0e-4_pReal, & !< relative tolerance for equilibrium
|
||||
err_thermal_tol = 1.0e-1_pReal, &
|
||||
err_damage_tol = 1.0e-2_pReal, &
|
||||
err_vacancydiffusion_tol = 1.0e-8_pReal, &
|
||||
vacancyBoundPenalty = 1.0e+4_pReal !< penalty to enforce 0 < Cv < 1
|
||||
integer(pInt), protected, public :: &
|
||||
integrationOrder = 2_pInt, & !< order of quadrature rule required
|
||||
structOrder = 2_pInt, & !< order of displacement shape functions
|
||||
thermalOrder = 2_pInt, & !< order of temperature field shape functions
|
||||
damageOrder = 2_pInt, & !< order of damage field shape functions
|
||||
vacancyfluxOrder = 2_pInt, & !< order of vacancy concentration and chemical potential field shape functions
|
||||
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 :: &
|
||||
petsc_optionsFEM = '-mech_snes_type newtonls &
|
||||
&-mech_snes_linesearch_type cp &
|
||||
|
@ -123,50 +148,43 @@ module numerics
|
|||
&-mech_ksp_type fgmres &
|
||||
&-mech_ksp_max_it 25 &
|
||||
&-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_chebyshev_estimate_eigenvalues 0,0.1,0,1.1 &
|
||||
&-mech_mg_levels_pc_type sor &
|
||||
&-mech_pc_ml_nullspace user &
|
||||
&-damage_snes_type newtonls &
|
||||
&-damage_snes_linesearch_type cp &
|
||||
&-damage_ksp_type fgmres &
|
||||
&-damage_ksp_max_it 25 &
|
||||
&-damage_snes_atol 1e-8 &
|
||||
&-damage_pc_type ml &
|
||||
&-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 &
|
||||
&-damage_pc_type hypre &
|
||||
&-thermal_snes_type newtonls &
|
||||
&-thermal_snes_linesearch_type cp &
|
||||
&-thermal_ksp_type fgmres &
|
||||
&-thermal_ksp_max_it 25 &
|
||||
&-thermal_snes_atol 1e-1 &
|
||||
&-thermal_pc_type ml &
|
||||
&-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 &
|
||||
&-thermal_pc_type hypre &
|
||||
&-vacancy_snes_type newtonls &
|
||||
&-vacancy_snes_linesearch_type cp &
|
||||
&-vacancy_ksp_type fgmres &
|
||||
&-vacancy_snes_atol 1e-9 &
|
||||
&-vacancy_ksp_type fgmres &
|
||||
&-vacancy_ksp_max_it 25 &
|
||||
&-vacancy_pc_type ml &
|
||||
&-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 '
|
||||
integer(pInt), protected, public :: &
|
||||
itmaxFEM = 25_pInt, & !< maximum number of iterations
|
||||
itminFEM = 1_pInt, & !< minimum number of iterations
|
||||
stagItMax = 10_pInt, & !< max number of field level staggered iterations
|
||||
maxCutBackFEM = 3_pInt, & !< max number of cut backs
|
||||
integrationOrder = 2_pInt, &
|
||||
structOrder = 2_pInt, &
|
||||
thermalOrder = 2_pInt, &
|
||||
damageOrder = 2_pInt, &
|
||||
vacancyDiffusionOrder = 2_pInt
|
||||
logical, protected, public :: &
|
||||
BBarStabilisation = .false.
|
||||
&-vacancy_mg_levels_pc_type sor &
|
||||
&-porosity_snes_type newtonls &
|
||||
&-porosity_snes_linesearch_type cp &
|
||||
&-porosity_ksp_type fgmres &
|
||||
&-porosity_ksp_max_it 25 &
|
||||
&-porosity_snes_atol 1e-8 &
|
||||
&-porosity_pc_type hypre &
|
||||
&-hydrogen_snes_type newtonls &
|
||||
&-hydrogen_snes_linesearch_type cp &
|
||||
&-hydrogen_snes_atol 1e-9 &
|
||||
&-hydrogen_ksp_type fgmres &
|
||||
&-hydrogen_ksp_max_it 25 &
|
||||
&-hydrogen_pc_type ml &
|
||||
&-hydrogen_mg_levels_ksp_type chebyshev &
|
||||
&-hydrogen_mg_levels_pc_type sor '
|
||||
#endif
|
||||
|
||||
public :: numerics_init
|
||||
|
@ -350,6 +368,49 @@ subroutine numerics_init
|
|||
case ('residualstiffness')
|
||||
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
|
||||
#ifdef Spectral
|
||||
|
@ -361,12 +422,6 @@ subroutine numerics_init
|
|||
err_stress_tolrel = IO_floatValue(line,positions,2_pInt)
|
||||
case ('err_stress_tolabs')
|
||||
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')
|
||||
continueCalculation = IO_intValue(line,positions,2_pInt)
|
||||
case ('memory_efficient')
|
||||
|
@ -395,36 +450,16 @@ subroutine numerics_init
|
|||
polarBeta = IO_floatValue(line,positions,2_pInt)
|
||||
#else
|
||||
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', &
|
||||
'err_curl_tolabs','err_curl_tolrel', &
|
||||
'maxcutback','polaralpha','polarbeta')
|
||||
'polaralpha','polarbeta')
|
||||
call IO_warning(40_pInt,ext_msg=tag)
|
||||
#endif
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! FEM parameters
|
||||
#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')
|
||||
integrationorder = IO_intValue(line,positions,2_pInt)
|
||||
case ('structorder')
|
||||
|
@ -433,16 +468,19 @@ subroutine numerics_init
|
|||
thermalorder = IO_intValue(line,positions,2_pInt)
|
||||
case ('damageorder')
|
||||
damageorder = IO_intValue(line,positions,2_pInt)
|
||||
case ('vacancydiffusionorder')
|
||||
vacancyDiffusionOrder = IO_intValue(line,positions,2_pInt)
|
||||
case ('vacancyfluxorder')
|
||||
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')
|
||||
petsc_optionsFEM = trim(line(positions(4):))
|
||||
case ('bbarstabilisation')
|
||||
BBarStabilisation = IO_intValue(line,positions,2_pInt) > 0_pInt
|
||||
#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
|
||||
'vacancyboundpenalty','itmaxfem', 'itminfem','maxcutbackfem','maxstaggerediter','integrationorder',&
|
||||
'structorder','thermalorder', 'damageorder','petsc_optionsfem','bbarstabilisation')
|
||||
case ('integrationorder','structorder','thermalorder', 'damageorder','vacancyfluxorder', &
|
||||
'porosityorder','hydrogenfluxorder','petsc_optionsfem','bbarstabilisation')
|
||||
call IO_warning(40_pInt,ext_msg=tag)
|
||||
#endif
|
||||
case default ! found unknown keyword
|
||||
|
@ -541,11 +579,31 @@ subroutine numerics_init
|
|||
!$ write(6,'(a24,1x,i8,/)') ' number of threads: ',DAMASK_NumThreadsInt
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! spectral parameters
|
||||
#ifdef Spectral
|
||||
! field parameters
|
||||
write(6,'(a24,1x,i8)') ' itmax: ',itmax
|
||||
write(6,'(a24,1x,i8)') ' itmin: ',itmin
|
||||
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,L8)') ' memory_efficient: ',memory_efficient
|
||||
write(6,'(a24,1x,i8)') ' divergence_correction: ',divergence_correction
|
||||
|
@ -573,21 +631,13 @@ subroutine numerics_init
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
! spectral parameters
|
||||
#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)') ' structOrder: ',structOrder
|
||||
write(6,'(a24,1x,i8)') ' thermalOrder: ',thermalOrder
|
||||
write(6,'(a24,1x,i8)') ' damageOrder: ',damageOrder
|
||||
write(6,'(a24,1x,i8)') ' vacancyDiffusionOrder: ',vacancyDiffusionOrder
|
||||
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_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,i8)') ' vacancyfluxOrder: ',vacancyfluxOrder
|
||||
write(6,'(a24,1x,i8)') ' porosityOrder: ',porosityOrder
|
||||
write(6,'(a24,1x,i8)') ' hydrogenfluxOrder: ',hydrogenfluxOrder
|
||||
write(6,'(a24,1x,a)') ' PETSc_optionsFEM: ',trim(petsc_optionsFEM)
|
||||
write(6,'(a24,1x,L8)') ' B-Bar stabilisation: ',BBarStabilisation
|
||||
#endif
|
||||
|
@ -634,14 +684,28 @@ subroutine numerics_init
|
|||
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 (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 (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. &
|
||||
continueCalculation /= 1_pInt) call IO_error(301_pInt,ext_msg='continueCalculation')
|
||||
if (divergence_correction < 0_pInt .or. &
|
||||
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. &
|
||||
.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')
|
||||
|
@ -655,18 +719,6 @@ subroutine numerics_init
|
|||
if (polarBeta < 0.0_pReal .or. &
|
||||
polarBeta > 2.0_pReal) call IO_error(301_pInt,ext_msg='polarBeta')
|
||||
#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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
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
|
||||
|
||||
type, public :: p_intvec
|
||||
integer(pInt), dimension(:), allocatable :: p
|
||||
type, public :: p_intvec
|
||||
integer(pInt), dimension(:), pointer :: p
|
||||
end type p_intvec
|
||||
|
||||
!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
|
||||
sizeDotState = 0_pInt, & !< size of dot state, i.e. parts of the state that are integrated
|
||||
sizePostResults = 0_pInt !< size of output data
|
||||
logical :: &
|
||||
nonlocal = .false. !< absolute tolerance for state integration
|
||||
real(pReal), allocatable, dimension(:) :: &
|
||||
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
|
||||
state, & !< state
|
||||
dotState !< state rate
|
||||
real(pReal), allocatable, dimension(:,:) :: &
|
||||
dotState, & !< state rate
|
||||
state0, &
|
||||
partionedState0, &
|
||||
subState0, &
|
||||
|
@ -97,17 +94,23 @@ type, public :: p_intvec
|
|||
nSlip = 0_pInt , &
|
||||
nTwin = 0_pInt, &
|
||||
nTrans = 0_pInt
|
||||
logical :: &
|
||||
nonlocal = .false. !< absolute tolerance for state integration
|
||||
real(pReal), pointer, dimension(:,:), contiguous :: &
|
||||
slipRate, & !< slip rate
|
||||
accumulatedSlip !< accumulated plastic slip
|
||||
end type
|
||||
|
||||
type, public :: tFieldData
|
||||
integer(pInt) :: &
|
||||
sizeField = 0_pInt , &
|
||||
sizePostResults = 0_pInt
|
||||
real(pReal), allocatable, dimension(:,:) :: &
|
||||
field !< field data
|
||||
type, public :: tSourceState
|
||||
type(tState), dimension(:), allocatable :: p !< tState for each active source mechanism in a phase
|
||||
end type
|
||||
|
||||
type, public :: tHomogMapping
|
||||
integer(pInt), pointer, dimension(:,:) :: p
|
||||
end type
|
||||
|
||||
type, public :: tPhaseMapping
|
||||
integer(pInt), pointer, dimension(:,:,:) :: p
|
||||
end type
|
||||
|
||||
#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$
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @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
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
module thermal_adiabatic
|
||||
|
@ -22,10 +22,7 @@ module thermal_adiabatic
|
|||
thermal_adiabatic_output !< name of each post result output
|
||||
|
||||
integer(pInt), dimension(:), allocatable, target, public :: &
|
||||
thermal_adiabatic_Noutput !< number of outputs per instance of this damage
|
||||
|
||||
real(pReal), dimension(:), allocatable, public :: &
|
||||
thermal_adiabatic_aTol
|
||||
thermal_adiabatic_Noutput !< number of outputs per instance of this thermal model
|
||||
|
||||
enum, bind(c)
|
||||
enumerator :: undefined_ID, &
|
||||
|
@ -37,14 +34,10 @@ module thermal_adiabatic
|
|||
|
||||
public :: &
|
||||
thermal_adiabatic_init, &
|
||||
thermal_adiabatic_stateInit, &
|
||||
thermal_adiabatic_aTolState, &
|
||||
thermal_adiabatic_microstructure, &
|
||||
thermal_adiabatic_LTAndItsTangent, &
|
||||
thermal_adiabatic_getTemperature, &
|
||||
thermal_adiabatic_getLocalTemperature, &
|
||||
thermal_adiabatic_putLocalTemperature, &
|
||||
thermal_adiabatic_getHeatGeneration, &
|
||||
thermal_adiabatic_updateState, &
|
||||
thermal_adiabatic_getSourceAndItsTangent, &
|
||||
thermal_adiabatic_getSpecificHeat, &
|
||||
thermal_adiabatic_getMassDensity, &
|
||||
thermal_adiabatic_postResults
|
||||
|
||||
contains
|
||||
|
@ -56,10 +49,6 @@ contains
|
|||
!--------------------------------------------------------------------------------------------------
|
||||
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 debug, only: &
|
||||
debug_level,&
|
||||
debug_constitutive,&
|
||||
debug_levelBasic
|
||||
use IO, only: &
|
||||
IO_read, &
|
||||
IO_lc, &
|
||||
|
@ -74,17 +63,20 @@ subroutine thermal_adiabatic_init(fileUnit,temperature_init)
|
|||
IO_timeStamp, &
|
||||
IO_EOF
|
||||
use material, only: &
|
||||
phase_thermal, &
|
||||
phase_thermalInstance, &
|
||||
phase_Noutput, &
|
||||
LOCAL_THERMAL_ADIABATIC_label, &
|
||||
LOCAL_THERMAL_adiabatic_ID, &
|
||||
material_phase, &
|
||||
thermal_type, &
|
||||
thermal_typeInstance, &
|
||||
homogenization_Noutput, &
|
||||
THERMAL_ADIABATIC_label, &
|
||||
THERMAL_adiabatic_ID, &
|
||||
material_homog, &
|
||||
mappingHomogenization, &
|
||||
thermalState, &
|
||||
MATERIAL_partPhase
|
||||
thermalMapping, &
|
||||
temperature, &
|
||||
temperatureRate, &
|
||||
material_partHomogenization
|
||||
use numerics,only: &
|
||||
worldrank, &
|
||||
numerics_integrator
|
||||
worldrank
|
||||
|
||||
implicit none
|
||||
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), dimension(1+2*MAXNCHUNKS) :: positions
|
||||
integer(pInt) :: maxNinstance,mySize=0_pInt,phase,instance,o
|
||||
integer(pInt) :: sizeState, sizeDotState
|
||||
integer(pInt) :: NofMyPhase
|
||||
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_'//LOCAL_THERMAL_ADIABATIC_label//' init -+>>>'
|
||||
write(6,'(/,a)') ' <<<+- thermal_'//THERMAL_ADIABATIC_label//' init -+>>>'
|
||||
write(6,'(a)') ' $Id$'
|
||||
write(6,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||
#include "compilation_info.f90"
|
||||
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 (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_sizePostResult(maxval(phase_Noutput),maxNinstance),source=0_pInt)
|
||||
allocate(thermal_adiabatic_output(maxval(phase_Noutput),maxNinstance))
|
||||
allocate(thermal_adiabatic_sizePostResults(maxNinstance), source=0_pInt)
|
||||
allocate(thermal_adiabatic_sizePostResult (maxval(homogenization_Noutput),maxNinstance),source=0_pInt)
|
||||
allocate(thermal_adiabatic_output (maxval(homogenization_Noutput),maxNinstance))
|
||||
thermal_adiabatic_output = ''
|
||||
allocate(thermal_adiabatic_outputID(maxval(phase_Noutput),maxNinstance), source=undefined_ID)
|
||||
allocate(thermal_adiabatic_Noutput(maxNinstance), source=0_pInt)
|
||||
allocate(thermal_adiabatic_aTol(maxNinstance), source=0.0_pReal)
|
||||
allocate(thermal_adiabatic_outputID (maxval(homogenization_Noutput),maxNinstance),source=undefined_ID)
|
||||
allocate(thermal_adiabatic_Noutput (maxNinstance), source=0_pInt)
|
||||
|
||||
rewind(fileUnit)
|
||||
phase = 0_pInt
|
||||
do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= MATERIAL_partPhase) ! wind forward to <phase>
|
||||
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 phase part
|
||||
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 phase section
|
||||
phase = phase + 1_pInt ! advance phase section counter
|
||||
if (IO_getTag(line,'[',']') /= '') then ! next homog section
|
||||
section = section + 1_pInt ! advance homog section counter
|
||||
cycle ! skip to next line
|
||||
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)
|
||||
tag = IO_lc(IO_stringValue(line,positions,1_pInt)) ! extract key
|
||||
select case(tag)
|
||||
|
@ -152,17 +141,14 @@ subroutine thermal_adiabatic_init(fileUnit,temperature_init)
|
|||
IO_lc(IO_stringValue(line,positions,2_pInt))
|
||||
end select
|
||||
|
||||
case ('atol_adiabatic')
|
||||
thermal_adiabatic_aTol(instance) = IO_floatValue(line,positions,2_pInt)
|
||||
|
||||
end select
|
||||
endif; endif
|
||||
enddo parsingFile
|
||||
|
||||
initializeInstances: do phase = 1_pInt, size(phase_thermal)
|
||||
if (phase_thermal(phase) == LOCAL_THERMAL_adiabatic_ID) then
|
||||
NofMyPhase=count(material_phase==phase)
|
||||
instance = phase_thermalInstance(phase)
|
||||
initializeInstances: do section = 1_pInt, size(thermal_type)
|
||||
if (thermal_type(section) == THERMAL_adiabatic_ID) then
|
||||
NofMyHomog=count(material_homog==section)
|
||||
instance = thermal_typeInstance(section)
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
! 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
|
||||
endif
|
||||
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(thermalState(phase)%deltaState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||
allocate(thermalState(phase)%dotState_backup (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||
if (any(numerics_integrator == 1_pInt)) then
|
||||
allocate(thermalState(phase)%previousDotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||
allocate(thermalState(phase)%previousDotState2 (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||
endif
|
||||
if (any(numerics_integrator == 4_pInt)) &
|
||||
allocate(thermalState(phase)%RK4dotState (sizeDotState,NofMyPhase), source=0.0_pReal)
|
||||
if (any(numerics_integrator == 5_pInt)) &
|
||||
allocate(thermalState(phase)%RKCK45dotState (6,sizeDotState,NofMyPhase),source=0.0_pReal)
|
||||
! allocate state arrays
|
||||
sizeState = 1_pInt
|
||||
thermalState(section)%sizeState = sizeState
|
||||
thermalState(section)%sizePostResults = thermal_adiabatic_sizePostResults(instance)
|
||||
allocate(thermalState(section)%state0 (sizeState,NofMyHomog), source=temperature_init)
|
||||
allocate(thermalState(section)%subState0(sizeState,NofMyHomog), source=temperature_init)
|
||||
allocate(thermalState(section)%state (sizeState,NofMyHomog), source=temperature_init)
|
||||
|
||||
call thermal_adiabatic_stateInit(phase,temperature_init)
|
||||
call thermal_adiabatic_aTolState(phase,instance)
|
||||
nullify(thermalMapping(section)%p)
|
||||
thermalMapping(section)%p => mappingHomogenization(1,:,:)
|
||||
deallocate(temperature(section)%p)
|
||||
temperature(section)%p => thermalState(section)%state(1,:)
|
||||
deallocate(temperatureRate(section)%p)
|
||||
allocate (temperatureRate(section)%p(NofMyHomog), source=0.0_pReal)
|
||||
|
||||
endif
|
||||
|
||||
enddo initializeInstances
|
||||
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)
|
||||
use material, only: &
|
||||
thermalState
|
||||
|
||||
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)
|
||||
function thermal_adiabatic_updateState(subdt, ip, el)
|
||||
use numerics, only: &
|
||||
err_thermal_tolAbs, &
|
||||
err_thermal_tolRel
|
||||
use material, only: &
|
||||
mappingHomogenization, &
|
||||
fieldThermal, &
|
||||
field_thermal_type, &
|
||||
FIELD_THERMAL_nonlocal_ID, &
|
||||
material_homog, &
|
||||
mappingConstitutive, &
|
||||
thermalState
|
||||
|
||||
thermalState, &
|
||||
temperature, &
|
||||
temperatureRate, &
|
||||
thermalMapping
|
||||
|
||||
implicit none
|
||||
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
|
||||
el !< element number
|
||||
real(pReal), intent(in) :: &
|
||||
localTemperature
|
||||
subdt
|
||||
logical, dimension(2) :: &
|
||||
thermal_adiabatic_updateState
|
||||
integer(pInt) :: &
|
||||
homog, &
|
||||
offset
|
||||
real(pReal) :: &
|
||||
T, Tdot, dTdot_dT
|
||||
|
||||
homog = mappingHomogenization(2,ip,el)
|
||||
offset = mappingHomogenization(1,ip,el)
|
||||
|
||||
thermalState(mappingConstitutive(2,ipc,ip,el))%state(1,mappingConstitutive(1,ipc,ip,el))= &
|
||||
localTemperature
|
||||
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
|
||||
|
||||
end subroutine thermal_adiabatic_putLocalTemperature
|
||||
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
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
pure function thermal_adiabatic_getHeatGeneration(Tstar_v, Lp)
|
||||
subroutine thermal_adiabatic_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
|
||||
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) :: thermal_adiabatic_getHeatGeneration
|
||||
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)
|
||||
|
||||
thermal_adiabatic_getHeatGeneration = 0.95_pReal &
|
||||
* sum(abs(math_Mandel6to33(Tstar_v))*Lp)
|
||||
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
|
||||
|
||||
end function thermal_adiabatic_getHeatGeneration
|
||||
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: &
|
||||
mappingConstitutive, &
|
||||
phase_thermalInstance, &
|
||||
thermalState
|
||||
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_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
|
||||
integer(pInt), intent(in) :: &
|
||||
ipc, & !< component-ID of integration point
|
||||
ip, & !< integration point
|
||||
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
|
||||
|
||||
integer(pInt) :: &
|
||||
instance, phase, constituent, o, c
|
||||
instance, homog, offset, o, c
|
||||
|
||||
phase = mappingConstitutive(2,ipc,ip,el)
|
||||
constituent = mappingConstitutive(1,ipc,ip,el)
|
||||
instance = phase_thermalInstance(phase)
|
||||
homog = mappingHomogenization(2,ip,el)
|
||||
offset = thermalMapping(homog)%p(ip,el)
|
||||
instance = thermal_typeInstance(homog)
|
||||
|
||||
c = 0_pInt
|
||||
thermal_adiabatic_postResults = 0.0_pReal
|
||||
|
@ -459,7 +408,7 @@ function thermal_adiabatic_postResults(ipc,ip,el)
|
|||
select case(thermal_adiabatic_outputID(o,instance))
|
||||
|
||||
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
|
||||
end select
|
||||
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$
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @brief material subroutine for purely elastic material
|
||||
!> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH
|
||||
!> @brief material subroutine for isothermal temperature field
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
module thermal_isothermal
|
||||
use prec, only: &
|
||||
pInt, &
|
||||
pReal
|
||||
|
||||
implicit none
|
||||
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 :: &
|
||||
thermal_isothermal_init
|
||||
|
||||
contains
|
||||
|
||||
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
!> @brief module initialization
|
||||
!> @details reads in material parameters, allocates arrays, and does sanity checks
|
||||
!> @brief allocates all neccessary fields, reads information from material configuration file
|
||||
!--------------------------------------------------------------------------------------------------
|
||||
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 debug, only: &
|
||||
debug_level, &
|
||||
debug_constitutive, &
|
||||
debug_levelBasic
|
||||
use prec, only: &
|
||||
pReal, &
|
||||
pInt
|
||||
use IO, only: &
|
||||
IO_timeStamp
|
||||
use material
|
||||
use numerics, only: &
|
||||
worldrank, &
|
||||
numerics_integrator
|
||||
use material, only: &
|
||||
phase_thermal, &
|
||||
LOCAL_THERMAL_ISOTHERMAL_label, &
|
||||
LOCAL_THERMAL_ISOTHERMAL_ID, &
|
||||
material_phase, &
|
||||
thermalState, &
|
||||
MATERIAL_partPhase
|
||||
|
||||
worldrank
|
||||
|
||||
implicit none
|
||||
|
||||
real(pReal), intent(in) :: temperature_init !< initial temperature
|
||||
integer(pInt) :: &
|
||||
maxNinstance, &
|
||||
phase, &
|
||||
NofMyPhase, &
|
||||
sizeState, &
|
||||
sizeDotState
|
||||
homog, &
|
||||
NofMyHomog, &
|
||||
sizeState
|
||||
|
||||
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,'(a15,a)') ' Current time: ',IO_timeStamp()
|
||||
#include "compilation_info.f90"
|
||||
endif mainProcess
|
||||
|
||||
maxNinstance = int(count(phase_thermal == LOCAL_THERMAL_ISOTHERMAL_ID),pInt)
|
||||
if (maxNinstance == 0_pInt) return
|
||||
initializeInstances: do homog = 1_pInt, material_Nhomogenization
|
||||
|
||||
myhomog: if (thermal_type(homog) == THERMAL_isothermal_ID) then
|
||||
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)
|
||||
|
||||
deallocate(temperature (homog)%p)
|
||||
allocate (temperature (homog)%p(1), source=temperature_init)
|
||||
deallocate(temperatureRate(homog)%p)
|
||||
allocate (temperatureRate(homog)%p(1), source=0.0_pReal)
|
||||
|
||||
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) &
|
||||
write(6,'(a16,1x,i5,/)') '# instances:',maxNinstance
|
||||
|
||||
initializeInstances: do phase = 1_pInt, size(phase_thermal)
|
||||
NofMyPhase=count(material_phase==phase)
|
||||
|
||||
if (phase_thermal(phase) == LOCAL_THERMAL_ISOTHERMAL_ID) then
|
||||
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
|
||||
endif myhomog
|
||||
enddo initializeInstances
|
||||
allocate(thermal_isothermal_sizePostResults(maxNinstance), source=0_pInt)
|
||||
allocate(thermal_isothermal_temperature(maxNinstance), source=temperature_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