From 8f4663985a58c3c477721c93f12b28cbc0a99da3 Mon Sep 17 00:00:00 2001
From: Pratheek Shanthraj
Date: Thu, 28 May 2015 17:02:23 +0000
Subject: [PATCH] major restructuring of multi field handling in DAMASK and
added some example config files for multi field simulations. please report
bugs
---
code/CPFEM.f90 | 52 +-
code/DAMASK_spectral_driver.f90 | 2 +-
code/DAMASK_spectral_solverBasicPETSc.f90 | 2 +-
code/DAMASK_spectral_utilities.f90 | 37 +-
code/Makefile | 210 ++-
code/commercialFEM_fileList.f90 | 39 +-
.../Homogenization_Damage_NonLocal.config | 3 +
...enization_HydrogenFlux_CahnHilliard.config | 3 +
.../Homogenization_Porosity_PhaseField.config | 3 +
.../Homogenization_Thermal_Conduction.config | 3 +
...genization_VacancyFlux_CahnHilliard.config | 3 +
code/config/Homogenization_multiField.config | 9 +
code/config/Kinematics_Hydrogen_Strain.config | 3 +
.../Kinematics_Thermal_Expansion.config | 3 +
code/config/Kinematics_Vacancy_Strain.config | 3 +
code/config/Phase_Damage.config | 3 +
code/config/Phase_Hydrogen.config | 4 +
.../Phase_Phenopowerlaw_multiField.config | 62 +
code/config/Phase_Porosity.config | 3 +
code/config/Phase_Thermal.config | 5 +
code/config/Phase_Vacancy.config | 6 +
code/config/Source_Damage_IsoBrittle.config | 5 +
code/config/Source_Thermal_Dissipation.config | 3 +
code/config/Source_Vacancy_Irradiation.config | 4 +
.../Source_Vacancy_PhenoPlasticity.config | 3 +
code/constitutive.f90 | 1349 +++++-----------
code/crystallite.f90 | 1240 +++++++--------
code/damage_anisoBrittle.f90 | 635 --------
code/damage_anisoDuctile.f90 | 608 -------
code/damage_gurson.f90 | 503 ------
code/damage_isoBrittle.f90 | 484 ------
code/damage_isoDuctile.f90 | 457 ------
code/damage_local.f90 | 327 ++++
code/damage_none.f90 | 95 +-
code/damage_nonlocal.f90 | 378 +++++
code/damage_phaseField.f90 | 510 ------
code/homogenization.f90 | 1410 +++++++----------
code/homogenization_RGC.f90 | 2 -
code/hydrogenflux_cahnhilliard.f90 | 544 +++++++
code/hydrogenflux_isoconc.f90 | 64 +
code/kinematics_cleavage_opening.f90 | 305 ++++
code/kinematics_hydrogen_strain.f90 | 220 +++
code/kinematics_slipplane_opening.f90 | 325 ++++
code/kinematics_thermal_expansion.f90 | 182 +++
code/kinematics_vacancy_strain.f90 | 220 +++
code/lattice.f90 | 92 +-
code/material.f90 | 589 ++++---
code/numerics.f90 | 248 +--
code/porosity_none.f90 | 62 +
code/porosity_phasefield.f90 | 488 ++++++
code/prec.f90 | 29 +-
code/source_damage_anisoBrittle.f90 | 423 +++++
code/source_damage_anisoDuctile.f90 | 412 +++++
code/source_damage_isoBrittle.f90 | 362 +++++
code/source_damage_isoDuctile.f90 | 347 ++++
code/source_thermal_dissipation.f90 | 217 +++
code/source_vacancy_irradiation.f90 | 250 +++
code/source_vacancy_phenoplasticity.f90 | 212 +++
code/source_vacancy_thermalfluc.f90 | 240 +++
code/thermal_adiabatic.f90 | 523 +++---
code/thermal_conduction.f90 | 439 +++++
code/thermal_isothermal.f90 | 103 +-
code/vacancy_constant.f90 | 101 --
code/vacancy_generation.f90 | 534 -------
code/vacancyflux_cahnhilliard.f90 | 637 ++++++++
code/vacancyflux_isochempot.f90 | 330 ++++
code/vacancyflux_isoconc.f90 | 64 +
67 files changed, 9782 insertions(+), 7251 deletions(-)
create mode 100644 code/config/Homogenization_Damage_NonLocal.config
create mode 100644 code/config/Homogenization_HydrogenFlux_CahnHilliard.config
create mode 100644 code/config/Homogenization_Porosity_PhaseField.config
create mode 100644 code/config/Homogenization_Thermal_Conduction.config
create mode 100644 code/config/Homogenization_VacancyFlux_CahnHilliard.config
create mode 100644 code/config/Homogenization_multiField.config
create mode 100644 code/config/Kinematics_Hydrogen_Strain.config
create mode 100644 code/config/Kinematics_Thermal_Expansion.config
create mode 100644 code/config/Kinematics_Vacancy_Strain.config
create mode 100644 code/config/Phase_Damage.config
create mode 100644 code/config/Phase_Hydrogen.config
create mode 100644 code/config/Phase_Phenopowerlaw_multiField.config
create mode 100644 code/config/Phase_Porosity.config
create mode 100644 code/config/Phase_Thermal.config
create mode 100644 code/config/Phase_Vacancy.config
create mode 100644 code/config/Source_Damage_IsoBrittle.config
create mode 100644 code/config/Source_Thermal_Dissipation.config
create mode 100644 code/config/Source_Vacancy_Irradiation.config
create mode 100644 code/config/Source_Vacancy_PhenoPlasticity.config
delete mode 100644 code/damage_anisoBrittle.f90
delete mode 100644 code/damage_anisoDuctile.f90
delete mode 100644 code/damage_gurson.f90
delete mode 100644 code/damage_isoBrittle.f90
delete mode 100644 code/damage_isoDuctile.f90
create mode 100644 code/damage_local.f90
create mode 100644 code/damage_nonlocal.f90
delete mode 100644 code/damage_phaseField.f90
create mode 100644 code/hydrogenflux_cahnhilliard.f90
create mode 100644 code/hydrogenflux_isoconc.f90
create mode 100644 code/kinematics_cleavage_opening.f90
create mode 100644 code/kinematics_hydrogen_strain.f90
create mode 100644 code/kinematics_slipplane_opening.f90
create mode 100644 code/kinematics_thermal_expansion.f90
create mode 100644 code/kinematics_vacancy_strain.f90
create mode 100644 code/porosity_none.f90
create mode 100644 code/porosity_phasefield.f90
create mode 100644 code/source_damage_anisoBrittle.f90
create mode 100644 code/source_damage_anisoDuctile.f90
create mode 100644 code/source_damage_isoBrittle.f90
create mode 100644 code/source_damage_isoDuctile.f90
create mode 100644 code/source_thermal_dissipation.f90
create mode 100644 code/source_vacancy_irradiation.f90
create mode 100644 code/source_vacancy_phenoplasticity.f90
create mode 100644 code/source_vacancy_thermalfluc.f90
create mode 100644 code/thermal_conduction.f90
delete mode 100644 code/vacancy_constant.f90
delete mode 100644 code/vacancy_generation.f90
create mode 100644 code/vacancyflux_cahnhilliard.f90
create mode 100644 code/vacancyflux_isochempot.f90
create mode 100644 code/vacancyflux_isoconc.f90
diff --git a/code/CPFEM.f90 b/code/CPFEM.f90
index 034d08a39..6713ae113 100644
--- a/code/CPFEM.f90
+++ b/code/CPFEM.f90
@@ -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
diff --git a/code/DAMASK_spectral_driver.f90 b/code/DAMASK_spectral_driver.f90
index 83b52deee..e7f8b301c 100644
--- a/code/DAMASK_spectral_driver.f90
+++ b/code/DAMASK_spectral_driver.f90
@@ -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$'
diff --git a/code/DAMASK_spectral_solverBasicPETSc.f90 b/code/DAMASK_spectral_solverBasicPETSc.f90
index 14cbd66ee..bb76b80b0 100644
--- a/code/DAMASK_spectral_solverBasicPETSc.f90
+++ b/code/DAMASK_spectral_solverBasicPETSc.f90
@@ -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, &
diff --git a/code/DAMASK_spectral_utilities.f90 b/code/DAMASK_spectral_utilities.f90
index 0ee3ce5e3..30169b9bf 100644
--- a/code/DAMASK_spectral_utilities.f90
+++ b/code/DAMASK_spectral_utilities.f90
@@ -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
diff --git a/code/Makefile b/code/Makefile
index 3bf916c0e..af7b8d2d8 100644
--- a/code/Makefile
+++ b/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
diff --git a/code/commercialFEM_fileList.f90 b/code/commercialFEM_fileList.f90
index 608096309..ffdb0015c 100644
--- a/code/commercialFEM_fileList.f90
+++ b/code/commercialFEM_fileList.f90
@@ -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"
diff --git a/code/config/Homogenization_Damage_NonLocal.config b/code/config/Homogenization_Damage_NonLocal.config
new file mode 100644
index 000000000..1b6bcfc16
--- /dev/null
+++ b/code/config/Homogenization_Damage_NonLocal.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+damage nonlocal
+(output) damage
diff --git a/code/config/Homogenization_HydrogenFlux_CahnHilliard.config b/code/config/Homogenization_HydrogenFlux_CahnHilliard.config
new file mode 100644
index 000000000..73705d846
--- /dev/null
+++ b/code/config/Homogenization_HydrogenFlux_CahnHilliard.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+hydrogenflux cahnhilliard
+(output) hydrogenconc
diff --git a/code/config/Homogenization_Porosity_PhaseField.config b/code/config/Homogenization_Porosity_PhaseField.config
new file mode 100644
index 000000000..38a618ceb
--- /dev/null
+++ b/code/config/Homogenization_Porosity_PhaseField.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+porosity phasefield
+(output) porosity
diff --git a/code/config/Homogenization_Thermal_Conduction.config b/code/config/Homogenization_Thermal_Conduction.config
new file mode 100644
index 000000000..f761ce0b3
--- /dev/null
+++ b/code/config/Homogenization_Thermal_Conduction.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+thermal conduction
+(output) temperature
diff --git a/code/config/Homogenization_VacancyFlux_CahnHilliard.config b/code/config/Homogenization_VacancyFlux_CahnHilliard.config
new file mode 100644
index 000000000..00f5399f2
--- /dev/null
+++ b/code/config/Homogenization_VacancyFlux_CahnHilliard.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+vacancyflux cahnhilliard
+(output) vacancyconc
diff --git a/code/config/Homogenization_multiField.config b/code/config/Homogenization_multiField.config
new file mode 100644
index 000000000..926737ff9
--- /dev/null
+++ b/code/config/Homogenization_multiField.config
@@ -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}
diff --git a/code/config/Kinematics_Hydrogen_Strain.config b/code/config/Kinematics_Hydrogen_Strain.config
new file mode 100644
index 000000000..f4a999038
--- /dev/null
+++ b/code/config/Kinematics_Hydrogen_Strain.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+(kinematics) vacancy_strain
+vacancy_strain_coeff 0.006
diff --git a/code/config/Kinematics_Thermal_Expansion.config b/code/config/Kinematics_Thermal_Expansion.config
new file mode 100644
index 000000000..408c489e2
--- /dev/null
+++ b/code/config/Kinematics_Thermal_Expansion.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+(kinematics) thermal_expansion
+thermal_expansion_coeff 0.00231
diff --git a/code/config/Kinematics_Vacancy_Strain.config b/code/config/Kinematics_Vacancy_Strain.config
new file mode 100644
index 000000000..cfb75ed0d
--- /dev/null
+++ b/code/config/Kinematics_Vacancy_Strain.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+(kinematics) hydrogen_strain
+hydrogen_strain_coeff 0.06
diff --git a/code/config/Phase_Damage.config b/code/config/Phase_Damage.config
new file mode 100644
index 000000000..67c70a987
--- /dev/null
+++ b/code/config/Phase_Damage.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+damage_diffusion11 1.0
+damage_mobility 0.001
diff --git a/code/config/Phase_Hydrogen.config b/code/config/Phase_Hydrogen.config
new file mode 100644
index 000000000..e3797df52
--- /dev/null
+++ b/code/config/Phase_Hydrogen.config
@@ -0,0 +1,4 @@
+### $Id$ ###
+hydrogenflux_diffusion11 1.0
+hydrogenflux_mobility11 1.0
+hydrogenVolume 1e-28
diff --git a/code/config/Phase_Phenopowerlaw_multiField.config b/code/config/Phase_Phenopowerlaw_multiField.config
new file mode 100644
index 000000000..3de057f3f
--- /dev/null
+++ b/code/config/Phase_Phenopowerlaw_multiField.config
@@ -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}
+
+
diff --git a/code/config/Phase_Porosity.config b/code/config/Phase_Porosity.config
new file mode 100644
index 000000000..3f1ba52ce
--- /dev/null
+++ b/code/config/Phase_Porosity.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+porosity_diffusion11 1.0
+porosity_mobility 0.001
diff --git a/code/config/Phase_Thermal.config b/code/config/Phase_Thermal.config
new file mode 100644
index 000000000..5b6cb94d1
--- /dev/null
+++ b/code/config/Phase_Thermal.config
@@ -0,0 +1,5 @@
+### $Id$ ###
+thermal_conductivity11 237.0
+specific_heat 910.0
+mass_density 2700.0
+reference_temperature 300.0
diff --git a/code/config/Phase_Vacancy.config b/code/config/Phase_Vacancy.config
new file mode 100644
index 000000000..2905913f6
--- /dev/null
+++ b/code/config/Phase_Vacancy.config
@@ -0,0 +1,6 @@
+### $Id$ ###
+vacancyflux_diffusion11 1.0
+vacancyflux_mobility11 1.0
+vacancyFormationEnergy 1e-19
+voidSurfaceEnergy 1e+10
+vacancyVolume 1e-28
diff --git a/code/config/Source_Damage_IsoBrittle.config b/code/config/Source_Damage_IsoBrittle.config
new file mode 100644
index 000000000..3def4c13a
--- /dev/null
+++ b/code/config/Source_Damage_IsoBrittle.config
@@ -0,0 +1,5 @@
+### $Id$ ###
+(source) damage_isoBrittle
+isobrittle_criticalStrainEnergy 1400000.0
+isobrittle_atol 0.01
+(output) isoBrittle_DrivingForce
\ No newline at end of file
diff --git a/code/config/Source_Thermal_Dissipation.config b/code/config/Source_Thermal_Dissipation.config
new file mode 100644
index 000000000..218c5a4b5
--- /dev/null
+++ b/code/config/Source_Thermal_Dissipation.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+(source) thermal_dissipation
+dissipation_ColdWorkCoeff 0.95
diff --git a/code/config/Source_Vacancy_Irradiation.config b/code/config/Source_Vacancy_Irradiation.config
new file mode 100644
index 000000000..a346d73d4
--- /dev/null
+++ b/code/config/Source_Vacancy_Irradiation.config
@@ -0,0 +1,4 @@
+### $Id$ ###
+(source) vacancy_irradiation
+irradiation_cascadeprobability 0.00001
+irradiation_cascadevolume 1000.0
diff --git a/code/config/Source_Vacancy_PhenoPlasticity.config b/code/config/Source_Vacancy_PhenoPlasticity.config
new file mode 100644
index 000000000..634b39134
--- /dev/null
+++ b/code/config/Source_Vacancy_PhenoPlasticity.config
@@ -0,0 +1,3 @@
+### $Id$ ###
+(source) vacancy_phenoplasticity
+phenoplasticity_ratecoeff 0.01
diff --git a/code/constitutive.f90 b/code/constitutive.f90
index 163759bb5..00a74ef5b 100644
--- a/code/constitutive.f90
+++ b/code/constitutive.f90
@@ -12,39 +12,20 @@ module constitutive
implicit none
private
integer(pInt), public, protected :: &
- constitutive_maxSizePostResults, &
- constitutive_maxSizeDotState, &
- constitutive_damage_maxSizePostResults, &
- constitutive_damage_maxSizeDotState, &
- constitutive_thermal_maxSizePostResults, &
- constitutive_thermal_maxSizeDotState, &
- constitutive_vacancy_maxSizePostResults, &
- constitutive_vacancy_maxSizeDotState
+ constitutive_plasticity_maxSizePostResults, &
+ constitutive_plasticity_maxSizeDotState, &
+ constitutive_source_maxSizePostResults, &
+ constitutive_source_maxSizeDotState
public :: &
constitutive_init, &
constitutive_homogenizedC, &
- constitutive_damagedC, &
constitutive_microstructure, &
constitutive_LpAndItsTangent, &
constitutive_LiAndItsTangent, &
constitutive_TandItsTangent, &
constitutive_collectDotState, &
constitutive_collectDeltaState, &
- constitutive_getLocalDamage, &
- constitutive_putLocalDamage, &
- constitutive_getDamage, &
- constitutive_getDamageDiffusion33, &
- constitutive_getAdiabaticTemperature, &
- constitutive_putAdiabaticTemperature, &
- constitutive_getTemperature, &
- constitutive_getHeatGeneration, &
- constitutive_getLocalVacancyConcentration, &
- constitutive_putLocalVacancyConcentration, &
- constitutive_getVacancyConcentration, &
- constitutive_getVacancyDiffusion33, &
- constitutive_getVacancyMobility33, &
- constitutive_getVacancyEnergy, &
constitutive_postResults
private :: &
@@ -56,7 +37,7 @@ contains
!--------------------------------------------------------------------------------------------------
!> @brief allocates arrays pointing to array of the various constitutive modules
!--------------------------------------------------------------------------------------------------
-subroutine constitutive_init(temperature_init)
+subroutine constitutive_init()
#ifdef HDF
use hdf5, only: &
HID_T
@@ -89,12 +70,9 @@ subroutine constitutive_init(temperature_init)
phase_name, &
phase_plasticity, &
phase_plasticityInstance, &
- phase_damage, &
- phase_damageInstance, &
- phase_thermal, &
- phase_thermalInstance, &
- phase_vacancy, &
- phase_vacancyInstance, &
+ phase_Nsources, &
+ phase_source, &
+ phase_kinematics, &
ELASTICITY_hooke_ID, &
PLASTICITY_none_ID, &
PLASTICITY_j2_ID, &
@@ -104,6 +82,19 @@ subroutine constitutive_init(temperature_init)
PLASTICITY_disloucla_ID, &
PLASTICITY_titanmod_ID, &
PLASTICITY_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, &
ELASTICITY_HOOKE_label, &
PLASTICITY_NONE_label, &
PLASTICITY_J2_label, &
@@ -113,32 +104,16 @@ subroutine constitutive_init(temperature_init)
PLASTICITY_DISLOUCLA_label, &
PLASTICITY_TITANMOD_label, &
PLASTICITY_NONLOCAL_label, &
- 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, &
- LOCAL_DAMAGE_none_LABEL, &
- LOCAL_DAMAGE_isoBrittle_LABEL, &
- LOCAL_DAMAGE_isoDuctile_LABEL, &
- LOCAL_DAMAGE_anisoBrittle_LABEL, &
- LOCAL_DAMAGE_anisoDuctile_LABEL, &
- LOCAL_DAMAGE_gurson_LABEL, &
- LOCAL_DAMAGE_phaseField_label, &
- LOCAL_THERMAL_isothermal_label, &
- LOCAL_THERMAL_adiabatic_label, &
- LOCAL_VACANCY_constant_label, &
- LOCAL_VACANCY_generation_label, &
+ SOURCE_thermal_dissipation_label, &
+ SOURCE_damage_isoBrittle_label, &
+ SOURCE_damage_isoDuctile_label, &
+ SOURCE_damage_anisoBrittle_label, &
+ SOURCE_damage_anisoDuctile_label, &
+ SOURCE_vacancy_phenoplasticity_label, &
+ SOURCE_vacancy_irradiation_label, &
+ SOURCE_vacancy_thermalfluc_label, &
plasticState, &
- damageState, &
- thermalState, &
- vacancyState
+ sourceState
use plastic_none
use plastic_j2
@@ -148,31 +123,33 @@ subroutine constitutive_init(temperature_init)
use plastic_disloucla
use plastic_titanmod
use plastic_nonlocal
- use damage_none
- use damage_isoBrittle
- use damage_isoDuctile
- use damage_anisoDuctile
- use damage_anisoBrittle
- use damage_gurson
- use damage_phaseField
- use thermal_isothermal
- use thermal_adiabatic
- use vacancy_constant
- use vacancy_generation
+ use source_thermal_dissipation
+ use source_damage_isoBrittle
+ use source_damage_isoDuctile
+ use source_damage_anisoBrittle
+ use source_damage_anisoDuctile
+ use source_vacancy_phenoplasticity
+ use source_vacancy_irradiation
+ use source_vacancy_thermalfluc
+ use kinematics_cleavage_opening
+ use kinematics_slipplane_opening
+ use kinematics_thermal_expansion
+ use kinematics_vacancy_strain
+ use kinematics_hydrogen_strain
implicit none
- real(pReal), intent(in) :: temperature_init !< initial temperature
integer(pInt), parameter :: FILEUNIT = 200_pInt
integer(pInt) :: &
e, & !< maximum number of elements
phase, &
+ mySource, &
instance
integer(pInt), dimension(:,:), pointer :: thisSize
integer(pInt), dimension(:) , pointer :: thisNoutput
character(len=64), dimension(:,:), pointer :: thisOutput
character(len=32) :: outputName !< name of output, intermediate fix until HDF5 output is ready
- logical :: knownPlasticity, knownDamage, knownThermal, knownVacancy, nonlocalConstitutionPresent
+ logical :: knownPlasticity, knownSource, nonlocalConstitutionPresent
nonlocalConstitutionPresent = .false.
!--------------------------------------------------------------------------------------------------
@@ -193,32 +170,28 @@ subroutine constitutive_init(temperature_init)
close(FILEUNIT)
!--------------------------------------------------------------------------------------------------
-! parse damage from config file
+! parse source mechanisms from config file
if (.not. IO_open_jobFile_stat(FILEUNIT,material_localFileExt)) & ! no local material configuration present...
call IO_open_file(FILEUNIT,material_configFile) ! ... open material.config file
- if (any(phase_damage == LOCAL_DAMAGE_none_ID)) call damage_none_init
- if (any(phase_damage == LOCAL_DAMAGE_isoBrittle_ID)) call damage_isoBrittle_init(FILEUNIT)
- if (any(phase_damage == LOCAL_DAMAGE_isoductile_ID)) call damage_isoDuctile_init(FILEUNIT)
- if (any(phase_damage == LOCAL_DAMAGE_anisoBrittle_ID)) call damage_anisoBrittle_init(FILEUNIT)
- if (any(phase_damage == LOCAL_DAMAGE_anisoductile_ID)) call damage_anisoDuctile_init(FILEUNIT)
- if (any(phase_damage == LOCAL_DAMAGE_gurson_ID)) call damage_gurson_init(FILEUNIT)
- if (any(phase_damage == LOCAL_DAMAGE_phaseField_ID)) call damage_phaseField_init(FILEUNIT)
+ if (any(phase_source == SOURCE_thermal_dissipation_ID)) call source_thermal_dissipation_init(FILEUNIT)
+ if (any(phase_source == SOURCE_damage_isoBrittle_ID)) call source_damage_isoBrittle_init(FILEUNIT)
+ if (any(phase_source == SOURCE_damage_isoDuctile_ID)) call source_damage_isoDuctile_init(FILEUNIT)
+ if (any(phase_source == SOURCE_damage_anisoBrittle_ID)) call source_damage_anisoBrittle_init(FILEUNIT)
+ if (any(phase_source == SOURCE_damage_anisoDuctile_ID)) call source_damage_anisoDuctile_init(FILEUNIT)
+ if (any(phase_source == SOURCE_vacancy_phenoplasticity_ID)) call source_vacancy_phenoplasticity_init(FILEUNIT)
+ if (any(phase_source == SOURCE_vacancy_irradiation_ID)) call source_vacancy_irradiation_init(FILEUNIT)
+ if (any(phase_source == SOURCE_vacancy_thermalfluc_ID)) call source_vacancy_thermalfluc_init(FILEUNIT)
close(FILEUNIT)
!--------------------------------------------------------------------------------------------------
-! parse thermal from config file
+! parse kinematic mechanisms from config file
if (.not. IO_open_jobFile_stat(FILEUNIT,material_localFileExt)) & ! no local material configuration present...
call IO_open_file(FILEUNIT,material_configFile) ! ... open material.config file
- if (any(phase_thermal == LOCAL_THERMAL_isothermal_ID)) call thermal_isothermal_init(temperature_init)
- if (any(phase_thermal == LOCAL_THERMAL_adiabatic_ID)) call thermal_adiabatic_init(FILEUNIT,temperature_init)
- close(FILEUNIT)
-
-!--------------------------------------------------------------------------------------------------
-! parse vacancy model from config file
- if (.not. IO_open_jobFile_stat(FILEUNIT,material_localFileExt)) & ! no local material configuration present...
- call IO_open_file(FILEUNIT,material_configFile) ! ... open material.config file
- if (any(phase_vacancy == LOCAL_VACANCY_constant_ID)) call vacancy_constant_init
- if (any(phase_vacancy == LOCAL_VACANCY_generation_ID)) call vacancy_generation_init(FILEUNIT)
+ if (any(phase_kinematics == KINEMATICS_cleavage_opening_ID)) call kinematics_cleavage_opening_init(FILEUNIT)
+ if (any(phase_kinematics == KINEMATICS_slipplane_opening_ID)) call kinematics_slipplane_opening_init(FILEUNIT)
+ if (any(phase_kinematics == KINEMATICS_thermal_expansion_ID)) call kinematics_thermal_expansion_init(FILEUNIT)
+ if (any(phase_kinematics == KINEMATICS_vacancy_strain_ID)) call kinematics_vacancy_strain_init(FILEUNIT)
+ if (any(phase_kinematics == KINEMATICS_hydrogen_strain_ID)) call kinematics_hydrogen_strain_init(FILEUNIT)
close(FILEUNIT)
mainProcess: if (worldrank == 0) then
@@ -289,134 +262,93 @@ subroutine constitutive_init(temperature_init)
enddo
endif
endif
- instance = phase_damageInstance(phase) ! which instance of a plasticity is present phase
- knownDamage = .true.
- select case(phase_damage(phase)) ! split per constititution
- case (LOCAL_DAMAGE_none_ID)
- outputName = LOCAL_DAMAGE_NONE_label
- thisNoutput => null()
- thisOutput => null()
- thisSize => null()
- case (LOCAL_DAMAGE_isoBrittle_ID)
- outputName = LOCAL_DAMAGE_isoBrittle_LABEL
- thisNoutput => damage_isoBrittle_Noutput
- thisOutput => damage_isoBrittle_output
- thisSize => damage_isoBrittle_sizePostResult
- case (LOCAL_DAMAGE_isoDuctile_ID)
- outputName = LOCAL_DAMAGE_isoDuctile_LABEL
- thisNoutput => damage_isoDuctile_Noutput
- thisOutput => damage_isoDuctile_output
- thisSize => damage_isoDuctile_sizePostResult
- case (LOCAL_DAMAGE_anisoBrittle_ID)
- outputName = LOCAL_DAMAGE_anisoBrittle_label
- thisNoutput => damage_anisoBrittle_Noutput
- thisOutput => damage_anisoBrittle_output
- thisSize => damage_anisoBrittle_sizePostResult
- case (LOCAL_DAMAGE_anisoDuctile_ID)
- outputName = LOCAL_DAMAGE_anisoDuctile_LABEL
- thisNoutput => damage_anisoDuctile_Noutput
- thisOutput => damage_anisoDuctile_output
- thisSize => damage_anisoDuctile_sizePostResult
- case (LOCAL_DAMAGE_gurson_ID)
- outputName = LOCAL_DAMAGE_gurson_label
- thisNoutput => damage_gurson_Noutput
- thisOutput => damage_gurson_output
- thisSize => damage_gurson_sizePostResult
- case (LOCAL_DAMAGE_phaseField_ID)
- outputName = LOCAL_DAMAGE_phaseField_label
- thisNoutput => damage_phaseField_Noutput
- thisOutput => damage_phaseField_output
- thisSize => damage_phaseField_sizePostResult
- case default
- knownDamage = .false.
- end select
- if (knownDamage) then
- write(FILEUNIT,'(a)') '(damage)'//char(9)//trim(outputName)
- if (phase_damage(phase) /= LOCAL_DAMAGE_none_ID) then
+ do mySource = 1_pInt, phase_Nsources(phase)
+ knownSource = .true.
+ select case (phase_source(mySource,phase))
+ case (SOURCE_thermal_dissipation_ID)
+ instance = source_thermal_dissipation_instance(phase)
+ outputName = SOURCE_thermal_dissipation_label
+ thisNoutput => source_thermal_dissipation_Noutput
+ thisOutput => source_thermal_dissipation_output
+ thisSize => source_thermal_dissipation_sizePostResult
+ case (SOURCE_damage_isoBrittle_ID)
+ instance = source_damage_isoBrittle_instance(phase)
+ outputName = SOURCE_damage_isoBrittle_label
+ thisNoutput => source_damage_isoBrittle_Noutput
+ thisOutput => source_damage_isoBrittle_output
+ thisSize => source_damage_isoBrittle_sizePostResult
+ case (SOURCE_damage_isoDuctile_ID)
+ instance = source_damage_isoDuctile_instance(phase)
+ outputName = SOURCE_damage_isoDuctile_label
+ thisNoutput => source_damage_isoDuctile_Noutput
+ thisOutput => source_damage_isoDuctile_output
+ thisSize => source_damage_isoDuctile_sizePostResult
+ case (SOURCE_damage_anisoBrittle_ID)
+ instance = source_damage_anisoBrittle_instance(phase)
+ outputName = SOURCE_damage_anisoBrittle_label
+ thisNoutput => source_damage_anisoBrittle_Noutput
+ thisOutput => source_damage_anisoBrittle_output
+ thisSize => source_damage_anisoBrittle_sizePostResult
+ case (SOURCE_damage_anisoDuctile_ID)
+ instance = source_damage_anisoDuctile_instance(phase)
+ outputName = SOURCE_damage_anisoDuctile_label
+ thisNoutput => source_damage_anisoDuctile_Noutput
+ thisOutput => source_damage_anisoDuctile_output
+ thisSize => source_damage_anisoDuctile_sizePostResult
+ case (SOURCE_vacancy_phenoplasticity_ID)
+ instance = source_vacancy_phenoplasticity_instance(phase)
+ outputName = SOURCE_vacancy_phenoplasticity_label
+ thisNoutput => source_vacancy_phenoplasticity_Noutput
+ thisOutput => source_vacancy_phenoplasticity_output
+ thisSize => source_vacancy_phenoplasticity_sizePostResult
+ case (SOURCE_vacancy_irradiation_ID)
+ instance = source_vacancy_irradiation_instance(phase)
+ outputName = SOURCE_vacancy_irradiation_label
+ thisNoutput => source_vacancy_irradiation_Noutput
+ thisOutput => source_vacancy_irradiation_output
+ thisSize => source_vacancy_irradiation_sizePostResult
+ case (SOURCE_vacancy_thermalfluc_ID)
+ instance = source_vacancy_thermalfluc_instance(phase)
+ outputName = SOURCE_vacancy_thermalfluc_label
+ thisNoutput => source_vacancy_thermalfluc_Noutput
+ thisOutput => source_vacancy_thermalfluc_output
+ thisSize => source_vacancy_thermalfluc_sizePostResult
+ case default
+ knownSource = .false.
+ end select
+ if (knownSource) then
+ write(FILEUNIT,'(a)') '(source)'//char(9)//trim(outputName)
do e = 1_pInt,thisNoutput(instance)
write(FILEUNIT,'(a,i4)') trim(thisOutput(e,instance))//char(9),thisSize(e,instance)
enddo
endif
- endif
- instance = phase_thermalInstance(phase) ! which instance is present phase
- knownThermal = .true.
- select case(phase_thermal(phase)) ! split per constititution
- case (LOCAL_THERMAL_isothermal_ID)
- outputName = LOCAL_THERMAL_ISOTHERMAL_label
- thisNoutput => null()
- thisOutput => null()
- thisSize => null()
- case (LOCAL_THERMAL_adiabatic_ID)
- outputName = LOCAL_THERMAL_ADIABATIC_label
- thisNoutput => thermal_adiabatic_Noutput
- thisOutput => thermal_adiabatic_output
- thisSize => thermal_adiabatic_sizePostResult
- case default
- knownThermal = .false.
- end select
- if (knownThermal) then
- write(FILEUNIT,'(a)') '(thermal)'//char(9)//trim(outputName)
- if (phase_thermal(phase) /= LOCAL_THERMAL_isothermal_ID) then
- do e = 1_pInt,thisNoutput(instance)
- write(FILEUNIT,'(a,i4)') trim(thisOutput(e,instance))//char(9),thisSize(e,instance)
- enddo
- endif
- endif
- instance = phase_vacancyInstance(phase) ! which instance is present phase
- knownVacancy = .true.
- select case(phase_vacancy(phase)) ! split per constititution
- case (LOCAL_VACANCY_constant_ID)
- outputName = LOCAL_VACANCY_constant_label
- thisNoutput => null()
- thisOutput => null()
- thisSize => null()
- case (LOCAL_VACANCY_generation_ID)
- outputName = LOCAL_VACANCY_generation_label
- thisNoutput => vacancy_generation_Noutput
- thisOutput => vacancy_generation_output
- thisSize => vacancy_generation_sizePostResult
- case default
- knownVacancy = .false.
- end select
- if (knownVacancy) then
- write(FILEUNIT,'(a)') '(vacancy)'//char(9)//trim(outputName)
- if (phase_vacancy(phase) /= LOCAL_VACANCY_constant_ID) then
- do e = 1_pInt,thisNoutput(instance)
- write(FILEUNIT,'(a,i4)') trim(thisOutput(e,instance))//char(9),thisSize(e,instance)
- enddo
- endif
- endif
+ enddo
endif
enddo
close(FILEUNIT)
endif
- constitutive_maxSizeDotState = 0_pInt
- constitutive_maxSizePostResults = 0_pInt
- constitutive_damage_maxSizePostResults = 0_pInt
- constitutive_damage_maxSizeDotState = 0_pInt
- constitutive_thermal_maxSizePostResults = 0_pInt
- constitutive_thermal_maxSizeDotState = 0_pInt
- constitutive_vacancy_maxSizePostResults = 0_pInt
- constitutive_vacancy_maxSizeDotState = 0_pInt
+ constitutive_plasticity_maxSizeDotState = 0_pInt
+ constitutive_plasticity_maxSizePostResults = 0_pInt
+ constitutive_source_maxSizeDotState = 0_pInt
+ constitutive_source_maxSizePostResults = 0_pInt
PhaseLoop2:do phase = 1_pInt,material_Nphase
- plasticState(phase)%partionedState0 = plasticState(phase)%State0
- plasticState(phase)%State = plasticState(phase)%State0
- constitutive_maxSizeDotState = max(constitutive_maxSizeDotState, plasticState(phase)%sizeDotState)
- constitutive_maxSizePostResults = max(constitutive_maxSizePostResults, plasticState(phase)%sizePostResults)
- damageState(phase)%partionedState0 = damageState(phase)%State0
- damageState(phase)%State = damageState(phase)%State0
- constitutive_damage_maxSizeDotState = max(constitutive_damage_maxSizeDotState, damageState(phase)%sizeDotState)
- constitutive_damage_maxSizePostResults = max(constitutive_damage_maxSizePostResults, damageState(phase)%sizePostResults)
- thermalState(phase)%partionedState0 = thermalState(phase)%State0
- thermalState(phase)%State = thermalState(phase)%State0
- constitutive_thermal_maxSizeDotState = max(constitutive_thermal_maxSizeDotState, thermalState(phase)%sizeDotState)
- constitutive_thermal_maxSizePostResults = max(constitutive_thermal_maxSizePostResults, thermalState(phase)%sizePostResults)
- vacancyState(phase)%partionedState0 = vacancyState(phase)%State0
- vacancyState(phase)%State = vacancyState(phase)%State0
- constitutive_vacancy_maxSizeDotState = max(constitutive_vacancy_maxSizeDotState, vacancyState(phase)%sizeDotState)
- constitutive_vacancy_maxSizePostResults = max(constitutive_vacancy_maxSizePostResults, vacancyState(phase)%sizePostResults)
+ plasticState (phase)%partionedState0 = plasticState (phase)%State0
+ plasticState (phase)%State = plasticState (phase)%State0
+ forall(mySource = 1_pInt:phase_Nsources(phase)) &
+ sourceState(phase)%p(mySource)%partionedState0 = sourceState(phase)%p(mySource)%State0
+ forall(mySource = 1_pInt:phase_Nsources(phase)) &
+ sourceState(phase)%p(mySource)%State = sourceState(phase)%p(mySource)%State0
+
+ constitutive_plasticity_maxSizeDotState = max(constitutive_plasticity_maxSizeDotState, &
+ plasticState(phase)%sizeDotState)
+ constitutive_plasticity_maxSizePostResults = max(constitutive_plasticity_maxSizePostResults, &
+ plasticState(phase)%sizePostResults)
+ constitutive_source_maxSizeDotState = max(constitutive_source_maxSizeDotState, &
+ maxval(sourceState(phase)%p(:)%sizeDotState))
+ constitutive_source_maxSizePostResults = max(constitutive_source_maxSizePostResults, &
+ maxval(sourceState(phase)%p(:)%sizePostResults))
enddo PhaseLoop2
#ifdef HDF
@@ -434,7 +366,7 @@ subroutine constitutive_init(temperature_init)
!--------------------------------------------------------------------------------------------------
! report
constitutive_maxSizeState = maxval(constitutive_sizeState)
- constitutive_maxSizeDotState = maxval(constitutive_sizeDotState)
+ constitutive_plasticity_maxSizeDotState = maxval(constitutive_sizeDotState)
if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0_pInt) then
write(6,'(a32,1x,7(i8,1x))') 'constitutive_state0: ', shape(constitutive_state0)
@@ -448,8 +380,8 @@ subroutine constitutive_init(temperature_init)
write(6,'(a32,1x,7(i8,1x))') 'constitutive_sizeDotState: ', shape(constitutive_sizeDotState)
write(6,'(a32,1x,7(i8,1x),/)') 'constitutive_sizePostResults: ', shape(constitutive_sizePostResults)
write(6,'(a32,1x,7(i8,1x))') 'maxSizeState: ', constitutive_maxSizeState
- write(6,'(a32,1x,7(i8,1x))') 'maxSizeDotState: ', constitutive_maxSizeDotState
- write(6,'(a32,1x,7(i8,1x))') 'maxSizePostResults: ', constitutive_maxSizePostResults
+ write(6,'(a32,1x,7(i8,1x))') 'maxSizeDotState: ', constitutive_plasticity_maxSizeDotState
+ write(6,'(a32,1x,7(i8,1x))') 'maxSizePostResults: ', constitutive_plasticity_maxSizePostResults
endif
flush(6)
#endif
@@ -506,76 +438,23 @@ function constitutive_homogenizedC(ipc,ip,el)
end function constitutive_homogenizedC
-!--------------------------------------------------------------------------------------------------
-!> @brief returns the damaged elasticity matrix if relevant
-!--------------------------------------------------------------------------------------------------
-function constitutive_damagedC(ipc,ip,el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_DAMAGE_isoBrittle_ID, &
- LOCAL_DAMAGE_isoDuctile_ID, &
- LOCAL_DAMAGE_phaseField_ID, &
- phase_damage
- use damage_isoBrittle, only: &
- damage_isoBrittle_getDamagedC66
- use damage_isoDuctile, only: &
- damage_isoDuctile_getDamagedC66
- use damage_phaseField, only: &
- damage_phaseField_getDamagedC66
-
- implicit none
- real(pReal), dimension(6,6) :: constitutive_damagedC
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el
-
- select case (phase_damage(material_phase(ipc,ip,el)))
- case (LOCAL_DAMAGE_isoBrittle_ID)
- constitutive_damagedC = damage_isoBrittle_getDamagedC66(constitutive_homogenizedC(ipc,ip,el), &
- ipc,ip,el)
-
- case (LOCAL_DAMAGE_isoDuctile_ID)
- constitutive_damagedC = damage_isoDuctile_getDamagedC66(constitutive_homogenizedC(ipc,ip,el), &
- ipc,ip,el)
-
- case (LOCAL_DAMAGE_phaseField_ID)
- constitutive_damagedC = damage_phaseField_getDamagedC66(constitutive_homogenizedC(ipc,ip,el), &
- ipc,ip,el)
- case default
- constitutive_damagedC = constitutive_homogenizedC(ipc,ip,el)
-
- end select
-
-end function constitutive_damagedC
-
!--------------------------------------------------------------------------------------------------
!> @brief calls microstructure function of the different constitutive models
!--------------------------------------------------------------------------------------------------
-subroutine constitutive_microstructure(Tstar_v, Fe, Fp, Lp, subdt, ipc, ip, el)
+subroutine constitutive_microstructure(Fe, Fp, ipc, ip, el)
use prec, only: &
pReal
use material, only: &
phase_plasticity, &
- phase_damage, &
- phase_thermal, &
- phase_vacancy, &
material_phase, &
+ material_homog, &
+ temperature, &
+ thermalMapping, &
PLASTICITY_dislotwin_ID, &
PLASTICITY_dislokmc_ID, &
PLASTICITY_disloucla_ID, &
PLASTICITY_titanmod_ID, &
- PLASTICITY_nonlocal_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_VACANCY_generation_ID, &
- LOCAL_THERMAL_adiabatic_ID
+ PLASTICITY_nonlocal_ID
use plastic_titanmod, only: &
plastic_titanmod_microstructure
use plastic_nonlocal, only: &
@@ -586,86 +465,36 @@ subroutine constitutive_microstructure(Tstar_v, Fe, Fp, Lp, subdt, ipc, ip, el)
plastic_dislokmc_microstructure
use plastic_disloucla, only: &
plastic_disloucla_microstructure
- use damage_isoBrittle, only: &
- damage_isoBrittle_microstructure
- use damage_isoDuctile, only: &
- damage_isoDuctile_microstructure
- use damage_anisoBrittle, only: &
- damage_anisoBrittle_microstructure
- use damage_anisoDuctile, only: &
- damage_anisoDuctile_microstructure
- use damage_gurson, only: &
- damage_gurson_microstructure
- use damage_phaseField, only: &
- damage_phaseField_microstructure
- use vacancy_generation, only: &
- vacancy_generation_microstructure
- use thermal_adiabatic, only: &
- thermal_adiabatic_microstructure
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) :: &
Fe, & !< elastic deformation gradient
- Fp, & !< plastic deformation gradient
- Lp
- real(pReal), intent(in) :: &
- subdt !< timestep
+ Fp !< plastic deformation gradient
+ integer(pInt) :: &
+ phase, homog, offset
- select case (phase_plasticity(material_phase(ipc,ip,el)))
+ phase = material_phase(ipc,ip,el)
+ homog = material_homog( ip,el)
+ offset = thermalMapping(homog)%p(ip,el)
+ select case (phase_plasticity(phase))
case (PLASTICITY_DISLOTWIN_ID)
- call plastic_dislotwin_microstructure(constitutive_getTemperature(ipc,ip,el),ipc,ip,el)
+ call plastic_dislotwin_microstructure(temperature(homog)%p(offset),ipc,ip,el)
case (PLASTICITY_DISLOKMC_ID)
- call plastic_dislokmc_microstructure(constitutive_getTemperature(ipc,ip,el),ipc,ip,el)
+ call plastic_dislokmc_microstructure (temperature(homog)%p(offset),ipc,ip,el)
case (PLASTICITY_DISLOUCLA_ID)
- call plastic_disloucla_microstructure(constitutive_getTemperature(ipc,ip,el),ipc,ip,el)
+ call plastic_disloucla_microstructure(temperature(homog)%p(offset),ipc,ip,el)
case (PLASTICITY_TITANMOD_ID)
- call plastic_titanmod_microstructure (constitutive_getTemperature(ipc,ip,el),ipc,ip,el)
+ call plastic_titanmod_microstructure (temperature(homog)%p(offset),ipc,ip,el)
case (PLASTICITY_NONLOCAL_ID)
- call plastic_nonlocal_microstructure (Fe,Fp, ip,el)
+ call plastic_nonlocal_microstructure (Fe,Fp,ip,el)
end select
- select case (phase_damage(material_phase(ipc,ip,el)))
- case (LOCAL_DAMAGE_isoBrittle_ID)
- call damage_isoBrittle_microstructure(constitutive_homogenizedC(ipc,ip,el), Fe, subdt, &
- ipc, ip, el)
- case (LOCAL_DAMAGE_isoDuctile_ID)
- call damage_isoDuctile_microstructure(subdt, ipc, ip, el)
- case (LOCAL_DAMAGE_anisoBrittle_ID)
- call damage_anisoBrittle_microstructure(Tstar_v, subdt, ipc, ip, el)
- case (LOCAL_DAMAGE_anisoDuctile_ID)
- call damage_anisoDuctile_microstructure(subdt, ipc, ip, el)
- case (LOCAL_DAMAGE_gurson_ID)
- call damage_gurson_microstructure(ipc, ip, el)
- case (LOCAL_DAMAGE_phaseField_ID)
- call damage_phaseField_microstructure(constitutive_homogenizedC(ipc,ip,el), Fe, &
- constitutive_getVacancyConcentration(ipc, ip, el), &
- subdt, ipc, ip, el)
-
- end select
-
- select case (phase_thermal(material_phase(ipc,ip,el)))
- case (LOCAL_THERMAL_adiabatic_ID)
- call thermal_adiabatic_microstructure(Tstar_v, Lp, subdt, ipc, ip, el)
-
- end select
-
- select case (phase_vacancy(material_phase(ipc,ip,el)))
- case (LOCAL_VACANCY_generation_ID)
- call vacancy_generation_microstructure(Tstar_v, &
- constitutive_getTemperature(ipc,ip,el), &
- constitutive_getDamage(ipc, ip, el), &
- subdt,ipc,ip,el)
-
- end select
-
end subroutine constitutive_microstructure
@@ -684,6 +513,9 @@ subroutine constitutive_LpAndItsTangent(Lp, dLp_dTstar3333, dLp_dFi3333, Tstar_v
use material, only: &
phase_plasticity, &
material_phase, &
+ material_homog, &
+ temperature, &
+ thermalMapping, &
PLASTICITY_NONE_ID, &
PLASTICITY_J2_ID, &
PLASTICITY_PHENOPOWERLAW_ID, &
@@ -728,11 +560,14 @@ subroutine constitutive_LpAndItsTangent(Lp, dLp_dTstar3333, dLp_dFi3333, Tstar_v
real(pReal), dimension(3,3) :: &
temp_33
integer(pInt) :: &
- i, j
+ i, j, phase, homog, offset
+ phase = material_phase(ipc,ip,el)
+ homog = material_homog( ip,el)
+ offset = thermalMapping(homog)%p(ip,el)
Mstar_v = math_Mandel33to6(math_mul33x33(math_mul33x33(math_transpose33(Fi),Fi), &
math_Mandel6to33(Tstar_v)))
- select case (phase_plasticity(material_phase(ipc,ip,el)))
+ select case (phase_plasticity(phase))
case (PLASTICITY_NONE_ID)
Lp = 0.0_pReal
@@ -743,23 +578,23 @@ subroutine constitutive_LpAndItsTangent(Lp, dLp_dTstar3333, dLp_dFi3333, Tstar_v
call plastic_phenopowerlaw_LpAndItsTangent(Lp,dLp_dMstar,Mstar_v,ipc,ip,el)
case (PLASTICITY_NONLOCAL_ID)
call plastic_nonlocal_LpAndItsTangent(Lp,dLp_dMstar,Mstar_v, &
- constitutive_getTemperature(ipc,ip,el), &
+ temperature(homog)%p(offset), &
ip,el)
case (PLASTICITY_DISLOTWIN_ID)
call plastic_dislotwin_LpAndItsTangent(Lp,dLp_dMstar,Mstar_v, &
- constitutive_getTemperature(ipc,ip,el), &
+ temperature(homog)%p(offset), &
ipc,ip,el)
case (PLASTICITY_DISLOKMC_ID)
call plastic_dislokmc_LpAndItsTangent(Lp,dLp_dMstar,Mstar_v, &
- constitutive_getTemperature(ipc,ip,el), &
+ temperature(homog)%p(offset), &
ipc,ip,el)
case (PLASTICITY_DISLOUCLA_ID)
call plastic_disloucla_LpAndItsTangent(Lp,dLp_dMstar,Mstar_v, &
- constitutive_getTemperature(ipc,ip,el), &
- ipc,ip,el)
+ temperature(homog)%p(offset), &
+ ipc,ip,el)
case (PLASTICITY_TITANMOD_ID)
call plastic_titanmod_LpAndItsTangent(Lp,dLp_dMstar,Mstar_v, &
- constitutive_getTemperature(ipc,ip,el), &
+ temperature(homog)%p(offset), &
ipc,ip,el)
end select
@@ -781,7 +616,7 @@ end subroutine constitutive_LpAndItsTangent
!--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the velocity gradient
!--------------------------------------------------------------------------------------------------
-subroutine constitutive_LiAndItsTangent(Li, dLi_dTstar3333, dLi_dFi3333, Tstar_v, Fi, Lp, ipc, ip, el)
+subroutine constitutive_LiAndItsTangent(Li, dLi_dTstar3333, dLi_dFi3333, Tstar_v, Fi, ipc, ip, el)
use prec, only: &
pReal
use math, only: &
@@ -791,18 +626,24 @@ subroutine constitutive_LiAndItsTangent(Li, dLi_dTstar3333, dLi_dFi3333, Tstar_v
math_transpose33, &
math_mul33x33
use material, only: &
- phase_damage, &
- phase_thermal, &
+ phase_kinematics, &
+ phase_Nkinematics, &
material_phase, &
- LOCAL_DAMAGE_anisoBrittle_ID, &
- LOCAL_DAMAGE_anisoDuctile_ID, &
- LOCAL_THERMAL_adiabatic_ID
- use damage_anisoBrittle, only: &
- damage_anisoBrittle_LdAndItsTangent
- use damage_anisoDuctile, only: &
- damage_anisoDuctile_LdAndItsTangent
- use thermal_adiabatic, only: &
- thermal_adiabatic_LTAndItsTangent
+ KINEMATICS_cleavage_opening_ID, &
+ KINEMATICS_slipplane_opening_ID, &
+ KINEMATICS_thermal_expansion_ID, &
+ KINEMATICS_vacancy_strain_ID, &
+ KINEMATICS_hydrogen_strain_ID
+ use kinematics_cleavage_opening, only: &
+ kinematics_cleavage_opening_LiAndItsTangent
+ use kinematics_slipplane_opening, only: &
+ kinematics_slipplane_opening_LiAndItsTangent
+ use kinematics_thermal_expansion, only: &
+ kinematics_thermal_expansion_LiAndItsTangent
+ use kinematics_vacancy_strain, only: &
+ kinematics_vacancy_strain_LiAndItsTangent
+ use kinematics_hydrogen_strain, only: &
+ kinematics_hydrogen_strain_LiAndItsTangent
implicit none
integer(pInt), intent(in) :: &
@@ -812,49 +653,53 @@ subroutine constitutive_LiAndItsTangent(Li, dLi_dTstar3333, dLi_dFi3333, Tstar_v
real(pReal), intent(in), dimension(6) :: &
Tstar_v !< 2nd Piola-Kirchhoff stress
real(pReal), intent(in), dimension(3,3) :: &
- Fi, & !< intermediate deformation gradient
- Lp !< plastic velocity gradient
+ Fi !< intermediate deformation gradient
real(pReal), intent(out), dimension(3,3) :: &
Li !< intermediate velocity gradient
real(pReal), intent(out), dimension(3,3,3,3) :: &
dLi_dTstar3333, & !< derivative of Li with respect to Tstar (4th-order tensor)
dLi_dFi3333
real(pReal), dimension(3,3) :: &
- Li_temp !< intermediate velocity gradient
+ my_Li !< intermediate velocity gradient
real(pReal), dimension(3,3,3,3) :: &
- dLi_dTstar_temp
+ my_dLi_dTstar
real(pReal), dimension(3,3) :: &
FiInv, &
temp_33
real(pReal) :: &
detFi
integer(pInt) :: &
- i, j
+ i, j, kinematics
Li = 0.0_pReal
dLi_dTstar3333 = 0.0_pReal
dLi_dFi3333 = 0.0_pReal
- select case (phase_damage(material_phase(ipc,ip,el)))
- case (LOCAL_DAMAGE_anisoBrittle_ID)
- call damage_anisoBrittle_LdAndItsTangent(Li_temp, dLi_dTstar_temp, Tstar_v, ipc, ip, el)
- Li = Li + Li_temp
- dLi_dTstar3333 = dLi_dTstar3333 + dLi_dTstar_temp
+ do kinematics = 1_pInt, phase_Nkinematics(material_phase(ipc,ip,el))
+ select case (phase_kinematics(kinematics,material_phase(ipc,ip,el)))
+ case (KINEMATICS_cleavage_opening_ID)
+ call kinematics_cleavage_opening_LiAndItsTangent(my_Li, my_dLi_dTstar, Tstar_v, ipc, ip, el)
- case (LOCAL_DAMAGE_anisoDuctile_ID)
- call damage_anisoDuctile_LdAndItsTangent(Li_temp, dLi_dTstar_temp, Tstar_v, ipc, ip, el)
- Li = Li + Li_temp
- dLi_dTstar3333 = dLi_dTstar3333 + dLi_dTstar_temp
- end select
+ case (KINEMATICS_slipplane_opening_ID)
+ call kinematics_slipplane_opening_LiAndItsTangent(my_Li, my_dLi_dTstar, Tstar_v, ipc, ip, el)
+
+ case (KINEMATICS_thermal_expansion_ID)
+ call kinematics_thermal_expansion_LiAndItsTangent(my_Li, my_dLi_dTstar, ipc, ip, el)
+
+ case (KINEMATICS_vacancy_strain_ID)
+ call kinematics_vacancy_strain_LiAndItsTangent(my_Li, my_dLi_dTstar, ipc, ip, el)
+
+ case (KINEMATICS_hydrogen_strain_ID)
+ call kinematics_hydrogen_strain_LiAndItsTangent(my_Li, my_dLi_dTstar, ipc, ip, el)
+
+ case default
+ my_Li = 0.0_pReal
+ my_dLi_dTstar = 0.0_pReal
+ end select
+ Li = Li + my_Li
+ dLi_dTstar3333 = dLi_dTstar3333 + my_dLi_dTstar
+enddo
- select case (phase_thermal(material_phase(ipc,ip,el)))
- case (LOCAL_THERMAL_adiabatic_ID)
- call thermal_adiabatic_LTAndItsTangent(Li_temp, dLi_dTstar_temp, Tstar_v, Lp, ipc, ip, el)
- Li = Li + Li_temp
- dLi_dTstar3333 = dLi_dTstar3333 + dLi_dTstar_temp
-
- end select
-
FiInv = math_inv33(Fi)
detFi = math_det33(Fi)
Li = math_mul33x33(math_mul33x33(Fi,Li),FiInv)*detFi !< push forward to intermediate configuration
@@ -912,6 +757,17 @@ subroutine constitutive_hooke_TandItsTangent(T, dT_dFe, dT_dFi, Fe, Fi, ipc, ip,
math_transpose33, &
math_trace33, &
math_I3
+ use material, only: &
+ material_phase, &
+ material_homog, &
+ phase_NstiffnessDegradations, &
+ phase_stiffnessDegradation, &
+ damage, &
+ damageMapping, &
+ porosity, &
+ porosityMapping, &
+ STIFFNESS_DEGRADATION_damage_ID, &
+ STIFFNESS_DEGRADATION_porosity_ID
implicit none
integer(pInt), intent(in) :: &
@@ -927,11 +783,27 @@ subroutine constitutive_hooke_TandItsTangent(T, dT_dFe, dT_dFi, Fe, Fi, ipc, ip,
dT_dFe, & !< derivative of 2nd P-K stress with respect to elastic deformation gradient
dT_dFi !< derivative of 2nd P-K stress with respect to intermediate deformation gradient
- integer(pInt) :: i, j
+ integer(pInt) :: i, j, phase, homog
real(pReal), dimension(3,3) :: E
real(pReal), dimension(3,3,3,3) :: C
- C = math_Mandel66to3333(constitutive_damagedC(ipc,ip,el)) !< elastic stiffness in lattice configuration
+ phase = material_phase(ipc,ip,el)
+ homog = material_homog(ip,el)
+ C = math_Mandel66to3333(constitutive_homogenizedC(ipc,ip,el))
+ do i = 1_pInt, phase_NstiffnessDegradations(phase)
+ select case(phase_stiffnessDegradation(i,phase))
+ case (STIFFNESS_DEGRADATION_damage_ID)
+ C = damage(homog)%p(damageMapping(homog)%p(ip,el))* &
+ damage(homog)%p(damageMapping(homog)%p(ip,el))* &
+ C
+
+ case (STIFFNESS_DEGRADATION_porosity_ID)
+ C = porosity(homog)%p(porosityMapping(homog)%p(ip,el))* &
+ porosity(homog)%p(porosityMapping(homog)%p(ip,el))* &
+ C
+ end select
+ enddo
+
E = 0.5_pReal*(math_mul33x33(math_transpose33(Fe),Fe)-math_I3) !< Green-Lagrange strain in unloaded configuration
T = math_mul3333xx33(C,math_mul33x33(math_mul33x33(math_transpose33(Fi),E),Fi)) !< 2PK stress in lattice configuration in work conjugate with GL strain pulled back to lattice configuration
@@ -948,8 +820,7 @@ end subroutine constitutive_hooke_TandItsTangent
!--------------------------------------------------------------------------------------------------
!> @brief contains the constitutive equation for calculating the rate of change of microstructure
!--------------------------------------------------------------------------------------------------
-subroutine constitutive_collectDotState(Tstar_v, Lp, FeArray, FpArray, subdt, subfracArray,&
- ipc, ip, el)
+subroutine constitutive_collectDotState(Tstar_v, FeArray, FpArray, subdt, subfracArray,ipc, ip, el)
use prec, only: &
pReal, &
pLongInt
@@ -964,8 +835,12 @@ subroutine constitutive_collectDotState(Tstar_v, Lp, FeArray, FpArray, subdt, su
mesh_maxNips
use material, only: &
phase_plasticity, &
- phase_damage, &
+ phase_source, &
+ phase_Nsources, &
material_phase, &
+ material_homog, &
+ temperature, &
+ thermalMapping, &
homogenization_maxNgrains, &
PLASTICITY_none_ID, &
PLASTICITY_j2_ID, &
@@ -975,7 +850,9 @@ subroutine constitutive_collectDotState(Tstar_v, Lp, FeArray, FpArray, subdt, su
PLASTICITY_disloucla_ID, &
PLASTICITY_titanmod_ID, &
PLASTICITY_nonlocal_ID, &
- LOCAL_DAMAGE_gurson_ID
+ SOURCE_damage_isoDuctile_ID, &
+ SOURCE_damage_anisoBrittle_ID, &
+ SOURCE_damage_anisoDuctile_ID
use plastic_j2, only: &
plastic_j2_dotState
use plastic_phenopowerlaw, only: &
@@ -990,8 +867,12 @@ subroutine constitutive_collectDotState(Tstar_v, Lp, FeArray, FpArray, subdt, su
plastic_titanmod_dotState
use plastic_nonlocal, only: &
plastic_nonlocal_dotState
- use damage_gurson, only: &
- damage_gurson_dotState
+ use source_damage_isoDuctile, only: &
+ source_damage_isoDuctile_dotState
+ use source_damage_anisoBrittle, only: &
+ source_damage_anisoBrittle_dotState
+ use source_damage_anisoDuctile, only: &
+ source_damage_anisoDuctile_dotState
implicit none
integer(pInt), intent(in) :: &
@@ -1007,42 +888,52 @@ subroutine constitutive_collectDotState(Tstar_v, Lp, FeArray, FpArray, subdt, su
FpArray !< plastic deformation gradient
real(pReal), intent(in), dimension(6) :: &
Tstar_v !< 2nd Piola Kirchhoff stress tensor (Mandel)
- real(pReal), intent(in), dimension(3,3) :: &
- Lp !< plastic velocity gradient
integer(pLongInt) :: &
tick, tock, &
tickrate, &
maxticks
+ integer(pInt) :: &
+ phase, homog, offset, mySource
if (iand(debug_level(debug_constitutive), debug_levelBasic) /= 0_pInt) &
call system_clock(count=tick,count_rate=tickrate,count_max=maxticks)
- select case (phase_plasticity(material_phase(ipc,ip,el)))
+ phase = material_phase(ipc,ip,el)
+ homog = material_homog( ip,el)
+ offset = thermalMapping(homog)%p(ip,el)
+ select case (phase_plasticity(phase))
case (PLASTICITY_J2_ID)
call plastic_j2_dotState (Tstar_v,ipc,ip,el)
case (PLASTICITY_PHENOPOWERLAW_ID)
call plastic_phenopowerlaw_dotState(Tstar_v,ipc,ip,el)
case (PLASTICITY_DISLOTWIN_ID)
- call plastic_dislotwin_dotState (Tstar_v,constitutive_getTemperature(ipc,ip,el), &
+ call plastic_dislotwin_dotState (Tstar_v,temperature(homog)%p(offset), &
ipc,ip,el)
case (PLASTICITY_DISLOKMC_ID)
- call plastic_dislokmc_dotState (Tstar_v,constitutive_getTemperature(ipc,ip,el), &
+ call plastic_dislokmc_dotState (Tstar_v,temperature(homog)%p(offset), &
ipc,ip,el)
case (PLASTICITY_DISLOUCLA_ID)
- call plastic_disloucla_dotState (Tstar_v,constitutive_getTemperature(ipc,ip,el), &
+ call plastic_disloucla_dotState (Tstar_v,temperature(homog)%p(offset), &
ipc,ip,el)
case (PLASTICITY_TITANMOD_ID)
- call plastic_titanmod_dotState (Tstar_v,constitutive_getTemperature(ipc,ip,el), &
+ call plastic_titanmod_dotState (Tstar_v,temperature(homog)%p(offset), &
ipc,ip,el)
case (PLASTICITY_NONLOCAL_ID)
- call plastic_nonlocal_dotState (Tstar_v,FeArray,FpArray,constitutive_getTemperature(ipc,ip,el), &
+ call plastic_nonlocal_dotState (Tstar_v,FeArray,FpArray,temperature(homog)%p(offset), &
subdt,subfracArray,ip,el)
end select
- select case (phase_damage(material_phase(ipc,ip,el)))
- case (LOCAL_DAMAGE_gurson_ID)
- call damage_gurson_dotState(Tstar_v, Lp, ipc, ip, el)
- end select
+ do mySource = 1_pInt, phase_Nsources(phase)
+ select case (phase_source(mySource,phase))
+ case (SOURCE_damage_anisoBrittle_ID)
+ call source_damage_anisoBrittle_dotState(Tstar_v, ipc, ip, el)
+ case (SOURCE_damage_isoDuctile_ID)
+ call source_damage_isoDuctile_dotState ( ipc, ip, el)
+ case (SOURCE_damage_anisoDuctile_ID)
+ call source_damage_anisoDuctile_dotState( ipc, ip, el)
+
+ end select
+ enddo
if (iand(debug_level(debug_constitutive), debug_levelBasic) /= 0_pInt) then
call system_clock(count=tock,count_rate=tickrate,count_max=maxticks)
@@ -1059,7 +950,7 @@ end subroutine constitutive_collectDotState
!> @brief for constitutive models having an instantaneous change of state (so far, only nonlocal)
!> will return false if delta state is not needed/supported by the constitutive model
!--------------------------------------------------------------------------------------------------
-logical function constitutive_collectDeltaState(Tstar_v, ipc, ip, el)
+logical function constitutive_collectDeltaState(Tstar_v, Fe, ipc, ip, el)
use prec, only: &
pReal, &
pLongInt
@@ -1071,10 +962,21 @@ logical function constitutive_collectDeltaState(Tstar_v, ipc, ip, el)
debug_levelBasic
use material, only: &
phase_plasticity, &
+ phase_source, &
+ phase_Nsources, &
material_phase, &
- PLASTICITY_NONLOCAL_ID
+ PLASTICITY_NONLOCAL_ID, &
+ SOURCE_damage_isoBrittle_ID, &
+ SOURCE_vacancy_irradiation_ID, &
+ SOURCE_vacancy_thermalfluc_ID
use plastic_nonlocal, only: &
plastic_nonlocal_deltaState
+ use source_damage_isoBrittle, only: &
+ source_damage_isoBrittle_deltaState
+ use source_vacancy_irradiation, only: &
+ source_vacancy_irradiation_deltaState
+ use source_vacancy_thermalfluc, only: &
+ source_vacancy_thermalfluc_deltaState
implicit none
integer(pInt), intent(in) :: &
@@ -1083,6 +985,10 @@ logical function constitutive_collectDeltaState(Tstar_v, ipc, ip, el)
el !< element number
real(pReal), intent(in), dimension(6) :: &
Tstar_v !< 2nd Piola-Kirchhoff stress
+ real(pReal), intent(in), dimension(3,3) :: &
+ Fe !< elastic deformation gradient
+ integer(pInt) :: &
+ mySource
integer(pLongInt) :: &
tick, tock, &
tickrate, &
@@ -1101,6 +1007,22 @@ logical function constitutive_collectDeltaState(Tstar_v, ipc, ip, el)
end select
+ do mySource = 1_pInt, phase_Nsources(material_phase(ipc,ip,el))
+ select case (phase_source(mySource,material_phase(ipc,ip,el)))
+ case (SOURCE_damage_isoBrittle_ID)
+ constitutive_collectDeltaState = constitutive_collectDeltaState .and. .true.
+ call source_damage_isoBrittle_deltaState (constitutive_homogenizedC(ipc,ip,el), Fe, &
+ ipc, ip, el)
+ case (SOURCE_vacancy_irradiation_ID)
+ constitutive_collectDeltaState = constitutive_collectDeltaState .and. .true.
+ call source_vacancy_irradiation_deltaState(ipc, ip, el)
+ case (SOURCE_vacancy_thermalfluc_ID)
+ constitutive_collectDeltaState = constitutive_collectDeltaState .and. .true.
+ call source_vacancy_thermalfluc_deltaState(ipc, ip, el)
+
+ end select
+ enddo
+
if (iand(debug_level(debug_constitutive), debug_levelBasic) /= 0_pInt) then
call system_clock(count=tock,count_rate=tickrate,count_max=maxticks)
!$OMP CRITICAL (debugTimingDeltaState)
@@ -1114,540 +1036,6 @@ logical function constitutive_collectDeltaState(Tstar_v, ipc, ip, el)
end function constitutive_collectDeltaState
-!--------------------------------------------------------------------------------------------------
-!> @brief Returns the local(regularised) damage
-!--------------------------------------------------------------------------------------------------
-pure function constitutive_getLocalDamage(ipc, ip, el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_DAMAGE_isoBrittle_ID, &
- LOCAL_DAMAGE_isoDuctile_ID, &
- LOCAL_DAMAGE_anisoBrittle_ID, &
- LOCAL_DAMAGE_anisoDuctile_ID, &
- LOCAL_DAMAGE_phaseField_ID, &
- phase_damage
- use damage_isoBrittle, only: &
- damage_isoBrittle_getLocalDamage
- use damage_isoDuctile, only: &
- damage_isoDuctile_getLocalDamage
- use damage_anisoBrittle, only: &
- damage_anisoBrittle_getLocalDamage
- use damage_anisoDuctile, only: &
- damage_anisoDuctile_getLocalDamage
- use damage_phaseField, only: &
- damage_phaseField_getLocalDamage
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal) :: constitutive_getLocalDamage
-
- select case (phase_damage(material_phase(ipc,ip,el)))
- case default
- constitutive_getLocalDamage = 1.0_pReal
-
- case (LOCAL_DAMAGE_isoBrittle_ID)
- constitutive_getLocalDamage = damage_isoBrittle_getLocalDamage(ipc, ip, el)
-
- case (LOCAL_DAMAGE_isoDuctile_ID)
- constitutive_getLocalDamage = damage_isoDuctile_getLocalDamage(ipc, ip, el)
-
- case (LOCAL_DAMAGE_anisoBrittle_ID)
- constitutive_getLocalDamage = damage_anisoBrittle_getLocalDamage(ipc, ip, el)
-
- case (LOCAL_DAMAGE_anisoDuctile_ID)
- constitutive_getLocalDamage = damage_anisoDuctile_getLocalDamage(ipc, ip, el)
-
- case (LOCAL_DAMAGE_phaseField_ID)
- constitutive_getLocalDamage = damage_phaseField_getLocalDamage(ipc, ip, el)
-
- end select
-
-end function constitutive_getLocalDamage
-
-!--------------------------------------------------------------------------------------------------
-!> @brief Returns the local(unregularised) damage
-!--------------------------------------------------------------------------------------------------
-subroutine constitutive_putLocalDamage(ipc, ip, el, localDamage)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_DAMAGE_isoBrittle_ID, &
- LOCAL_DAMAGE_isoDuctile_ID, &
- LOCAL_DAMAGE_anisoBrittle_ID, &
- LOCAL_DAMAGE_anisoDuctile_ID, &
- LOCAL_DAMAGE_gurson_ID, &
- LOCAL_DAMAGE_phaseField_ID, &
- phase_damage
- use damage_isoBrittle, only: &
- damage_isoBrittle_putLocalDamage
- use damage_isoDuctile, only: &
- damage_isoDuctile_putLocalDamage
- use damage_anisoBrittle, only: &
- damage_anisoBrittle_putLocalDamage
- use damage_anisoDuctile, only: &
- damage_anisoDuctile_putLocalDamage
- use damage_gurson, only: &
- damage_gurson_putLocalDamage
- use damage_phaseField, only: &
- damage_phaseField_putLocalDamage
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal), intent(in) :: &
- localDamage
-
- select case (phase_damage(material_phase(ipc,ip,el)))
- case (LOCAL_DAMAGE_isoBrittle_ID)
- call damage_isoBrittle_putLocalDamage(ipc, ip, el, localDamage)
-
- case (LOCAL_DAMAGE_isoDuctile_ID)
- call damage_isoDuctile_putLocalDamage(ipc, ip, el, localDamage)
-
- case (LOCAL_DAMAGE_anisoBrittle_ID)
- call damage_anisoBrittle_putLocalDamage(ipc, ip, el, localDamage)
-
- case (LOCAL_DAMAGE_anisoDuctile_ID)
- call damage_anisoDuctile_putLocalDamage(ipc, ip, el, localDamage)
-
- case (LOCAL_DAMAGE_gurson_ID)
- call damage_gurson_putLocalDamage(ipc, ip, el, localDamage)
-
- case (LOCAL_DAMAGE_phaseField_ID)
- call damage_phaseField_putLocalDamage(ipc, ip, el, localDamage)
-
- end select
-
-end subroutine constitutive_putLocalDamage
-
-!--------------------------------------------------------------------------------------------------
-!> @brief returns nonlocal (regularised) damage
-!--------------------------------------------------------------------------------------------------
-pure function constitutive_getDamage(ipc, ip, el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_DAMAGE_isoBrittle_ID, &
- LOCAL_DAMAGE_isoDuctile_ID, &
- LOCAL_DAMAGE_anisoBrittle_ID, &
- LOCAL_DAMAGE_anisoDuctile_ID, &
- LOCAL_DAMAGE_phaseField_ID, &
- phase_damage
- use damage_isoBrittle, only: &
- damage_isoBrittle_getDamage
- use damage_isoDuctile, only: &
- damage_isoDuctile_getDamage
- use damage_anisoBrittle, only: &
- damage_anisoBrittle_getDamage
- use damage_anisoDuctile, only: &
- damage_anisoDuctile_getDamage
- use damage_phaseField, only: &
- damage_phaseField_getDamage
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal) :: constitutive_getDamage
-
- select case (phase_damage(material_phase(ipc,ip,el)))
- case default
- constitutive_getDamage = 1.0_pReal
-
- case (LOCAL_DAMAGE_isoBrittle_ID)
- constitutive_getDamage = damage_isoBrittle_getDamage(ipc, ip, el)
-
- case (LOCAL_DAMAGE_isoDuctile_ID)
- constitutive_getDamage = damage_isoDuctile_getDamage(ipc, ip, el)
-
- case (LOCAL_DAMAGE_anisoBrittle_ID)
- constitutive_getDamage = damage_anisoBrittle_getDamage(ipc, ip, el)
-
- case (LOCAL_DAMAGE_anisoDuctile_ID)
- constitutive_getDamage = damage_anisoDuctile_getDamage(ipc, ip, el)
-
- case (LOCAL_DAMAGE_phaseField_ID)
- constitutive_getDamage = damage_phaseField_getDamage(ipc, ip, el)
-
- end select
-
-end function constitutive_getDamage
-
-!--------------------------------------------------------------------------------------------------
-!> @brief returns damage diffusion tensor
-!--------------------------------------------------------------------------------------------------
-pure function constitutive_getDamageDiffusion33(ipc, ip, el)
- use prec, only: &
- pReal
- use lattice, only: &
- lattice_DamageDiffusion33
- use material, only: &
- material_phase, &
- phase_damage, &
- LOCAL_DAMAGE_isoBrittle_ID, &
- LOCAL_DAMAGE_anisoBrittle_ID, &
- LOCAL_DAMAGE_phaseField_ID
- use damage_isoBrittle, only: &
- damage_isoBrittle_getDamageDiffusion33
- use damage_anisoBrittle, only: &
- damage_anisoBrittle_getDamageDiffusion33
- use damage_phaseField, only: &
- damage_phaseField_getDamageDiffusion33
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal), dimension(3,3) :: &
- constitutive_getDamageDiffusion33
-
- select case(phase_damage(material_phase(ipc,ip,el)))
- case (LOCAL_DAMAGE_isoBrittle_ID)
- constitutive_getDamageDiffusion33 = damage_isoBrittle_getDamageDiffusion33(ipc, ip, el)
- case (LOCAL_DAMAGE_anisoBrittle_ID)
- constitutive_getDamageDiffusion33 = damage_anisoBrittle_getDamageDiffusion33(ipc, ip, el)
- case (LOCAL_DAMAGE_phaseField_ID)
- constitutive_getDamageDiffusion33 = damage_phaseField_getDamageDiffusion33(ipc, ip, el)
- case default
- constitutive_getDamageDiffusion33 = lattice_DamageDiffusion33(1:3,1:3,material_phase(ipc,ip,el))
-
- end select
-
-end function constitutive_getDamageDiffusion33
-
-!--------------------------------------------------------------------------------------------------
-!> @brief returns local (unregularised) temperature
-!--------------------------------------------------------------------------------------------------
-pure function constitutive_getAdiabaticTemperature(ipc, ip, el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_THERMAL_adiabatic_ID, &
- phase_thermal, &
- phase_thermalInstance
- use thermal_isothermal, only: &
- thermal_isothermal_temperature
- use thermal_adiabatic, only: &
- thermal_adiabatic_getLocalTemperature
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal) :: constitutive_getAdiabaticTemperature
-
- select case (phase_thermal(material_phase(ipc,ip,el)))
- case (LOCAL_THERMAL_adiabatic_ID)
- constitutive_getAdiabaticTemperature = thermal_adiabatic_getLocalTemperature(ipc, ip, el)
-
- case default
- constitutive_getAdiabaticTemperature = &
- thermal_isothermal_temperature(phase_thermalInstance(material_phase(ipc,ip,el)))
-
- end select
-
-end function constitutive_getAdiabaticTemperature
-
-!--------------------------------------------------------------------------------------------------
-!> @brief assigns the local/nonlocal value of temperature to local thermal state
-!--------------------------------------------------------------------------------------------------
-subroutine constitutive_putAdiabaticTemperature(ipc, ip, el, localTemperature)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_THERMAL_adiabatic_ID, &
- phase_thermal
- use thermal_adiabatic, only: &
- thermal_adiabatic_putLocalTemperature
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal), intent(in) :: &
- localTemperature
-
- select case (phase_thermal(material_phase(ipc,ip,el)))
- case (LOCAL_THERMAL_adiabatic_ID)
- call thermal_adiabatic_putLocalTemperature(ipc, ip, el, localTemperature)
-
- end select
-
-end subroutine constitutive_putAdiabaticTemperature
-
-!--------------------------------------------------------------------------------------------------
-!> @brief returns nonlocal (regularised) temperature
-!--------------------------------------------------------------------------------------------------
-pure function constitutive_getTemperature(ipc, ip, el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_THERMAL_adiabatic_ID, &
- phase_thermal
- use thermal_adiabatic, only: &
- thermal_adiabatic_getTemperature
- use thermal_isothermal, only: &
- thermal_isothermal_temperature
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal) :: constitutive_getTemperature
-
- select case (phase_thermal(material_phase(ipc,ip,el)))
- case (LOCAL_THERMAL_adiabatic_ID)
- constitutive_getTemperature = thermal_adiabatic_getTemperature(ipc, ip, el)
-
- case default
- constitutive_getTemperature = thermal_isothermal_temperature(material_phase(ipc,ip,el))
-
- end select
-
-end function constitutive_getTemperature
-
-!--------------------------------------------------------------------------------------------------
-!> @brief returns heat generation rate
-!--------------------------------------------------------------------------------------------------
-pure function constitutive_getHeatGeneration(Tstar_v, Lp, ipc, ip, el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_THERMAL_adiabatic_ID, &
- phase_thermal
- use thermal_adiabatic, only: &
- thermal_adiabatic_getHeatGeneration
-
- 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) :: constitutive_getHeatGeneration
-
- select case (phase_thermal(material_phase(ipc,ip,el)))
- case (LOCAL_THERMAL_adiabatic_ID)
- constitutive_getHeatGeneration = thermal_adiabatic_getHeatGeneration(Tstar_v, Lp)
-
- case default
- constitutive_getHeatGeneration = 0.0_pReal
-
- end select
-
-end function constitutive_getHeatGeneration
-
-!--------------------------------------------------------------------------------------------------
-!> @brief returns local vacancy concentration
-!--------------------------------------------------------------------------------------------------
-pure function constitutive_getLocalVacancyConcentration(ipc, ip, el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_VACANCY_generation_ID, &
- phase_vacancy
- use vacancy_generation, only: &
- vacancy_generation_getLocalConcentration
- use lattice, only: &
- lattice_equilibriumVacancyConcentration
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal) :: constitutive_getLocalVacancyConcentration
-
- select case (phase_vacancy(material_phase(ipc,ip,el)))
- case (LOCAL_VACANCY_generation_ID)
- constitutive_getLocalVacancyConcentration = vacancy_generation_getLocalConcentration(ipc, ip, el)
-
- case default
- constitutive_getLocalVacancyConcentration = &
- lattice_equilibriumVacancyConcentration(material_phase(ipc,ip,el))
-
- end select
-
-end function constitutive_getLocalVacancyConcentration
-
-!--------------------------------------------------------------------------------------------------
-!> @brief Puts local vacancy concentration
-!--------------------------------------------------------------------------------------------------
-subroutine constitutive_putLocalVacancyConcentration(ipc, ip, el, localVacancyConcentration)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_VACANCY_generation_ID, &
- phase_vacancy
- use vacancy_generation, only: &
- vacancy_generation_putLocalConcentration
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal), intent(in) :: &
- localVacancyConcentration
-
- select case (phase_vacancy(material_phase(ipc,ip,el)))
- case (LOCAL_VACANCY_generation_ID)
- call vacancy_generation_putLocalConcentration(ipc, ip, el, localVacancyConcentration)
-
- end select
-
-end subroutine constitutive_putLocalVacancyConcentration
-
-!--------------------------------------------------------------------------------------------------
-!> @brief returns nonlocal vacancy concentration
-!--------------------------------------------------------------------------------------------------
-pure function constitutive_getVacancyConcentration(ipc, ip, el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_VACANCY_generation_ID, &
- phase_vacancy
- use vacancy_generation, only: &
- vacancy_generation_getConcentration
- use lattice, only: &
- lattice_equilibriumVacancyConcentration
- implicit none
-
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal) :: constitutive_getVacancyConcentration
-
- select case (phase_vacancy(material_phase(ipc,ip,el)))
- case (LOCAL_VACANCY_generation_ID)
- constitutive_getVacancyConcentration = vacancy_generation_getConcentration(ipc, ip, el)
-
- case default
- constitutive_getVacancyConcentration = &
- lattice_equilibriumVacancyConcentration(material_phase(ipc,ip,el))
-
- end select
-
-end function constitutive_getVacancyConcentration
-
-!--------------------------------------------------------------------------------------------------
-!> @brief returns vacancy diffusion tensor
-!--------------------------------------------------------------------------------------------------
-pure function constitutive_getVacancyDiffusion33(ipc, ip, el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_VACANCY_generation_ID, &
- phase_vacancy
- use vacancy_generation, only: &
- vacancy_generation_getVacancyDiffusion33
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal), dimension(3,3) :: &
- constitutive_getVacancyDiffusion33
-
- select case(phase_vacancy(material_phase(ipc,ip,el)))
- case (LOCAL_VACANCY_generation_ID)
- constitutive_getVacancyDiffusion33 = &
- vacancy_generation_getVacancyDiffusion33(ipc,ip,el)
-
- end select
-
-end function constitutive_getVacancyDiffusion33
-
-!--------------------------------------------------------------------------------------------------
-!> @brief returns vacancy diffusion tensor
-!--------------------------------------------------------------------------------------------------
-pure function constitutive_getVacancyMobility33(ipc, ip, el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_VACANCY_generation_ID, &
- phase_vacancy
- use vacancy_generation, only: &
- vacancy_generation_getVacancyMobility33
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
- real(pReal), dimension(3,3) :: &
- constitutive_getVacancyMobility33
-
- select case(phase_vacancy(material_phase(ipc,ip,el)))
- case (LOCAL_VACANCY_generation_ID)
- constitutive_getVacancyMobility33 = &
- vacancy_generation_getVacancyMobility33(constitutive_getTemperature(ipc,ip,el), &
- ipc,ip,el)
-
- end select
-
-end function constitutive_getVacancyMobility33
-
-!--------------------------------------------------------------------------------------------------
-!> @brief returns vacancy chemical potential driving force
-!--------------------------------------------------------------------------------------------------
-pure real(pReal) function constitutive_getVacancyEnergy(ipc, ip, el)
- use prec, only: &
- pReal
- use material, only: &
- material_phase, &
- LOCAL_VACANCY_generation_ID, &
- phase_vacancy
- use vacancy_generation, only: &
- vacancy_generation_getVacancyEnergy
-
- implicit none
- integer(pInt), intent(in) :: &
- ipc, & !< grain number
- ip, & !< integration point number
- el !< element number
-
- select case(phase_vacancy(material_phase(ipc,ip,el)))
- case (LOCAL_VACANCY_generation_ID)
- constitutive_getVacancyEnergy = &
- vacancy_generation_getVacancyEnergy(ipc,ip,el)
-
- case default
- constitutive_getVacancyEnergy = 0.0_pReal
-
- end select
-
-end function constitutive_getVacancyEnergy
-
-
!--------------------------------------------------------------------------------------------------
!> @brief returns array of constitutive results
!--------------------------------------------------------------------------------------------------
@@ -1659,14 +1047,14 @@ function constitutive_postResults(Tstar_v, FeArray, ipc, ip, el)
mesh_maxNips
use material, only: &
plasticState, &
- damageState, &
- thermalState, &
- vacancyState, &
+ sourceState, &
phase_plasticity, &
- phase_damage, &
- phase_thermal, &
- phase_vacancy, &
+ phase_source, &
+ phase_Nsources, &
material_phase, &
+ material_homog, &
+ temperature, &
+ thermalMapping, &
homogenization_maxNgrains, &
PLASTICITY_NONE_ID, &
PLASTICITY_J2_ID, &
@@ -1676,14 +1064,10 @@ function constitutive_postResults(Tstar_v, FeArray, ipc, ip, el)
PLASTICITY_DISLOUCLA_ID, &
PLASTICITY_TITANMOD_ID, &
PLASTICITY_NONLOCAL_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_ADIABATIC_ID, &
- LOCAL_VACANCY_generation_ID
+ SOURCE_damage_isoBrittle_ID, &
+ SOURCE_damage_isoDuctile_ID, &
+ SOURCE_damage_anisoBrittle_ID, &
+ SOURCE_damage_anisoDuctile_ID
use plastic_j2, only: &
#ifdef HDF
plastic_j2_postResults2,&
@@ -1701,22 +1085,14 @@ function constitutive_postResults(Tstar_v, FeArray, ipc, ip, el)
plastic_titanmod_postResults
use plastic_nonlocal, only: &
plastic_nonlocal_postResults
- use damage_isoBrittle, only: &
- damage_isoBrittle_postResults
- use damage_isoDuctile, only: &
- damage_isoDuctile_postResults
- use damage_anisoBrittle, only: &
- damage_anisoBrittle_postResults
- use damage_anisoDuctile, only: &
- damage_anisoDuctile_postResults
- use damage_gurson, only: &
- damage_gurson_postResults
- use damage_phaseField, only: &
- damage_phaseField_postResults
- use thermal_adiabatic, only: &
- thermal_adiabatic_postResults
- use vacancy_generation, only: &
- vacancy_generation_postResults
+ use source_damage_isoBrittle, only: &
+ source_damage_isoBrittle_postResults
+ use source_damage_isoDuctile, only: &
+ source_damage_isoDuctile_postResults
+ use source_damage_anisoBrittle, only: &
+ source_damage_anisoBrittle_postResults
+ use source_damage_anisoDuctile, only: &
+ source_damage_anisoDuctile_postResults
implicit none
integer(pInt), intent(in) :: &
@@ -1724,19 +1100,21 @@ function constitutive_postResults(Tstar_v, FeArray, ipc, ip, el)
ip, & !< integration point number
el !< element number
real(pReal), dimension(plasticState(material_phase(ipc,ip,el))%sizePostResults + &
- damageState( material_phase(ipc,ip,el))%sizePostResults + &
- thermalState(material_phase(ipc,ip,el))%sizePostResults + &
- vacancyState(material_phase(ipc,ip,el))%sizePostResults) :: &
+ sum(sourceState(material_phase(ipc,ip,el))%p(:)%sizePostResults)) :: &
constitutive_postResults
real(pReal), intent(in), dimension(3,3,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
FeArray !< elastic deformation gradient
real(pReal), intent(in), dimension(6) :: &
Tstar_v !< 2nd Piola Kirchhoff stress tensor (Mandel)
integer(pInt) :: &
- startPos, endPos
+ startPos, endPos, phase, homog, offset, mySource
constitutive_postResults = 0.0_pReal
+ phase = material_phase(ipc,ip,el)
+ homog = material_homog( ip,el)
+ offset = thermalMapping(homog)%p(ip,el)
+
startPos = 1_pInt
endPos = plasticState(material_phase(ipc,ip,el))%sizePostResults
select case (phase_plasticity(material_phase(ipc,ip,el)))
@@ -1749,50 +1127,33 @@ function constitutive_postResults(Tstar_v, FeArray, ipc, ip, el)
plastic_phenopowerlaw_postResults(Tstar_v,ipc,ip,el)
case (PLASTICITY_DISLOTWIN_ID)
constitutive_postResults(startPos:endPos) = &
- plastic_dislotwin_postResults(Tstar_v,constitutive_getTemperature(ipc,ip,el),ipc,ip,el)
+ plastic_dislotwin_postResults(Tstar_v,temperature(homog)%p(offset),ipc,ip,el)
case (PLASTICITY_DISLOKMC_ID)
constitutive_postResults(startPos:endPos) = &
- plastic_dislokmc_postResults(Tstar_v,constitutive_getTemperature(ipc,ip,el),ipc,ip,el)
+ plastic_dislokmc_postResults(Tstar_v,temperature(homog)%p(offset),ipc,ip,el)
case (PLASTICITY_DISLOUCLA_ID)
constitutive_postResults(startPos:endPos) = &
- plastic_disloucla_postResults(Tstar_v,constitutive_getTemperature(ipc,ip,el),ipc,ip,el)
+ plastic_disloucla_postResults(Tstar_v,temperature(homog)%p(offset),ipc,ip,el)
case (PLASTICITY_NONLOCAL_ID)
constitutive_postResults(startPos:endPos) = &
plastic_nonlocal_postResults (Tstar_v,FeArray,ip,el)
end select
- startPos = endPos + 1_pInt
- endPos = endPos + damageState(material_phase(ipc,ip,el))%sizePostResults
- select case (phase_damage(material_phase(ipc,ip,el)))
- case (LOCAL_DAMAGE_isoBrittle_ID)
- constitutive_postResults(startPos:endPos) = damage_isoBrittle_postResults(ipc, ip, el)
- case (LOCAL_DAMAGE_isoDuctile_ID)
- constitutive_postResults(startPos:endPos) = damage_isoDuctile_postResults(ipc, ip, el)
- case (LOCAL_DAMAGE_anisoBrittle_ID)
- constitutive_postResults(startPos:endPos) = damage_anisoBrittle_postResults(ipc, ip, el)
- case (LOCAL_DAMAGE_anisoDuctile_ID)
- constitutive_postResults(startPos:endPos) = damage_anisoDuctile_postResults(ipc, ip, el)
- case (LOCAL_DAMAGE_gurson_ID)
- constitutive_postResults(startPos:endPos) = damage_gurson_postResults(ipc, ip, el)
- case (LOCAL_DAMAGE_phaseField_ID)
- constitutive_postResults(startPos:endPos) = damage_phaseField_postResults(ipc, ip, el)
- end select
+ do mySource = 1_pInt, phase_Nsources(phase)
+ startPos = endPos + 1_pInt
+ endPos = endPos + sourceState(material_phase(ipc,ip,el))%p(mySource)%sizePostResults
+ select case (phase_source(mySource,material_phase(ipc,ip,el)))
+ case (SOURCE_damage_isoBrittle_ID)
+ constitutive_postResults(startPos:endPos) = source_damage_isoBrittle_postResults(ipc, ip, el)
+ case (SOURCE_damage_isoDuctile_ID)
+ constitutive_postResults(startPos:endPos) = source_damage_isoDuctile_postResults(ipc, ip, el)
+ case (SOURCE_damage_anisoBrittle_ID)
+ constitutive_postResults(startPos:endPos) = source_damage_anisoBrittle_postResults(ipc, ip, el)
+ case (SOURCE_damage_anisoDuctile_ID)
+ constitutive_postResults(startPos:endPos) = source_damage_anisoDuctile_postResults(ipc, ip, el)
+ end select
+ enddo
- startPos = endPos + 1_pInt
- endPos = endPos + thermalState(material_phase(ipc,ip,el))%sizePostResults
- select case (phase_thermal(material_phase(ipc,ip,el)))
- case (LOCAL_THERMAL_ADIABATIC_ID)
- constitutive_postResults(startPos:endPos) = thermal_adiabatic_postResults(ipc, ip, el)
- end select
-
- startPos = endPos + 1_pInt
- endPos = endPos + vacancyState(material_phase(ipc,ip,el))%sizePostResults
- select case (phase_vacancy(material_phase(ipc,ip,el)))
- case (LOCAL_VACANCY_generation_ID)
- constitutive_postResults(startPos:endPos) = vacancy_generation_postResults(ipc, ip, el)
- end select
-
end function constitutive_postResults
-
end module constitutive
diff --git a/code/crystallite.f90 b/code/crystallite.f90
index 98edb62eb..8bcc539fc 100644
--- a/code/crystallite.f90
+++ b/code/crystallite.f90
@@ -55,9 +55,9 @@ module crystallite
crystallite_Li, & !< current intermediate velocitiy grad (end of converged time step)
crystallite_Li0, & !< intermediate velocitiy grad at start of FE inc
crystallite_partionedLi0,& !< intermediate velocity grad at start of homog inc
+ crystallite_Fe, & !< current "elastic" def grad (end of converged time step)
crystallite_P !< 1st Piola-Kirchhoff stress per grain
real(pReal), dimension(:,:,:,:,:), allocatable, private :: &
- crystallite_Fe, & !< current "elastic" def grad (end of converged time step)
crystallite_subFe0,& !< "elastic" def grad at start of crystallite inc
crystallite_invFp, & !< inverse of current plastic def grad (end of converged time step)
crystallite_subFp0,& !< plastic def grad at start of crystallite inc
@@ -443,11 +443,9 @@ subroutine crystallite_init
do i = FEsolving_execIP(1,e),FEsolving_execIP(2,e)
do g = 1_pInt,myNgrains
call constitutive_microstructure( &
- crystallite_Tstar_v(1:6,g,i,e), &
crystallite_Fe(1:3,1:3,g,i,e), &
crystallite_Fp(1:3,1:3,g,i,e), &
- crystallite_Lp(1:3,1:3,g,i,e), &
- crystallite_subdt(g,i,e), g,i,e) ! update dependent state variables to be consistent with basic states
+ g,i,e) ! update dependent state variables to be consistent with basic states
enddo
enddo
enddo
@@ -574,9 +572,8 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
use material, only: &
homogenization_Ngrains, &
plasticState, &
- damageState, &
- thermalState, &
- vacancyState, &
+ sourceState, &
+ phase_Nsources, &
mappingConstitutive, &
homogenization_maxNgrains
use constitutive, only: &
@@ -623,7 +620,8 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
o, &
p, &
perturbation , & ! loop counter for forward,backward perturbation mode
- myNgrains
+ myNgrains, &
+ mySource
logical, dimension(homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
convergenceFlag_backup
! local variables used for calculating analytic Jacobian
@@ -670,31 +668,30 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
!$OMP PARALLEL DO PRIVATE(myNgrains)
elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2)
myNgrains = homogenization_Ngrains(mesh_element(3,e))
- forall (i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
- g = 1_pInt:myNgrains, crystallite_requested(g,i,e))
- plasticState(mappingConstitutive(2,g,i,e))%subState0( :,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%subState0( :,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%subState0( :,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%subState0( :,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e))
- crystallite_subFp0(1:3,1:3,g,i,e) = crystallite_partionedFp0(1:3,1:3,g,i,e) ! ...plastic def grad
- crystallite_subLp0(1:3,1:3,g,i,e) = crystallite_partionedLp0(1:3,1:3,g,i,e) ! ...plastic velocity grad
- crystallite_subFi0(1:3,1:3,g,i,e) = crystallite_partionedFi0(1:3,1:3,g,i,e) ! ...intermediate def grad
- crystallite_subLi0(1:3,1:3,g,i,e) = crystallite_partionedLi0(1:3,1:3,g,i,e) ! ...intermediate velocity grad
- crystallite_dPdF0(1:3,1:3,1:3,1:3,g,i,e) = crystallite_partioneddPdF0(1:3,1:3,1:3,1:3,g,i,e) ! ...stiffness
- crystallite_subF0(1:3,1:3,g,i,e) = crystallite_partionedF0(1:3,1:3,g,i,e) ! ...def grad
- crystallite_subTstar0_v(1:6,g,i,e) = crystallite_partionedTstar0_v(1:6,g,i,e) !...2nd PK stress
- crystallite_subFe0(1:3,1:3,g,i,e) = math_mul33x33(math_mul33x33(crystallite_subF0(1:3,1:3,g,i,e), &
- math_inv33(crystallite_subFp0(1:3,1:3,g,i,e))), &
- math_inv33(crystallite_subFi0(1:3,1:3,g,i,e)))! only needed later on for stiffness calculation
- crystallite_subFrac(g,i,e) = 0.0_pReal
- crystallite_subStep(g,i,e) = 1.0_pReal/subStepSizeCryst
- crystallite_todo(g,i,e) = .true.
- crystallite_converged(g,i,e) = .false. ! pretend failed step of twice the required size
- endforall
+ do i = FEsolving_execIP(1,e),FEsolving_execIP(2,e); do g = 1_pInt,myNgrains
+ if (crystallite_requested(g,i,e)) then
+ plasticState (mappingConstitutive(2,g,i,e))%subState0( :,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%subState0( :,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%partionedState0(:,mappingConstitutive(1,g,i,e))
+ enddo
+ crystallite_subFp0(1:3,1:3,g,i,e) = crystallite_partionedFp0(1:3,1:3,g,i,e) ! ...plastic def grad
+ crystallite_subLp0(1:3,1:3,g,i,e) = crystallite_partionedLp0(1:3,1:3,g,i,e) ! ...plastic velocity grad
+ crystallite_subFi0(1:3,1:3,g,i,e) = crystallite_partionedFi0(1:3,1:3,g,i,e) ! ...intermediate def grad
+ crystallite_subLi0(1:3,1:3,g,i,e) = crystallite_partionedLi0(1:3,1:3,g,i,e) ! ...intermediate velocity grad
+ crystallite_dPdF0(1:3,1:3,1:3,1:3,g,i,e) = crystallite_partioneddPdF0(1:3,1:3,1:3,1:3,g,i,e) ! ...stiffness
+ crystallite_subF0(1:3,1:3,g,i,e) = crystallite_partionedF0(1:3,1:3,g,i,e) ! ...def grad
+ crystallite_subTstar0_v(1:6,g,i,e) = crystallite_partionedTstar0_v(1:6,g,i,e) !...2nd PK stress
+ crystallite_subFe0(1:3,1:3,g,i,e) = math_mul33x33(math_mul33x33(crystallite_subF0(1:3,1:3,g,i,e), &
+ math_inv33(crystallite_subFp0(1:3,1:3,g,i,e))), &
+ math_inv33(crystallite_subFi0(1:3,1:3,g,i,e)))! only needed later on for stiffness calculation
+ crystallite_subFrac(g,i,e) = 0.0_pReal
+ crystallite_subStep(g,i,e) = 1.0_pReal/subStepSizeCryst
+ crystallite_todo(g,i,e) = .true.
+ crystallite_converged(g,i,e) = .false. ! pretend failed step of twice the required size
+ endif
+ enddo; enddo
enddo elementLooping1
!$OMP END PARALLEL DO
@@ -963,14 +960,12 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
crystallite_invFp(1:3,1:3,g,i,e)), &
crystallite_invFi(1:3,1:3,g,i,e)) ! only needed later on for stiffness calculation
!if abbrevation, make c and p private in omp
- plasticState(mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%subState0(:,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state( :,mappingConstitutive(1,g,i,e))
+ enddo
crystallite_subTstar0_v(1:6,g,i,e) = crystallite_Tstar_v(1:6,g,i,e) ! ...2nd PK stress
if (crystallite_syncSubFrac(i,e)) then ! if we just did a synchronization of states, then we wind forward without any further time integration
crystallite_syncSubFracCompleted(i,e) = .true.
@@ -1019,14 +1014,12 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
!$OMP FLUSH(crystallite_invFi)
crystallite_Lp(1:3,1:3,g,i,e) = crystallite_subLp0(1:3,1:3,g,i,e) ! ...plastic velocity grad
crystallite_Li(1:3,1:3,g,i,e) = crystallite_subLi0(1:3,1:3,g,i,e) ! ...intermediate velocity grad
- plasticState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state( :,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%subState0(:,mappingConstitutive(1,g,i,e))
+ enddo
crystallite_Tstar_v(1:6,g,i,e) = crystallite_subTstar0_v(1:6,g,i,e) ! ...2nd PK stress
! cant restore dotState here, since not yet calculated in first cutback after initialization
@@ -1176,7 +1169,7 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
crystallite_Fi(1:3,1:3,g,i,e),g,i,e) ! call constitutive law to calculate elastic stress tangent
call constitutive_LiAndItsTangent(temp_33,dLidS,dLidFi,crystallite_Tstar_v(1:6,g,i,e), &
- crystallite_Fi(1:3,1:3,g,i,e),crystallite_Lp(1:3,1:3,g,i,e), &
+ crystallite_Fi(1:3,1:3,g,i,e), &
g,i,e) ! call constitutive law to calculate Li tangent in lattice configuration
if (sum(abs(dLidS)) < tol_math_check) then
dFidS = 0.0_pReal
@@ -1286,25 +1279,21 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
!$OMP PARALLEL DO PRIVATE(myNgrains)
elementLooping7: do e = FEsolving_execElem(1),FEsolving_execElem(2)
myNgrains = homogenization_Ngrains(mesh_element(3,e))
- forall (i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), g = 1:myNgrains)
+ do i = FEsolving_execIP(1,e),FEsolving_execIP(2,e); do g = 1,myNgrains
- plasticState(mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state_backup(:,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state( :,mappingConstitutive(1,g,i,e))
+ enddo
- plasticState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%dotState_backup(:,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%dotState( :,mappingConstitutive(1,g,i,e))
+ enddo
F_backup(1:3,1:3,g,i,e) = crystallite_subF(1:3,1:3,g,i,e) ! ... and kinematics
Fp_backup(1:3,1:3,g,i,e) = crystallite_Fp(1:3,1:3,g,i,e)
@@ -1317,7 +1306,7 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
Tstar_v_backup(1:6,g,i,e) = crystallite_Tstar_v(1:6,g,i,e)
P_backup(1:3,1:3,g,i,e) = crystallite_P(1:3,1:3,g,i,e)
convergenceFlag_backup(g,i,e) = crystallite_converged(g,i,e)
- endforall
+ enddo; enddo
enddo elementLooping7
!$END PARALLEL DO
! --- CALCULATE STATE AND STRESS FOR PERTURBATION ---
@@ -1339,25 +1328,21 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
!why not OMP? ! Fix-point method: restore to last converged state at end of subinc, since this is probably closest to perturbed state
do e = FEsolving_execElem(1),FEsolving_execElem(2)
myNgrains = homogenization_Ngrains(mesh_element(3,e))
- forall (i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), g = 1:myNgrains)
+ do i = FEsolving_execIP(1,e),FEsolving_execIP(2,e); do g = 1,myNgrains
- plasticState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state( :,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state_backup(:,mappingConstitutive(1,g,i,e))
+ enddo
- plasticState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%dotState( :,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%dotState_backup(:,mappingConstitutive(1,g,i,e))
+ enddo
crystallite_Fp(1:3,1:3,g,i,e) = Fp_backup(1:3,1:3,g,i,e)
crystallite_invFp(1:3,1:3,g,i,e) = InvFp_backup(1:3,1:3,g,i,e)
@@ -1367,32 +1352,28 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
crystallite_Lp(1:3,1:3,g,i,e) = Lp_backup(1:3,1:3,g,i,e)
crystallite_Li(1:3,1:3,g,i,e) = Li_backup(1:3,1:3,g,i,e)
crystallite_Tstar_v(1:6,g,i,e) = Tstar_v_backup(1:6,g,i,e)
- endforall
+ enddo; enddo
enddo
case(2_pInt,3_pInt) ! explicit Euler methods: nothing to restore (except for F), since we are only doing a stress integration step
case(4_pInt,5_pInt)
!why not OMP? ! explicit Runge-Kutta methods: restore to start of subinc, since we are doing a full integration of state and stress
do e = FEsolving_execElem(1),FEsolving_execElem(2)
myNgrains = homogenization_Ngrains(mesh_element(3,e))
- forall (i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), g = 1:myNgrains)
+ do i = FEsolving_execIP(1,e),FEsolving_execIP(2,e); do g = 1,myNgrains
- plasticState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%subState0(:,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state( :,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%subState0(:,mappingConstitutive(1,g,i,e))
+ enddo
- plasticState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%dotState( :,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%dotState_backup(:,mappingConstitutive(1,g,i,e))
+ enddo
crystallite_Fp(1:3,1:3,g,i,e) = crystallite_subFp0(1:3,1:3,g,i,e)
crystallite_Fi(1:3,1:3,g,i,e) = crystallite_subFi0(1:3,1:3,g,i,e)
@@ -1400,7 +1381,7 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
crystallite_Lp(1:3,1:3,g,i,e) = crystallite_subLp0(1:3,1:3,g,i,e)
crystallite_Li(1:3,1:3,g,i,e) = crystallite_subLi0(1:3,1:3,g,i,e)
crystallite_Tstar_v(1:6,g,i,e) = crystallite_subTstar0_v(1:6,g,i,e)
- endforall
+ enddo; enddo
enddo
end select
@@ -1480,25 +1461,21 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
!why not OMP?
elementLooping10: do e = FEsolving_execElem(1),FEsolving_execElem(2)
myNgrains = homogenization_Ngrains(mesh_element(3,e))
- forall (i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), g = 1:myNgrains)
+ do i = FEsolving_execIP(1,e),FEsolving_execIP(2,e); do g = 1,myNgrains
- plasticState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%state_backup(:,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state( :,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state_backup(:,mappingConstitutive(1,g,i,e))
+ enddo
- plasticState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%dotState( :,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%dotState_backup(:,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%dotState( :,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%dotState_backup(:,mappingConstitutive(1,g,i,e))
+ enddo
crystallite_subF(1:3,1:3,g,i,e) = F_backup(1:3,1:3,g,i,e)
crystallite_Fp(1:3,1:3,g,i,e) = Fp_backup(1:3,1:3,g,i,e)
@@ -1511,7 +1488,7 @@ subroutine crystallite_stressAndItsTangent(updateJaco)
crystallite_Tstar_v(1:6,g,i,e) = Tstar_v_backup(1:6,g,i,e)
crystallite_P(1:3,1:3,g,i,e) = P_backup(1:3,1:3,g,i,e)
crystallite_converged(g,i,e) = convergenceFlag_backup(g,i,e)
- endforall
+ enddo; enddo
enddo elementLooping10
endif jacobianMethod
@@ -1548,9 +1525,9 @@ subroutine crystallite_integrateStateRK4()
use material, only: &
homogenization_Ngrains, &
plasticState, &
- damageState, &
- thermalState, &
- vacancyState, &
+ sourceState, &
+ phase_Nsources, &
+ material_Nphase, &
mappingConstitutive
use constitutive, only: &
constitutive_collectDotState, &
@@ -1568,14 +1545,14 @@ subroutine crystallite_integrateStateRK4()
p, & ! phase loop
c, &
n, &
+ mySource, &
mySizePlasticDotState, &
- mySizeDamageDotState, &
- mySizeThermalDotState, &
- mySizeVacancyDotState
+ mySizeSourceDotState
integer(pInt), dimension(2) :: eIter ! bounds for element iteration
integer(pInt), dimension(2,mesh_NcpElems) :: iIter, & ! bounds for ip iteration
gIter ! bounds for grain iteration
- logical :: singleRun ! flag indicating computation for single (g,i,e) triple
+ logical :: isNaN, &
+ singleRun ! flag indicating computation for single (g,i,e) triple
eIter = FEsolving_execElem(1:2)
do e = eIter(1),eIter(2)
@@ -1588,18 +1565,20 @@ subroutine crystallite_integrateStateRK4()
!--------------------------------------------------------------------------------------------------
! initialize dotState
if (.not. singleRun) then
- forall(p = 1_pInt:size(plasticState)) plasticState(p)%RK4dotState = 0.0_pReal
- forall(p = 1_pInt:size(damageState)) damageState(p)%RK4dotState = 0.0_pReal
- forall(p = 1_pInt:size(thermalState)) thermalState(p)%RK4dotState = 0.0_pReal
- forall(p = 1_pInt:size(vacancyState)) vacancyState(p)%RK4dotState = 0.0_pReal
+ do p = 1_pInt, material_Nphase
+ plasticState(p)%RK4dotState = 0.0_pReal
+ do mySource = 1_pInt, phase_Nsources(p)
+ sourceState(p)%p(mySource)%RK4dotState = 0.0_pReal
+ enddo
+ enddo
else
e = eIter(1)
i = iIter(1,e)
do g = iIter(1,e), iIter(2,e)
- plasticState(mappingConstitutive(2,g,i,e))%RK4dotState(:,mappingConstitutive(1,g,i,e)) = 0.0_pReal
- damageState( mappingConstitutive(2,g,i,e))%RK4dotState(:,mappingConstitutive(1,g,i,e)) = 0.0_pReal
- thermalState(mappingConstitutive(2,g,i,e))%RK4dotState(:,mappingConstitutive(1,g,i,e)) = 0.0_pReal
- vacancyState(mappingConstitutive(2,g,i,e))%RK4dotState(:,mappingConstitutive(1,g,i,e)) = 0.0_pReal
+ plasticState (mappingConstitutive(2,g,i,e))%RK4dotState(:,mappingConstitutive(1,g,i,e)) = 0.0_pReal
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%RK4dotState(:,mappingConstitutive(1,g,i,e)) = 0.0_pReal
+ enddo
enddo
endif
@@ -1609,27 +1588,30 @@ subroutine crystallite_integrateStateRK4()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), crystallite_Lp(1:3,1:3,g,i,e), &
+ call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), &
crystallite_Fe, &
crystallite_Fp, &
crystallite_subdt(g,i,e), crystallite_subFrac, g,i,e)
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(p,c)
+ !$OMP DO PRIVATE(p,c,isNaN)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
!$OMP FLUSH(crystallite_todo)
if (crystallite_todo(g,i,e)) then
c = mappingConstitutive(1,g,i,e)
p = mappingConstitutive(2,g,i,e)
- if ( any(prec_isNaN([plasticState(p)%dotState(:,c), damageState(p)%dotState(:,c), &
- thermalState(p)%dotState(:,c), vacancyState(p)%dotState(:,c)]))) then ! NaN occured in any dotState
- if (.not. crystallite_localPlasticity(g,i,e)) then ! if broken non-local...
+ isNaN = any(prec_isNaN(plasticState(p)%dotState(:,c)))
+ do mySource = 1_pInt, phase_Nsources(p)
+ isNaN = isNaN .or. any(prec_isNaN(sourceState(p)%p(mySource)%dotState(:,c)))
+ enddo
+ if (isNaN) then ! NaN occured in any dotState
+ if (.not. crystallite_localPlasticity(g,i,e)) then ! if broken non-local...
!$OMP CRITICAL (checkTodo)
- crystallite_todo = crystallite_todo .and. crystallite_localPlasticity ! ...all non-locals skipped
+ crystallite_todo = crystallite_todo .and. crystallite_localPlasticity ! ...all non-locals skipped
!$OMP END CRITICAL (checkTodo)
- else ! if broken local...
- crystallite_todo(g,i,e) = .false. ! ... skip this one next time
+ else ! if broken local...
+ crystallite_todo(g,i,e) = .false. ! ... skip this one next time
endif
endif
endif
@@ -1648,41 +1630,34 @@ subroutine crystallite_integrateStateRK4()
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
-
plasticState(p)%RK4dotState(:,c) = plasticState(p)%RK4dotState(:,c) &
+ weight(n)*plasticState(p)%dotState(:,c)
- damageState(p)%RK4dotState(:,c) = damageState(p)%RK4dotState(:,c) &
- + weight(n)*damageState(p)%dotState(:,c)
- thermalState(p)%RK4dotState(:,c) = thermalState(p)%RK4dotState(:,c) &
- + weight(n)*thermalState(p)%dotState(:,c)
- vacancyState(p)%RK4dotState(:,c) = vacancyState(p)%RK4dotState(:,c) &
- + weight(n)*vacancyState(p)%dotState(:,c)
+ do mySource = 1_pInt, phase_Nsources(p)
+ sourceState(p)%p(mySource)%RK4dotState(:,c) = sourceState(p)%p(mySource)%RK4dotState(:,c) &
+ + weight(n)*sourceState(p)%p(mySource)%dotState(:,c)
+ enddo
endif
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(mySizePlasticDotState,mySizeDamageDotState,mySizeThermalDotState,mySizeVacancyDotState,p,c)
+ !$OMP DO PRIVATE(mySizePlasticDotState,mySizeSourceDotState,p,c)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
mySizePlasticDotState = plasticState(p)%sizeDotState
- mySizeDamageDotState = damageState(p)%sizeDotState
- mySizeThermalDotState = thermalState(p)%sizeDotState
- mySizeVacancyDotState = vacancyState(p)%sizeDotState
- plasticState(p)%state(1:mySizePlasticDotState,c) = plasticState(p)%subState0(1:mySizePlasticDotState,c) &
- + plasticState(p)%dotState (1:mySizePlasticDotState,c) &
- * crystallite_subdt(g,i,e) * timeStepFraction(n)
- damageState( p)%state(1:mySizeDamageDotState,c) = damageState(p)%subState0(1:mySizeDamageDotState,c) &
- + damageState(p)%dotState (1:mySizeDamageDotState,c) &
- * crystallite_subdt(g,i,e) * timeStepFraction(n)
- thermalState(p)%state(1:mySizeThermalDotState,c) = thermalState(p)%subState0(1:mySizeThermalDotState,c) &
- + thermalState(p)%dotState (1:mySizeThermalDotState,c) &
- * crystallite_subdt(g,i,e) * timeStepFraction(n)
- vacancyState(p)%state(1:mySizeVacancyDotState,c) = vacancyState(p)%subState0(1:mySizeVacancyDotState,c) &
- + vacancyState(p)%dotState (1:mySizeVacancyDotState,c) &
- * crystallite_subdt(g,i,e) * timeStepFraction(n)
+ plasticState(p)%state (1:mySizePlasticDotState,c) = &
+ plasticState(p)%subState0(1:mySizePlasticDotState,c) &
+ + plasticState(p)%dotState (1:mySizePlasticDotState,c) &
+ * crystallite_subdt(g,i,e) * timeStepFraction(n)
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceState(p)%p(mySource)%state (1:mySizeSourceDotState,c) = &
+ sourceState(p)%p(mySource)%subState0(1:mySizeSourceDotState,c) &
+ + sourceState(p)%p(mySource)%dotState (1:mySizeSourceDotState,c) &
+ * crystallite_subdt(g,i,e) * timeStepFraction(n)
+ enddo
#ifndef _OPENMP
if (n == 4 &
@@ -1723,11 +1698,9 @@ subroutine crystallite_integrateStateRK4()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_microstructure(crystallite_Tstar_v(1:6,g,i,e), &
- crystallite_Fe(1:3,1:3,g,i,e), &
+ call constitutive_microstructure(crystallite_Fe(1:3,1:3,g,i,e), &
crystallite_Fp(1:3,1:3,g,i,e), &
- crystallite_Lp(1:3,1:3,g,i,e), &
- crystallite_subdt(g,i,e), g, i, e) ! update dependent state variables to be consistent with basic states
+ g, i, e) ! update dependent state variables to be consistent with basic states
enddo; enddo; enddo
!$OMP ENDDO
@@ -1756,7 +1729,7 @@ subroutine crystallite_integrateStateRK4()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), crystallite_Lp(1:3,1:3,g,i,e), &
+ call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), &
crystallite_Fe, &
crystallite_Fp, &
timeStepFraction(n)*crystallite_subdt(g,i,e), & ! fraction of original timestep
@@ -1764,15 +1737,18 @@ subroutine crystallite_integrateStateRK4()
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(p,c)
+ !$OMP DO PRIVATE(p,c,isNaN)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
!$OMP FLUSH(crystallite_todo)
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
- if (any(prec_isNaN([plasticState(p)%dotState(:,c), damageState(p)%dotState(:,c), &
- thermalState(p)%dotState(:,c), vacancyState(p)%dotState(:,c)]))) then ! NaN occured in any dotState
+ isNaN = any(prec_isNaN(plasticState(p)%dotState(:,c)))
+ do mySource = 1_pInt, phase_Nsources(p)
+ isNaN = isNaN .or. any(prec_isNaN(sourceState(p)%p(mySource)%dotState(:,c)))
+ enddo
+ if (isNaN) then ! NaN occured in any dotState
if (.not. crystallite_localPlasticity(g,i,e)) then ! if broken non-local...
!$OMP CRITICAL (checkTodo)
crystallite_todo = crystallite_todo .and. crystallite_localPlasticity ! ...all non-locals skipped
@@ -1846,17 +1822,14 @@ subroutine crystallite_integrateStateRKCK45()
use material, only: &
homogenization_Ngrains, &
plasticState, &
- damageState, &
- thermalState, &
- vacancyState, &
+ sourceState, &
+ phase_Nsources, &
mappingConstitutive, &
homogenization_maxNgrains
use constitutive, only: &
constitutive_collectDotState, &
- constitutive_maxSizeDotState, &
- constitutive_damage_maxSizeDotState, &
- constitutive_thermal_maxSizeDotState, &
- constitutive_vacancy_maxSizeDotState, &
+ constitutive_plasticity_maxSizeDotState, &
+ constitutive_source_maxSizeDotState, &
constitutive_microstructure
implicit none
@@ -1890,29 +1863,26 @@ subroutine crystallite_integrateStateRKCK45()
n, &
p, &
cc, &
+ mySource, &
mySizePlasticDotState, & ! size of dot States
- mySizeDamageDotState, &
- mySizeThermalDotState, &
- mySizeVacancyDotState
+ mySizeSourceDotState
integer(pInt), dimension(2) :: &
eIter ! bounds for element iteration
integer(pInt), dimension(2,mesh_NcpElems) :: &
iIter, & ! bounds for ip iteration
gIter ! bounds for grain iteration
- real(pReal), dimension(constitutive_maxSizeDotState,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
- stateResiduum, & ! residuum from evolution in microstructure
- relStateResiduum ! relative residuum from evolution in microstructure
- real(pReal), dimension(constitutive_damage_maxSizeDotState,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
- damageStateResiduum, & ! residuum from evolution in microstructure
- relDamageStateResiduum ! relative residuum from evolution in microstructure
- real(pReal), dimension(constitutive_thermal_maxSizeDotState,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
- thermalStateResiduum, & ! residuum from evolution in microstructure
- relThermalStateResiduum ! relative residuum from evolution in microstructure
- real(pReal), dimension(constitutive_vacancy_maxSizeDotState,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
- vacancyStateResiduum, & ! residuum from evolution in microstructure
- relVacancyStateResiduum ! relative residuum from evolution in microstructure
+ real(pReal), dimension(constitutive_plasticity_maxSizeDotState, &
+ homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
+ plasticStateResiduum, & ! residuum from evolution in microstructure
+ relPlasticStateResiduum ! relative residuum from evolution in microstructure
+ real(pReal), dimension(constitutive_source_maxSizeDotState, &
+ maxval(phase_Nsources), &
+ homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
+ sourceStateResiduum, & ! residuum from evolution in microstructure
+ relSourceStateResiduum ! relative residuum from evolution in microstructure
logical :: &
+ isNaN, &
singleRun ! flag indicating computation for single (g,i,e) triple
eIter = FEsolving_execElem(1:2)
@@ -1935,20 +1905,23 @@ subroutine crystallite_integrateStateRKCK45()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), crystallite_Lp(1:3,1:3,g,i,e), &
+ call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), &
crystallite_Fe, &
crystallite_Fp, &
crystallite_subdt(g,i,e), crystallite_subFrac, g,i,e)
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(p,cc)
+ !$OMP DO PRIVATE(p,cc,isNaN)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
!$OMP FLUSH(crystallite_todo)
if (crystallite_todo(g,i,e)) then
cc = mappingConstitutive(1,g,i,e)
p = mappingConstitutive(2,g,i,e)
- if (any(prec_isNaN([plasticState(p)%dotState(:,cc), damageState(p)%dotState(:,cc), &
- thermalState(p)%dotState(:,cc), vacancyState(p)%dotState(:,cc)]))) then ! NaN occured in any dotState
+ isNaN = any(prec_isNaN(plasticState(p)%dotState(:,cc)))
+ do mySource = 1_pInt, phase_Nsources(p)
+ isNaN = isNaN .or. any(prec_isNaN(sourceState(p)%p(mySource)%dotState(:,cc)))
+ enddo
+ if (isNaN) then ! NaN occured in any dotState
if (.not. crystallite_localPlasticity(g,i,e)) then ! if broken non-local...
!$OMP CRITICAL (checkTodo)
crystallite_todo = crystallite_todo .and. crystallite_localPlasticity ! ...all non-locals skipped
@@ -1976,9 +1949,9 @@ subroutine crystallite_integrateStateRKCK45()
p = mappingConstitutive(2,g,i,e)
cc = mappingConstitutive(1,g,i,e)
plasticState(p)%RKCK45dotState(stage,:,cc) = plasticState(p)%dotState(:,cc) ! store Runge-Kutta dotState
- damageState(p)%RKCK45dotState(stage,:,cc) = damageState(p)%dotState(:,cc) ! store Runge-Kutta dotState
- thermalState(p)%RKCK45dotState(stage,:,cc) = thermalState(p)%dotState(:,cc) ! store Runge-Kutta dotState
- vacancyState(p)%RKCK45dotState(stage,:,cc) = vacancyState(p)%dotState(:,cc) ! store Runge-Kutta dotState
+ do mySource = 1_pInt, phase_Nsources(p)
+ sourceState(p)%p(mySource)%RKCK45dotState(stage,:,cc) = sourceState(p)%p(mySource)%dotState(:,cc)
+ enddo
endif
enddo; enddo; enddo
!$OMP ENDDO
@@ -1990,44 +1963,38 @@ subroutine crystallite_integrateStateRKCK45()
cc = mappingConstitutive(1,g,i,e)
plasticState(p)%dotState(:,cc) = A(1,stage) * plasticState(p)%RKCK45dotState(1,:,cc)
- damageState( p)%dotState(:,cc) = A(1,stage) * damageState( p)%RKCK45dotState(1,:,cc)
- thermalState(p)%dotState(:,cc) = A(1,stage) * thermalState(p)%RKCK45dotState(1,:,cc)
- vacancyState(p)%dotState(:,cc) = A(1,stage) * vacancyState(p)%RKCK45dotState(1,:,cc)
+ do mySource = 1_pInt, phase_Nsources(p)
+ sourceState(p)%p(mySource)%dotState(:,cc) = A(1,stage) * sourceState(p)%p(mySource)%RKCK45dotState(1,:,cc)
+ enddo
do n = 2_pInt, stage
plasticState(p)%dotState(:,cc) = &
plasticState(p)%dotState(:,cc) + A(n,stage) * plasticState(p)%RKCK45dotState(n,:,cc)
- damageState( p)%dotState(:,cc) = &
- damageState( p)%dotState(:,cc) + A(n,stage) * damageState( p)%RKCK45dotState(n,:,cc)
- thermalState(p)%dotState(:,cc) = &
- thermalState(p)%dotState(:,cc) + A(n,stage) * thermalState(p)%RKCK45dotState(n,:,cc)
- vacancyState(p)%dotState(:,cc) = &
- vacancyState(p)%dotState(:,cc) + A(n,stage) * vacancyState(p)%RKCK45dotState(n,:,cc)
+ do mySource = 1_pInt, phase_Nsources(p)
+ sourceState(p)%p(mySource)%dotState(:,cc) = &
+ sourceState(p)%p(mySource)%dotState(:,cc) + A(n,stage) * sourceState(p)%p(mySource)%RKCK45dotState(n,:,cc)
+ enddo
enddo
endif
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(mySizePlasticDotState,mySizeDamageDotState,mySizeThermalDotState,mySizeVacancyDotState,p,cc)
+ !$OMP DO PRIVATE(mySizePlasticDotState,mySizeSourceDotState,p,cc)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
cc = mappingConstitutive(1,g,i,e)
mySizePlasticDotState = plasticState(p)%sizeDotState
- mySizeDamageDotState = damageState( p)%sizeDotState
- mySizeThermalDotState = thermalState(p)%sizeDotState
- mySizeVacancyDotState = vacancyState(p)%sizeDotState
- plasticState(p)%state(1:mySizePlasticDotState,cc) = plasticState(p)%subState0(1:mySizePlasticDotState,cc) &
- + plasticState(p)%dotState (1:mySizePlasticDotState,cc) &
- * crystallite_subdt(g,i,e)
- damageState(p)%state(1:mySizeDamageDotState,cc) = damageState(p)%subState0( 1:mySizeDamageDotState,cc) &
- + damageState(p)%dotState ( 1:mySizeDamageDotState,cc) &
- * crystallite_subdt(g,i,e)
- thermalState(p)%state(1:mySizeThermalDotState,cc) = thermalState(p)%subState0(1:mySizeThermalDotState,cc) &
- + thermalState(p)%dotState (1:mySizeThermalDotState,cc) &
- * crystallite_subdt(g,i,e)
- vacancyState(p)%state(1:mySizeVacancyDotState,cc) = vacancyState(p)%subState0(1:mySizeVacancyDotState,cc) &
- + vacancyState(p)%dotState (1:mySizeVacancyDotState,cc) &
- * crystallite_subdt(g,i,e)
+ plasticState (p)%state (1:mySizePlasticDotState, cc) = &
+ plasticState (p)%subState0(1:mySizePlasticDotState, cc) &
+ + plasticState (p)%dotState (1:mySizePlasticDotState, cc) &
+ * crystallite_subdt(g,i,e)
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceState(p)%p(mySource)%state (1:mySizeSourceDotState,cc) = &
+ sourceState(p)%p(mySource)%subState0(1:mySizeSourceDotState,cc) &
+ + sourceState(p)%p(mySource)%dotState (1:mySizeSourceDotState,cc) &
+ * crystallite_subdt(g,i,e)
+ enddo
endif
enddo; enddo; enddo
!$OMP ENDDO
@@ -2056,11 +2023,9 @@ subroutine crystallite_integrateStateRKCK45()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_microstructure(crystallite_Tstar_v(1:6,g,i,e), &
- crystallite_Fe(1:3,1:3,g,i,e), &
+ call constitutive_microstructure(crystallite_Fe(1:3,1:3,g,i,e), &
crystallite_Fp(1:3,1:3,g,i,e), &
- crystallite_Lp(1:3,1:3,g,i,e), &
- crystallite_subdt(g,i,e), g, i, e) ! update dependent state variables to be consistent with basic states
+ g, i, e) ! update dependent state variables to be consistent with basic states
enddo; enddo; enddo
!$OMP ENDDO
@@ -2091,22 +2056,25 @@ subroutine crystallite_integrateStateRKCK45()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), crystallite_Lp(1:3,1:3,g,i,e), &
+ call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), &
crystallite_Fe, &
crystallite_Fp, &
C(stage)*crystallite_subdt(g,i,e), & ! fraction of original timestep
crystallite_subFrac, g,i,e)
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(p,cc)
+ !$OMP DO PRIVATE(p,cc,isNaN)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
!$OMP FLUSH(crystallite_todo)
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
cc = mappingConstitutive(1,g,i,e)
- if (any(prec_isNaN([plasticState(p)%dotState(:,cc), damageState(p)%dotState(:,cc), &
- thermalState(p)%dotState(:,cc), vacancyState(p)%dotState(:,cc)]))) then ! NaN occured in any dotState
+ isNaN = any(prec_isNaN(plasticState(p)%dotState(:,cc)))
+ do mySource = 1_pInt, phase_Nsources(p)
+ isNaN = isNaN .or. any(prec_isNaN(sourceState(p)%p(mySource)%dotState(:,cc)))
+ enddo
+ if (isNaN) then ! NaN occured in any dotState
if (.not. crystallite_localPlasticity(g,i,e)) then ! if broken non-local...
!$OMP CRITICAL (checkTodo)
crystallite_todo = crystallite_todo .and. crystallite_localPlasticity ! ...all non-locals skipped
@@ -2126,130 +2094,109 @@ subroutine crystallite_integrateStateRKCK45()
!--------------------------------------------------------------------------------------------------
! --- STATE UPDATE WITH ERROR ESTIMATE FOR STATE ---
- relStateResiduum = 0.0_pReal
- relDamageStateResiduum = 0.0_pReal
- relThermalStateResiduum = 0.0_pReal
- relVacancyStateResiduum = 0.0_pReal
+ relPlasticStateResiduum = 0.0_pReal
+ relSourceStateResiduum = 0.0_pReal
!$OMP PARALLEL
!$OMP DO PRIVATE(p,cc)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
cc = mappingConstitutive(1,g,i,e)
- plasticState(p)%RKCK45dotState(6,:,cc) = plasticState(p)%dotState(:,cc) ! store Runge-Kutta dotState
- damageState( p)%RKCK45dotState(6,:,cc) = damageState( p)%dotState(:,cc) ! store Runge-Kutta dotState
- thermalState(p)%RKCK45dotState(6,:,cc) = thermalState(p)%dotState(:,cc) ! store Runge-Kutta dotState
- vacancyState(p)%RKCK45dotState(6,:,cc) = vacancyState(p)%dotState(:,cc) ! store Runge-Kutta dotState
+ plasticState(p)%RKCK45dotState(6,:,cc) = plasticState (p)%dotState(:,cc) ! store Runge-Kutta dotState
+ do mySource = 1_pInt, phase_Nsources(p)
+ sourceState(p)%p(mySource)%RKCK45dotState(6,:,cc) = sourceState(p)%p(mySource)%dotState(:,cc) ! store Runge-Kutta dotState
+ enddo
endif
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(mySizePlasticDotState,mySizeDamageDotState,mySizeThermalDotState,mySizeVacancyDotState,p,cc)
+ !$OMP DO PRIVATE(mySizePlasticDotState,mySizeSourceDotState,p,cc)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
cc = mappingConstitutive(1,g,i,e)
- mySizePlasticDotState = plasticState(p)%sizeDotState
- mySizeDamageDotState = damageState( p)%sizeDotState
- mySizeThermalDotState = thermalState(p)%sizeDotState
- mySizeVacancyDotState = vacancyState(p)%sizeDotState
! --- absolute residuum in state ---
- stateResiduum(1:mySizePlasticDotState,g,i,e) = &
- matmul(transpose(plasticState(p)%RKCK45dotState(1:6,1:mySizePlasticDotState,cc)),DB) &
- * crystallite_subdt(g,i,e)
- damageStateResiduum(1:mySizeDamageDotState,g,i,e) = &
- matmul(transpose(damageState(p)%RKCK45dotState(1:6,1:mySizeDamageDotState,cc)),DB) &
- * crystallite_subdt(g,i,e)
- thermalStateResiduum(1:mySizeThermalDotState,g,i,e) = &
- matmul(transpose(thermalState(p)%RKCK45dotState(1:6,1:mySizeThermalDotState,cc)),DB) &
- * crystallite_subdt(g,i,e)
- vacancyStateResiduum(1:mySizeVacancyDotState,g,i,e) = &
- matmul(transpose(vacancyState(p)%RKCK45dotState(1:6,1:mySizevacancyDotState,cc)),DB) &
- * crystallite_subdt(g,i,e)
+ mySizePlasticDotState = plasticState(p)%sizeDotState
+ plasticStateResiduum(1:mySizePlasticDotState,g,i,e) = &
+ matmul(transpose(plasticState(p)%RKCK45dotState(1:6,1:mySizePlasticDotState,cc)),DB) &
+ * crystallite_subdt(g,i,e)
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceStateResiduum(1:mySizeSourceDotState,mySource,g,i,e) = &
+ matmul(transpose(sourceState(p)%p(mySource)%RKCK45dotState(1:6,1:mySizeSourceDotState,cc)),DB) &
+ * crystallite_subdt(g,i,e)
+ enddo
! --- dot state ---
- plasticState(p)%dotState (:,cc) = &
- matmul(transpose(plasticState(p)%RKCK45dotState(1:6,1:mySizePlasticDotState,cc)),B)
- damageState(p)%dotState (:,cc) = &
- matmul(transpose(damageState(p)%RKCK45dotState(1:6,1:mySizeDamageDotState,cc)),B)
- thermalState(p)%dotState (:,cc) = &
- matmul(transpose(thermalState(p)%RKCK45dotState(1:6,1:mySizeThermalDotState,cc)),B)
- vacancyState(p)%dotState (:,cc) = &
- matmul(transpose(vacancyState(p)%RKCK45dotState(1:6,1:mySizevacancyDotState,cc)),B)
+ plasticState(p)%dotState(:,cc) = &
+ matmul(transpose(plasticState(p)%RKCK45dotState(1:6,1:mySizePlasticDotState,cc)), B)
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceState(p)%p(mySource)%dotState(:,cc) = &
+ matmul(transpose(sourceState(p)%p(mySource)%RKCK45dotState(1:6,1:mySizeSourceDotState,cc)),B)
+ enddo
endif
enddo; enddo; enddo
!$OMP ENDDO
! --- state and update ---
- !$OMP DO PRIVATE(mySizePlasticDotState,mySizeDamageDotState,mySizeThermalDotState,mySizeVacancyDotState,p,cc)
+ !$OMP DO PRIVATE(mySizePlasticDotState,mySizeSourceDotState,p,cc)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
cc = mappingConstitutive(1,g,i,e)
mySizePlasticDotState = plasticState(p)%sizeDotState
- mySizeDamageDotState = damageState( p)%sizeDotState
- mySizeThermalDotState = thermalState(p)%sizeDotState
- mySizeVacancyDotState = vacancyState(p)%sizeDotState
- plasticState(p)%state(1:mySizePlasticDotState,cc) = plasticState(p)%subState0(1:mySizePlasticDotState,cc)&
- + plasticState(p)%dotState (1:mySizePlasticDotState,cc)&
- * crystallite_subdt(g,i,e)
- damageState(p)%state (1:mySizeDamageDotState,cc) = damageState(p)%subState0(1:mySizeDamageDotState,cc)&
- + damageState(p)%dotState (1:mySizeDamageDotState,cc)&
- * crystallite_subdt(g,i,e)
- thermalState(p)%state(1:mySizeThermalDotState,cc) = thermalState(p)%subState0(1:mySizeThermalDotState,cc)&
- + thermalState(p)%dotState (1:mySizeThermalDotState,cc)&
- * crystallite_subdt(g,i,e)
- vacancyState(p)%state(1:mySizeVacancyDotState,cc) = vacancyState(p)%subState0(1:mySizeVacancyDotState,cc)&
- + vacancyState(p)%dotState (1:mySizeVacancyDotState,cc)&
- * crystallite_subdt(g,i,e)
+ plasticState(p)%state (1:mySizePlasticDotState,cc) = &
+ plasticState(p)%subState0(1:mySizePlasticDotState,cc) &
+ + plasticState(p)%dotState (1:mySizePlasticDotState,cc) &
+ * crystallite_subdt(g,i,e)
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceState(p)%p(mySource)%state (1:mySizeSourceDotState,cc) = &
+ sourceState(p)%p(mySource)%subState0(1:mySizeSourceDotState,cc) &
+ + sourceState(p)%p(mySource)%dotState (1:mySizeSourceDotState,cc)&
+ * crystallite_subdt(g,i,e)
+ enddo
endif
enddo; enddo; enddo
!$OMP ENDDO
! --- relative residui and state convergence ---
- !$OMP DO PRIVATE(mySizePlasticDotState,mySizeDamageDotState,mySizeThermalDotState,mySizeVacancyDotState,p,cc,s)
+ !$OMP DO PRIVATE(mySizePlasticDotState,mySizeSourceDotState,p,cc,s)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) then
- p = mappingConstitutive(2,g,i,e)
+ p = mappingConstitutive(2,g,i,e)
cc = mappingConstitutive(1,g,i,e)
mySizePlasticDotState = plasticState(p)%sizeDotState
- mySizeDamageDotState = damageState( p)%sizeDotState
- mySizeThermalDotState = thermalState(p)%sizeDotState
- mySizeVacancyDotState = vacancyState(p)%sizeDotState
- forall (s = 1_pInt:mySizePlasticDotState, abs(plasticState(p)%state(s,cc)) > 0.0_pReal) &
- relStateResiduum(s,g,i,e) = stateResiduum(s,g,i,e) / plasticState(p)%state(s,cc)
- forall (s = 1_pInt:mySizeDamageDotState, abs(damageState( p)%state(s,cc)) > 0.0_pReal) &
- relDamageStateResiduum(s,g,i,e) = damageStateResiduum(s,g,i,e) / damageState(p)%state(s,cc)
- forall (s = 1_pInt:mySizeThermalDotState, abs(thermalState(p)%state(s,cc)) > 0.0_pReal) &
- relThermalStateResiduum(s,g,i,e) = thermalStateResiduum(s,g,i,e) / thermalState(p)%state(s,cc)
- forall (s = 1_pInt:mySizeVacancyDotState, abs(vacancyState(p)%state(s,cc)) > 0.0_pReal) &
- relVacancyStateResiduum(s,g,i,e) = vacancyStateResiduum(s,g,i,e) / vacancyState(p)%state(s,cc)
- !$OMP FLUSH(relStateResiduum)
- !$OMP FLUSH(relDamageStateResiduum)
- !$OMP FLUSH(relThermalStateResiduum)
- !$OMP FLUSH(relVacancyStateResiduum)
+ forall (s = 1_pInt:mySizePlasticDotState, abs(plasticState(p)%state(s,cc)) > 0.0_pReal) &
+ relPlasticStateResiduum(s,g,i,e) = &
+ plasticStateResiduum(s,g,i,e) / plasticState(p)%state(s,cc)
+
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ forall (s = 1_pInt:mySizeSourceDotState,abs(sourceState(p)%p(mySource)%state(s,cc)) > 0.0_pReal) &
+ relSourceStateResiduum(s,mySource,g,i,e) = &
+ sourceStateResiduum(s,mySource,g,i,e) / sourceState(p)%p(mySource)%state(s,cc)
+ enddo
+ !$OMP FLUSH(relPlasticStateResiduum)
+ !$OMP FLUSH(relSourceStateResiduum)
! @Martin: do we need flushing? why..?
- crystallite_todo(g,i,e) = &
- ( all(abs(relStateResiduum(1:mySizePlasticDotState,g,i,e)) < &
- rTol_crystalliteState .or. &
- abs(stateResiduum(1:mySizePlasticDotState,g,i,e)) < &
- plasticState(p)%aTolState(1:mySizePlasticDotState)) &
- .and. all(abs(relDamageStateResiduum(1:mySizeDamageDotState,g,i,e)) < &
- rTol_crystalliteState .or. &
- abs(damageStateResiduum(1:mySizeDamageDotState,g,i,e)) < &
- damageState(p)%aTolState(1:mySizeDamageDotState)) &
- .and. all(abs(relThermalStateResiduum(1:mySizeThermalDotState,g,i,e)) < &
- rTol_crystalliteState .or. &
- abs(thermalStateResiduum(1:mySizeThermalDotState,g,i,e)) < &
- thermalState(p)%aTolState(1:mySizeThermalDotState)) &
- .and. all(abs(relVacancyStateResiduum(1:mySizeVacancyDotState,g,i,e)) < &
- rTol_crystalliteState .or. &
- abs(vacancyStateResiduum(1:mySizeVacancyDotState,g,i,e)) < &
- vacancyState(p)%aTolState(1:mySizeVacancyDotState)))
+ crystallite_todo(g,i,e) = all(abs(relPlasticStateResiduum(1:mySizePlasticDotState,g,i,e)) < &
+ rTol_crystalliteState .or. &
+ abs(plasticStateResiduum(1:mySizePlasticDotState,g,i,e)) < &
+ plasticState(p)%aTolState(1:mySizePlasticDotState))
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. &
+ all(abs(relSourceStateResiduum(1:mySizeSourceDotState,mySource,g,i,e)) < &
+ rTol_crystalliteState .or. &
+ abs(sourceStateResiduum(1:mySizeSourceDotState,mySource,g,i,e)) < &
+ sourceState(p)%p(mySource)%aTolState(1:mySizeSourceDotState))
+ enddo
#ifndef _OPENMP
if (iand(debug_level(debug_crystallite), debug_levelExtensive) /= 0_pInt&
@@ -2257,9 +2204,9 @@ subroutine crystallite_integrateStateRKCK45()
.or. .not. iand(debug_level(debug_crystallite), debug_levelSelective) /= 0_pInt)) then
write(6,'(a,i8,1x,i3,1x,i3,/)') '<< CRYST >> updateState at el ip g ',e,i,g
write(6,'(a,/,(12x,12(f12.1,1x)),/)') '<< CRYST >> absolute residuum tolerance', &
- stateResiduum(1:mySizePlasticDotState,g,i,e) / plasticState(p)%aTolState(1:mySizePlasticDotState)
+ plasticStateResiduum(1:mySizePlasticDotState,g,i,e) / plasticState(p)%aTolState(1:mySizePlasticDotState)
write(6,'(a,/,(12x,12(f12.1,1x)),/)') '<< CRYST >> relative residuum tolerance', &
- relStateResiduum(1:mySizePlasticDotState,g,i,e) / rTol_crystalliteState
+ relPlasticStateResiduum(1:mySizePlasticDotState,g,i,e) / rTol_crystalliteState
write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> dotState', &
plasticState(p)%dotState(1:mySizePlasticDotState,cc)
write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> new state', &
@@ -2294,11 +2241,9 @@ subroutine crystallite_integrateStateRKCK45()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_microstructure(crystallite_Tstar_v(1:6,g,i,e), &
- crystallite_Fe(1:3,1:3,g,i,e), &
+ call constitutive_microstructure(crystallite_Fe(1:3,1:3,g,i,e), &
crystallite_Fp(1:3,1:3,g,i,e), &
- crystallite_Lp(1:3,1:3,g,i,e), &
- crystallite_subdt(g,i,e), g, i, e) ! update dependent state variables to be consistent with basic states
+ g, i, e) ! update dependent state variables to be consistent with basic states
enddo; enddo; enddo
!$OMP ENDDO
@@ -2379,18 +2324,15 @@ subroutine crystallite_integrateStateAdaptiveEuler()
use material, only: &
homogenization_Ngrains, &
plasticState, &
- damageState, &
- thermalState, &
- vacancyState, &
+ sourceState, &
mappingConstitutive, &
+ phase_Nsources, &
homogenization_maxNgrains
use constitutive, only: &
constitutive_collectDotState, &
constitutive_microstructure, &
- constitutive_maxSizeDotState, &
- constitutive_damage_maxSizeDotState, &
- constitutive_thermal_maxSizeDotState, &
- constitutive_vacancy_maxSizeDotState
+ constitutive_plasticity_maxSizeDotState, &
+ constitutive_source_maxSizeDotState
implicit none
integer(pInt) :: &
@@ -2400,29 +2342,27 @@ subroutine crystallite_integrateStateAdaptiveEuler()
s, & ! state index
p, &
c, &
+ mySource, &
mySizePlasticDotState, & ! size of dot states
- mySizeDamageDotState, &
- mySizeThermalDotState, &
- mySizeVacancyDotState
+ mySizeSourceDotState
integer(pInt), dimension(2) :: &
eIter ! bounds for element iteration
integer(pInt), dimension(2,mesh_NcpElems) :: &
iIter, & ! bounds for ip iteration
gIter ! bounds for grain iteration
- real(pReal), dimension(constitutive_maxSizeDotState,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
- stateResiduum, & ! residuum from evolution in micrstructure
- relStateResiduum ! relative residuum from evolution in microstructure
- real(pReal), dimension(constitutive_damage_maxSizeDotState,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
- damageStateResiduum, & ! residuum from evolution in micrstructure
- relDamageStateResiduum ! relative residuum from evolution in microstructure
- real(pReal), dimension(constitutive_thermal_maxSizeDotState,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
- thermalStateResiduum, & ! residuum from evolution in micrstructure
- relThermalStateResiduum ! relative residuum from evolution in microstructure
- real(pReal), dimension(constitutive_vacancy_maxSizeDotState,homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
- vacancyStateResiduum, & ! residuum from evolution in micrstructure
- relVacancyStateResiduum ! relative residuum from evolution in microstructure
+ real(pReal), dimension(constitutive_plasticity_maxSizeDotState, &
+ homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
+ plasticStateResiduum, & ! residuum from evolution in micrstructure
+ relPlasticStateResiduum ! relative residuum from evolution in microstructure
+ real(pReal), dimension(constitutive_source_maxSizeDotState,&
+ maxval(phase_Nsources), &
+ homogenization_maxNgrains,mesh_maxNips,mesh_NcpElems) :: &
+ sourceStateResiduum, & ! residuum from evolution in micrstructure
+ relSourceStateResiduum ! relative residuum from evolution in microstructure
logical :: &
+ converged, &
+ isNaN, &
singleRun ! flag indicating computation for single (g,i,e) triple
@@ -2436,15 +2376,10 @@ subroutine crystallite_integrateStateAdaptiveEuler()
singleRun = (eIter(1) == eIter(2) .and. iIter(1,eIter(1)) == iIter(2,eIter(2)))
- stateResiduum = 0.0_pReal
- relStateResiduum = 0.0_pReal
- damageStateResiduum = 0.0_pReal
- relDamageStateResiduum = 0.0_pReal
- thermalStateResiduum = 0.0_pReal
- relThermalStateResiduum = 0.0_pReal
- vacancyStateResiduum = 0.0_pReal
- relVacancyStateResiduum = 0.0_pReal
-
+ plasticStateResiduum = 0.0_pReal
+ relPlasticStateResiduum = 0.0_pReal
+ sourceStateResiduum = 0.0_pReal
+ relSourceStateResiduum = 0.0_pReal
integrationMode: if (numerics_integrationMode == 1_pInt) then
@@ -2454,20 +2389,23 @@ subroutine crystallite_integrateStateAdaptiveEuler()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), crystallite_Lp(1:3,1:3,g,i,e), &
+ call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), &
crystallite_Fe, &
crystallite_Fp, &
crystallite_subdt(g,i,e), crystallite_subFrac, g,i,e)
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(p,c)
+ !$OMP DO PRIVATE(p,c,isNaN)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
!$OMP FLUSH(crystallite_todo)
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
- if (any(prec_isNaN([plasticState(p)%dotState(:,c), damageState(p)%dotState(:,c), &
- thermalState(p)%dotState(:,c), vacancyState(p)%dotState(:,c)]))) then ! NaN occured in any dotState
+ isNaN = any(prec_isNaN(plasticState(p)%dotState(:,c)))
+ do mySource = 1_pInt, phase_Nsources(p)
+ isNaN = isNaN .or. any(prec_isNaN(sourceState(p)%p(mySource)%dotState(:,c)))
+ enddo
+ if (isNaN) then ! NaN occured in any dotState
if (.not. crystallite_localPlasticity(g,i,e)) then ! if broken non-local...
!$OMP CRITICAL (checkTodo)
crystallite_todo = crystallite_todo .and. crystallite_localPlasticity ! ...all non-locals skipped
@@ -2483,39 +2421,31 @@ subroutine crystallite_integrateStateAdaptiveEuler()
! --- STATE UPDATE (EULER INTEGRATION) ---
- !$OMP DO PRIVATE(mySizePlasticDotState,mySizeDamageDotState,mySizeThermalDotState,mySizeVacancyDotState,p,c)
+ !$OMP DO PRIVATE(mySizePlasticDotState,mySizeSourceDotState,p,c)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
mySizePlasticDotState = plasticState(p)%sizeDotState
- mySizeDamageDotState = damageState( p)%sizeDotState
- mySizeThermalDotState = thermalState(p)%sizeDotState
- mySizeVacancyDotState = vacancyState(p)%sizeDotState
- stateResiduum(1:mySizePlasticDotState,g,i,e) = - 0.5_pReal &
- * plasticState(p)%dotstate(1:mySizePlasticDotState,c) &
- * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
- damageStateResiduum(1:mySizeDamageDotState,g,i,e) = - 0.5_pReal &
- * damageState(p)%dotstate(1:mySizeDamageDotState,c) &
- * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
- thermalStateResiduum(1:mySizeThermalDotState,g,i,e) = - 0.5_pReal &
- * thermalState(p)%dotstate(1:mySizeThermalDotState,c) &
- * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
- vacancyStateResiduum(1:mySizeVacancyDotState,g,i,e) = - 0.5_pReal &
- * vacancyState(p)%dotstate(1:mySizeVacancyDotState,c) &
- * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
- plasticState(p)%state(1:mySizePlasticDotState,c) = plasticState(p)%state(1:mySizePlasticDotState,c) &
- + plasticState(p)%dotstate(1:mySizePlasticDotState,c) &
- * crystallite_subdt(g,i,e)
- damageState(p)%state(1:mySizeDamageDotState,c) = damageState(p)%state(1:mySizeDamageDotState,c) &
- + damageState(p)%dotstate(1:mySizeDamageDotState,c) &
- * crystallite_subdt(g,i,e)
- thermalState(p)%state(1:mySizeThermalDotState,c) = thermalState(p)%state(1:mySizeThermalDotState,c) &
- + thermalState(p)%dotstate(1:mySizeThermalDotState,c) &
- * crystallite_subdt(g,i,e)
- vacancyState(p)%state(1:mySizeVacancyDotState,c) = vacancyState(p)%state(1:mySizeVacancyDotState,c) &
- + vacancyState(p)%dotstate(1:mySizeVacancyDotState,c) &
- * crystallite_subdt(g,i,e)
+ plasticStateResiduum(1:mySizePlasticDotState,g,i,e) = &
+ - 0.5_pReal &
+ * plasticState(p)%dotstate(1:mySizePlasticDotState,c) &
+ * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
+ plasticState(p)%state (1:mySizePlasticDotState,c) = &
+ plasticState(p)%state (1:mySizePlasticDotState,c) &
+ + plasticState(p)%dotstate(1:mySizePlasticDotState,c) &
+ * crystallite_subdt(g,i,e)
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceStateResiduum(1:mySizeSourceDotState,mySource,g,i,e) = &
+ - 0.5_pReal &
+ * sourceState(p)%p(mySource)%dotstate(1:mySizeSourceDotState,c) &
+ * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
+ sourceState(p)%p(mySource)%state (1:mySizeSourceDotState,c) = &
+ sourceState(p)%p(mySource)%state (1:mySizeSourceDotState,c) &
+ + sourceState(p)%p(mySource)%dotstate(1:mySizeSourceDotState,c) &
+ * crystallite_subdt(g,i,e)
+ enddo
endif
enddo; enddo; enddo
!$OMP ENDDO
@@ -2544,11 +2474,9 @@ subroutine crystallite_integrateStateAdaptiveEuler()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_microstructure(crystallite_Tstar_v(1:6,g,i,e), &
- crystallite_Fe(1:3,1:3,g,i,e), &
+ call constitutive_microstructure(crystallite_Fe(1:3,1:3,g,i,e), &
crystallite_Fp(1:3,1:3,g,i,e), &
- crystallite_Lp(1:3,1:3,g,i,e), &
- crystallite_subdt(g,i,e), g, i, e) ! update dependent state variables to be consistent with basic states
+ g, i, e) ! update dependent state variables to be consistent with basic states
enddo; enddo; enddo
!$OMP ENDDO
!$OMP END PARALLEL
@@ -2581,20 +2509,23 @@ subroutine crystallite_integrateStateAdaptiveEuler()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), crystallite_Lp(1:3,1:3,g,i,e), &
+ call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), &
crystallite_Fe, &
crystallite_Fp, &
crystallite_subdt(g,i,e), crystallite_subFrac, g,i,e)
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(p,c)
+ !$OMP DO PRIVATE(p,c,isNaN)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
!$OMP FLUSH(crystallite_todo)
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
- if (any(prec_isNaN([plasticState(p)%dotState(:,c), damageState(p)%dotState(:,c), &
- thermalState(p)%dotState(:,c), vacancyState(p)%dotState(:,c)]))) then ! NaN occured in any dotState
+ isNaN = any(prec_isNaN(plasticState(p)%dotState(:,c)))
+ do mySource = 1_pInt, phase_Nsources(p)
+ isNaN = isNaN .or. any(prec_isNaN(sourceState(p)%p(mySource)%dotState(:,c)))
+ enddo
+ if (isNaN) then ! NaN occured in any dotState
if (.not. crystallite_localPlasticity(g,i,e)) then ! if broken non-local...
!$OMP CRITICAL (checkTodo)
crystallite_todo = crystallite_todo .and. crystallite_localPlasticity ! ...all non-locals skipped
@@ -2611,54 +2542,43 @@ subroutine crystallite_integrateStateAdaptiveEuler()
! --- ERROR ESTIMATE FOR STATE (HEUN METHOD) ---
!$OMP SINGLE
- relStateResiduum = 0.0_pReal
- relDamageStateResiduum = 0.0_pReal
- relThermalStateResiduum = 0.0_pReal
- relVacancyStateResiduum = 0.0_pReal
+ relPlasticStateResiduum = 0.0_pReal
+ relSourceStateResiduum = 0.0_pReal
!$OMP END SINGLE
- !$OMP DO PRIVATE(mySizePlasticDotState,mySizeDamageDotState,mySizeThermalDotState,mySizeVacancyDotState,p,c,s)
+ !$OMP DO PRIVATE(mySizePlasticDotState,mySizeSourceDotState,converged,p,c,s)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
- mySizePlasticDotState = plasticState(p)%sizeDotState
- mySizeDamageDotState = damageState(p)%sizeDotState
- mySizeThermalDotState = thermalState(p)%sizeDotState
- mySizeVacancyDotState = vacancyState(p)%sizeDotState
! --- contribution of heun step to absolute residui ---
-
- stateResiduum(1:mySizePlasticDotState,g,i,e) = stateResiduum(1:mySizePlasticDotState,g,i,e) &
- + 0.5_pReal * plasticState(p)%dotState(:,c) &
- * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
- damageStateResiduum(1:mySizeDamageDotState,g,i,e) = damageStateResiduum(1:mySizeDamageDotState,g,i,e) &
- + 0.5_pReal * damageState(p)%dotState(:,c) &
- * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
- thermalStateResiduum(1:mySizeThermalDotState,g,i,e) = thermalStateResiduum(1:mySizeThermalDotState,g,i,e) &
- + 0.5_pReal * thermalState(p)%dotState(:,c) &
- * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
- vacancyStateResiduum(1:mySizeVacancyDotState,g,i,e) = vacancyStateResiduum(1:mySizeVacancyDotState,g,i,e) &
- + 0.5_pReal * vacancyState(p)%dotState(:,c) &
- * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
-
- !$OMP FLUSH(stateResiduum)
- !$OMP FLUSH(damageStateResiduum)
- !$OMP FLUSH(thermalStateResiduum)
- !$OMP FLUSH(vacancyStateResiduum)
+ mySizePlasticDotState = plasticState(p)%sizeDotState
+ plasticStateResiduum(1:mySizePlasticDotState,g,i,e) = &
+ plasticStateResiduum(1:mySizePlasticDotState,g,i,e) &
+ + 0.5_pReal * plasticState(p)%dotState(:,c) &
+ * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceStateResiduum(1:mySizeSourceDotState,mySource,g,i,e) = &
+ sourceStateResiduum(1:mySizeSourceDotState,mySource,g,i,e) &
+ + 0.5_pReal * sourceState(p)%p(mySource)%dotState(:,c) &
+ * crystallite_subdt(g,i,e) ! contribution to absolute residuum in state
+ enddo
+ !$OMP FLUSH(plasticStateResiduum)
+ !$OMP FLUSH(sourceStateResiduum)
! --- relative residui ---
forall (s = 1_pInt:mySizePlasticDotState, abs(plasticState(p)%dotState(s,c)) > 0.0_pReal) &
- relStateResiduum(s,g,i,e) = stateResiduum(s,g,i,e) / plasticState(p)%dotState(s,c)
- forall (s = 1_pInt:mySizeDamageDotState, abs(damageState(p)%dotState(s,c)) > 0.0_pReal) &
- relDamageStateResiduum(s,g,i,e) = damageStateResiduum(s,g,i,e) / damageState(p)%dotState(s,c)
- forall (s = 1_pInt:mySizeThermalDotState, abs(thermalState(p)%dotState(s,c)) > 0.0_pReal) &
- relThermalStateResiduum(s,g,i,e) = thermalStateResiduum(s,g,i,e) / thermalState(p)%dotState(s,c)
- forall (s = 1_pInt:mySizeVacancyDotState, abs(vacancyState(p)%dotState(s,c)) > 0.0_pReal) &
- relVacancyStateResiduum(s,g,i,e) = vacancyStateResiduum(s,g,i,e) / vacancyState(p)%dotState(s,c)
- !$OMP FLUSH(relStateResiduum)
- !$OMP FLUSH(relDamageStateResiduum)
- !$OMP FLUSH(relthermalStateResiduum)
- !$OMP FLUSH(relVacancyStateResiduum)
+ relPlasticStateResiduum(s,g,i,e) = &
+ plasticStateResiduum(s,g,i,e) / plasticState(p)%dotState(s,c)
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ forall (s = 1_pInt:mySizeSourceDotState,abs(sourceState(p)%p(mySource)%dotState(s,c)) > 0.0_pReal) &
+ relSourceStateResiduum(s,mySource,g,i,e) = &
+ sourceStateResiduum(s,mySource,g,i,e) / sourceState(p)%p(mySource)%dotState(s,c)
+ enddo
+ !$OMP FLUSH(relPlasticStateResiduum)
+ !$OMP FLUSH(relSourceStateResiduum)
#ifndef _OPENMP
@@ -2667,32 +2587,29 @@ subroutine crystallite_integrateStateAdaptiveEuler()
.or. .not. iand(debug_level(debug_crystallite), debug_levelSelective) /= 0_pInt)) then
write(6,'(a,i8,1x,i2,1x,i3,/)') '<< CRYST >> updateState at el ip g ',e,i,g
write(6,'(a,/,(12x,12(f12.1,1x)),/)') '<< CRYST >> absolute residuum tolerance', &
- stateResiduum(1:mySizePlasticDotState,g,i,e) / plasticState(p)%aTolState(1:mySizePlasticDotState)
+ plasticStateResiduum(1:mySizePlasticDotState,g,i,e) / plasticState(p)%aTolState(1:mySizePlasticDotState)
write(6,'(a,/,(12x,12(f12.1,1x)),/)') '<< CRYST >> relative residuum tolerance', &
- relStateResiduum(1:mySizePlasticDotState,g,i,e) / rTol_crystalliteState
+ relPlasticStateResiduum(1:mySizePlasticDotState,g,i,e) / rTol_crystalliteState
write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> dotState', plasticState(p)%dotState(1:mySizePlasticDotState,c) &
- - 2.0_pReal * stateResiduum(1:mySizePlasticDotState,g,i,e) / crystallite_subdt(g,i,e) ! calculate former dotstate from higher order solution and state residuum
+ - 2.0_pReal * plasticStateResiduum(1:mySizePlasticDotState,g,i,e) / crystallite_subdt(g,i,e) ! calculate former dotstate from higher order solution and state residuum
write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> new state', plasticState(p)%state(1:mySizePlasticDotState,c)
endif
#endif
! --- converged ? ---
- if ( all(abs(relStateResiduum(1:mySizePlasticDotState,g,i,e)) < &
+ converged = all(abs(relPlasticStateResiduum(1:mySizePlasticDotState,g,i,e)) < &
+ rTol_crystalliteState .or. &
+ abs(plasticStateResiduum(1:mySizePlasticDotState,g,i,e)) < &
+ plasticState(p)%aTolState(1:mySizePlasticDotState))
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ converged = converged .and. &
+ all(abs(relSourceStateResiduum(1:mySizeSourceDotState,mySource,g,i,e)) < &
rTol_crystalliteState .or. &
- abs(stateResiduum(1:mySizePlasticDotState,g,i,e)) < &
- plasticState(p)%aTolState(1:mySizePlasticDotState)) &
- .and. all(abs(relDamageStateResiduum(1:mySizeDamageDotState,g,i,e)) < &
- rTol_crystalliteState .or. &
- abs(damageStateResiduum(1:mySizeDamageDotState,g,i,e)) < &
- damageState(p)%aTolState(1:mySizeDamageDotState)) &
- .and. all(abs(relThermalStateResiduum(1:mySizeThermalDotState,g,i,e)) < &
- rTol_crystalliteState .or. &
- abs(thermalStateResiduum(1:mySizeThermalDotState,g,i,e)) < &
- thermalState(p)%aTolState(1:mySizeThermalDotState)) &
- .and. all(abs(relVacancyStateResiduum(1:mySizeVacancyDotState,g,i,e)) < &
- rTol_crystalliteState .or. &
- abs(vacancyStateResiduum(1:mySizeVacancyDotState,g,i,e)) < &
- vacancyState(p)%aTolState(1:mySizeVacancyDotState))) then
+ abs(sourceStateResiduum(1:mySizeSourceDotState,mySource,g,i,e)) < &
+ sourceState(p)%p(mySource)%aTolState(1:mySizeSourceDotState))
+ enddo
+ if (converged) then
crystallite_converged(g,i,e) = .true. ! ... converged per definitionem
if (iand(debug_level(debug_crystallite), debug_levelBasic) /= 0_pInt) then
!$OMP CRITICAL (distributionState)
@@ -2764,10 +2681,9 @@ subroutine crystallite_integrateStateEuler()
mesh_NcpElems
use material, only: &
plasticState, &
- damageState, &
- thermalState, &
- vacancyState, &
+ sourceState, &
mappingConstitutive, &
+ phase_Nsources, &
homogenization_Ngrains
use constitutive, only: &
constitutive_collectDotState, &
@@ -2779,18 +2695,18 @@ subroutine crystallite_integrateStateEuler()
e, & ! element index in element loop
i, & ! integration point index in ip loop
g, & ! grain index in grain loop
- p, & ! phase loop
+ p, & ! phase loop
c, &
+ mySource, &
mySizePlasticDotState, &
- mySizeDamageDotState, &
- mySizeThermalDotState, &
- mySizeVacancyDotState
+ mySizeSourceDotState
integer(pInt), dimension(2) :: &
eIter ! bounds for element iteration
integer(pInt), dimension(2,mesh_NcpElems) :: &
iIter, & ! bounds for ip iteration
gIter ! bounds for grain iteration
logical :: &
+ isNaN, &
singleRun ! flag indicating computation for single (g,i,e) triple
@@ -2810,20 +2726,23 @@ eIter = FEsolving_execElem(1:2)
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e) .and. .not. crystallite_converged(g,i,e)) &
- call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), crystallite_Lp(1:3,1:3,g,i,e), &
+ call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), &
crystallite_Fe, &
crystallite_Fp, &
crystallite_subdt(g,i,e), crystallite_subFrac, g,i,e)
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(p,c)
+ !$OMP DO PRIVATE(p,c,isNaN)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
!$OMP FLUSH(crystallite_todo)
if (crystallite_todo(g,i,e) .and. .not. crystallite_converged(g,i,e)) then
c = mappingConstitutive(1,g,i,e)
p = mappingConstitutive(2,g,i,e)
- if (any(prec_isNaN([plasticState(p)%dotState(:,c), damageState(p)%dotState(:,c), &
- thermalState(p)%dotState(:,c), vacancyState(p)%dotState(:,c)]))) then ! NaN occured in any dotState
+ isNaN = any(prec_isNaN(plasticState(p)%dotState(:,c)))
+ do mySource = 1_pInt, phase_Nsources(p)
+ isNaN = isNaN .or. any(prec_isNaN(sourceState(p)%p(mySource)%dotState(:,c)))
+ enddo
+ if (isNaN) then ! NaN occured in any dotState
if (.not. crystallite_localPlasticity(g,i,e) .and. .not. numerics_timeSyncing) then ! if broken non-local...
!$OMP CRITICAL (checkTodo)
crystallite_todo = crystallite_todo .and. crystallite_localPlasticity ! ...all non-locals skipped
@@ -2839,27 +2758,23 @@ eIter = FEsolving_execElem(1:2)
! --- UPDATE STATE ---
- !$OMP DO PRIVATE(mySizePlasticDotState,mySizeDamageDotState,mySizeThermalDotState,mySizeVacancyDotState,p,c)
+ !$OMP DO PRIVATE(mySizePlasticDotState,mySizeSourceDotState,p,c)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e) .and. .not. crystallite_converged(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
mySizePlasticDotState = plasticState(p)%sizeDotState
- mySizeDamageDotState = damageState( p)%sizeDotState
- mySizeThermalDotState = thermalState(p)%sizeDotState
- mySizeVacancyDotState = vacancyState(p)%sizeDotState
- plasticState(p)%state(1:mySizePlasticDotState,c) = plasticState(p)%state( 1:mySizePlasticDotState,c) &
- + plasticState(p)%dotState(1:mySizePlasticDotState,c) &
- * crystallite_subdt(g,i,e)
- damageState( p)%state(1:mySizeDamageDotState,c) = damageState( p)%state( 1:mySizeDamageDotState,c) &
- + damageState( p)%dotState(1:mySizeDamageDotState,c) &
- * crystallite_subdt(g,i,e)
- thermalState(p)%state(1:mySizeThermalDotState,c) = thermalState(p)%state( 1:mySizeThermalDotState,c) &
- + thermalState(p)%dotState(1:mySizeThermalDotState,c) &
- * crystallite_subdt(g,i,e)
- vacancyState(p)%state(1:mySizeVacancyDotState,c) = vacancyState(p)%state( 1:mySizeVacancyDotState,c) &
- + vacancyState(p)%dotState(1:mySizeVacancyDotState,c) &
- * crystallite_subdt(g,i,e)
+ plasticState(p)%state( 1:mySizePlasticDotState,c) = &
+ plasticState(p)%state( 1:mySizePlasticDotState,c) &
+ + plasticState(p)%dotState(1:mySizePlasticDotState,c) &
+ * crystallite_subdt(g,i,e)
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceState(p)%p(mySource)%state( 1:mySizeSourceDotState,c) = &
+ sourceState(p)%p(mySource)%state( 1:mySizeSourceDotState,c) &
+ + sourceState(p)%p(mySource)%dotState(1:mySizeSourceDotState,c) &
+ * crystallite_subdt(g,i,e)
+ enddo
#ifndef _OPENMP
if (iand(debug_level(debug_crystallite), debug_levelExtensive) /= 0_pInt &
@@ -2868,8 +2783,8 @@ eIter = FEsolving_execElem(1:2)
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
write(6,'(a,i8,1x,i2,1x,i3,/)') '<< CRYST >> update state at el ip g ',e,i,g
- write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> dotState', plasticState(p)%dotState (1:mySizePlasticDotState,c)
- write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> new state', plasticState(p)%state (1:mySizePlasticDotState,c)
+ write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> dotState', plasticState(p)%dotState(1:mySizePlasticDotState,c)
+ write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> new state', plasticState(p)%state (1:mySizePlasticDotState,c)
endif
#endif
endif
@@ -2901,11 +2816,9 @@ eIter = FEsolving_execElem(1:2)
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e) .and. .not. crystallite_converged(g,i,e)) &
- call constitutive_microstructure(crystallite_Tstar_v(1:6,g,i,e), &
- crystallite_Fe(1:3,1:3,g,i,e), &
+ call constitutive_microstructure(crystallite_Fe(1:3,1:3,g,i,e), &
crystallite_Fp(1:3,1:3,g,i,e), &
- crystallite_Lp(1:3,1:3,g,i,e), &
- crystallite_subdt(g,i,e), g, i, e) ! update dependent state variables to be consistent with basic states
+ g, i, e) ! update dependent state variables to be consistent with basic states
enddo; enddo; enddo
!$OMP ENDDO
!$OMP END PARALLEL
@@ -2991,18 +2904,15 @@ subroutine crystallite_integrateStateFPI()
mesh_NcpElems
use material, only: &
plasticState, &
- damageState, &
- thermalState, &
- vacancyState, &
+ sourceState, &
mappingConstitutive, &
+ phase_Nsources, &
homogenization_Ngrains
use constitutive, only: &
constitutive_collectDotState, &
constitutive_microstructure, &
- constitutive_maxSizeDotState, &
- constitutive_damage_maxSizeDotState, &
- constitutive_thermal_maxSizeDotState, &
- constitutive_vacancy_maxSizeDotState
+ constitutive_plasticity_maxSizeDotState, &
+ constitutive_source_maxSizeDotState
implicit none
@@ -3013,10 +2923,9 @@ subroutine crystallite_integrateStateFPI()
g, & !< grain index in grain loop
p, &
c, &
+ mySource, &
mySizePlasticDotState, & ! size of dot states
- mySizeDamageDotState, &
- mySizeThermalDotState, &
- mySizeVacancyDotState
+ mySizeSourceDotState
integer(pInt), dimension(2) :: &
eIter ! bounds for element iteration
integer(pInt), dimension(2,mesh_NcpElems) :: &
@@ -3025,23 +2934,17 @@ subroutine crystallite_integrateStateFPI()
real(pReal) :: &
dot_prod12, &
dot_prod22, &
- stateDamper, & ! damper for integration of state
- damageStateDamper, &
- thermalStateDamper, &
- vacancyStateDamper
- real(pReal), dimension(constitutive_maxSizeDotState) :: &
- stateResiduum, &
- tempState
- real(pReal), dimension(constitutive_damage_maxSizeDotState) :: &
- damageStateResiduum, & ! residuum from evolution in micrstructure
- tempDamageState
- real(pReal), dimension(constitutive_thermal_maxSizeDotState) :: &
- thermalStateResiduum, & ! residuum from evolution in micrstructure
- tempThermalState
- real(pReal), dimension(constitutive_vacancy_maxSizeDotState) :: &
- vacancyStateResiduum, & ! residuum from evolution in micrstructure
- tempVacancyState
+ plasticStateDamper, & ! damper for integration of state
+ sourceStateDamper
+ real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: &
+ plasticStateResiduum, &
+ tempPlasticState
+ real(pReal), dimension(constitutive_source_maxSizeDotState, maxval(phase_Nsources)) :: &
+ sourceStateResiduum, & ! residuum from evolution in micrstructure
+ tempSourceState
logical :: &
+ converged, &
+ isNaN, &
singleRun, & ! flag indicating computation for single (g,i,e) triple
doneWithIntegration
@@ -3060,18 +2963,10 @@ subroutine crystallite_integrateStateFPI()
plasticState(p)%previousDotState = 0.0_pReal
plasticState(p)%previousDotState2 = 0.0_pReal
end forall
- forall(p = 1_pInt:size(damageState))
- damageState(p)%previousDotState = 0.0_pReal
- damageState(p)%previousDotState2 = 0.0_pReal
- end forall
- forall(p = 1_pInt:size(thermalState))
- thermalState(p)%previousDotState = 0.0_pReal
- thermalState(p)%previousDotState2 = 0.0_pReal
- end forall
- forall(p = 1_pInt:size(vacancyState))
- vacancyState(p)%previousDotState = 0.0_pReal
- vacancyState(p)%previousDotState2 = 0.0_pReal
- end forall
+ do p = 1_pInt, size(sourceState); do mySource = 1_pInt, phase_Nsources(p)
+ sourceState(p)%p(mySource)%previousDotState = 0.0_pReal
+ sourceState(p)%p(mySource)%previousDotState2 = 0.0_pReal
+ enddo; enddo
else
e = eIter(1)
i = iIter(1,e)
@@ -3080,12 +2975,10 @@ subroutine crystallite_integrateStateFPI()
c = mappingConstitutive(1,g,i,e)
plasticState(p)%previousDotState (:,c) = 0.0_pReal
plasticState(p)%previousDotState2(:,c) = 0.0_pReal
- damageState( p)%previousDotState (:,c) = 0.0_pReal
- damageState( p)%previousDotState2(:,c) = 0.0_pReal
- thermalState(p)%previousDotState (:,c) = 0.0_pReal
- thermalState(p)%previousDotState2(:,c) = 0.0_pReal
- vacancyState(p)%previousDotState (:,c) = 0.0_pReal
- vacancyState(p)%previousDotState2(:,c) = 0.0_pReal
+ do mySource = 1_pInt, phase_Nsources(p)
+ sourceState(p)%p(mySource)%previousDotState (:,c) = 0.0_pReal
+ sourceState(p)%p(mySource)%previousDotState2(:,c) = 0.0_pReal
+ enddo
enddo
endif
@@ -3097,21 +2990,24 @@ subroutine crystallite_integrateStateFPI()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) &
- call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), crystallite_Lp(1:3,1:3,g,i,e), &
+ call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), &
crystallite_Fe, &
crystallite_Fp, &
crystallite_subdt(g,i,e), crystallite_subFrac, g,i,e)
enddo; enddo; enddo
!$OMP ENDDO
- !$OMP DO PRIVATE(p,c)
+ !$OMP DO PRIVATE(p,c,isNaN)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
!$OMP FLUSH(crystallite_todo)
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
- if (any(prec_isNaN([plasticState(p)%dotState(:,c), damageState(p)%dotState(:,c), &
- thermalState(p)%dotState(:,c), vacancyState(p)%dotState(:,c)]))) then ! NaN occured in any dotState
+ isNaN = any(prec_isNaN(plasticState(p)%dotState(:,c)))
+ do mySource = 1_pInt, phase_Nsources(p)
+ isNaN = isNaN .or. any(prec_isNaN(sourceState(p)%p(mySource)%dotState(:,c)))
+ enddo
+ if (isNaN) then ! NaN occured in any dotState
if (.not. crystallite_localPlasticity(g,i,e)) then ! if broken is a non-local...
!$OMP CRITICAL (checkTodo)
crystallite_todo = crystallite_todo .and. crystallite_localPlasticity ! ...all non-locals done (and broken)
@@ -3126,27 +3022,23 @@ subroutine crystallite_integrateStateFPI()
! --- UPDATE STATE ---
- !$OMP DO PRIVATE(mySizePlasticDotState,mySizeDamageDotState,mySizeThermalDotState,mySizeVacancyDotState,p,c)
+ !$OMP DO PRIVATE(mySizePlasticDotState,mySizeSourceDotState,p,c)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
mySizePlasticDotState = plasticState(p)%sizeDotState
- mySizeDamageDotState = damageState( p)%sizeDotState
- mySizeThermalDotState = thermalState(p)%sizeDotState
- mySizeVacancyDotState = vacancyState(p)%sizeDotState
- plasticState(p)%state(1:mySizePlasticDotState,c) = plasticState(p)%subState0(1:mySizePlasticDotState,c) &
- + plasticState(p)%dotState (1:mySizePlasticDotState,c) &
- * crystallite_subdt(g,i,e)
- damageState( p)%state(1:mySizeDamageDotState,c) = damageState( p)%subState0(1:mySizeDamageDotState,c) &
- + damageState( p)%dotState (1:mySizeDamageDotState,c) &
- * crystallite_subdt(g,i,e)
- thermalState(p)%state(1:mySizeThermalDotState,c) = thermalState(p)%subState0(1:mySizeThermalDotState,c) &
- + thermalState(p)%dotState (1:mySizeThermalDotState,c) &
- * crystallite_subdt(g,i,e)
- vacancyState(p)%state(1:mySizeVacancyDotState,c) = vacancyState(p)%subState0(1:mySizeVacancyDotState,c) &
- + vacancyState(p)%dotState (1:mySizeVacancyDotState,c) &
- * crystallite_subdt(g,i,e)
+ plasticState(p)%state(1:mySizePlasticDotState,c) = &
+ plasticState(p)%subState0(1:mySizePlasticDotState,c) &
+ + plasticState(p)%dotState (1:mySizePlasticDotState,c) &
+ * crystallite_subdt(g,i,e)
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceState(p)%p(mySource)%state(1:mySizeSourceDotState,c) = &
+ sourceState(p)%p(mySource)%subState0(1:mySizeSourceDotState,c) &
+ + sourceState(p)%p(mySource)%dotState (1:mySizeSourceDotState,c) &
+ * crystallite_subdt(g,i,e)
+ enddo
endif
enddo; enddo; enddo
!$OMP ENDDO
@@ -3167,21 +3059,17 @@ subroutine crystallite_integrateStateFPI()
!$OMP DO PRIVATE(p,c)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e) .and. .not. crystallite_converged(g,i,e)) &
- call constitutive_microstructure(crystallite_Tstar_v(1:6,g,i,e), &
- crystallite_Fe(1:3,1:3,g,i,e), &
+ call constitutive_microstructure(crystallite_Fe(1:3,1:3,g,i,e), &
crystallite_Fp(1:3,1:3,g,i,e), &
- crystallite_Lp(1:3,1:3,g,i,e), &
- crystallite_subdt(g,i,e), g, i, e) ! update dependent state variables to be consistent with basic states
+ g, i, e) ! update dependent state variables to be consistent with basic states
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
plasticState(p)%previousDotState2(:,c) = plasticState(p)%previousDotState(:,c)
- damageState( p)%previousDotState2(:,c) = damageState( p)%previousDotState(:,c)
- thermalState(p)%previousDotState2(:,c) = thermalState(p)%previousDotState(:,c)
- vacancyState(p)%previousDotState2(:,c) = vacancyState(p)%previousDotState(:,c)
plasticState(p)%previousDotState (:,c) = plasticState(p)%dotState(:,c)
- damageState( p)%previousDotState (:,c) = damageState( p)%dotState(:,c)
- thermalState(p)%previousDotState (:,c) = thermalState(p)%dotState(:,c)
- vacancyState(p)%previousDotState (:,c) = vacancyState(p)%dotState(:,c)
+ do mySource = 1_pInt, phase_Nsources(p)
+ sourceState(p)%p(mySource)%previousDotState2(:,c) = sourceState(p)%p(mySource)%previousDotState(:,c)
+ sourceState(p)%p(mySource)%previousDotState (:,c) = sourceState(p)%p(mySource)%dotState(:,c)
+ enddo
enddo; enddo; enddo
!$OMP ENDDO
@@ -3215,7 +3103,7 @@ subroutine crystallite_integrateStateFPI()
!$OMP DO
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e) .and. .not. crystallite_converged(g,i,e)) &
- call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), crystallite_Lp(1:3,1:3,g,i,e), &
+ call constitutive_collectDotState(crystallite_Tstar_v(1:6,g,i,e), &
crystallite_Fe, &
crystallite_Fp, &
crystallite_subdt(g,i,e), crystallite_subFrac, g,i,e)
@@ -3228,8 +3116,11 @@ subroutine crystallite_integrateStateFPI()
if (crystallite_todo(g,i,e) .and. .not. crystallite_converged(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
- if (any(prec_isNaN([plasticState(p)%dotState(:,c), damageState(p)%dotState(:,c), &
- thermalState(p)%dotState(:,c), vacancyState(p)%dotState(:,c)]))) then ! NaN occured in any dotState
+ isNaN = any(prec_isNaN(plasticState(p)%dotState(:,c)))
+ do mySource = 1_pInt, phase_Nsources(p)
+ isNaN = isNaN .or. any(prec_isNaN(sourceState(p)%p(mySource)%dotState(:,c)))
+ enddo
+ if (isNaN) then ! NaN occured in any dotState
crystallite_todo(g,i,e) = .false. ! ... skip me next time
if (.not. crystallite_localPlasticity(g,i,e)) then ! if me is non-local...
!$OMP CRITICAL (checkTodo)
@@ -3246,141 +3137,117 @@ subroutine crystallite_integrateStateFPI()
! --- UPDATE STATE ---
!$OMP DO PRIVATE(dot_prod12,dot_prod22, &
- !$OMP& mySizePlasticDotState,mySizeDamageDotState,mySizeThermalDotState,mySizeVacancyDotState, &
- !$OMP& stateResiduum, damageStateResiduum,thermalStateResiduum,vacancyStateResiduum, &
- !$OMP& statedamper, damageStateDamper,thermalStateDamper,vacancyStateDamper, &
- !$OMP& tempState, tempDamageState,tempThermalState,tempVacancyState,p,c)
+ !$OMP& mySizePlasticDotState,mySizeSourceDotState, &
+ !$OMP& plasticStateResiduum,sourceStateResiduum, &
+ !$OMP& plasticStatedamper,sourceStateDamper, &
+ !$OMP& tempPlasticState,tempSourceState,converged,p,c)
do e = eIter(1),eIter(2); do i = iIter(1,e),iIter(2,e); do g = gIter(1,e),gIter(2,e) ! iterate over elements, ips and grains
if (crystallite_todo(g,i,e) .and. .not. crystallite_converged(g,i,e)) then
p = mappingConstitutive(2,g,i,e)
c = mappingConstitutive(1,g,i,e)
- mySizePlasticDotState = plasticState(p)%sizeDotState
- mySizeDamageDotState = damageState( p)%sizeDotState
- mySizeThermalDotState = thermalState(p)%sizeDotState
- mySizeVacancyDotState = vacancyState(p)%sizeDotState
-
- dot_prod12 = dot_product(plasticState(p)%dotState(:,c) - plasticState(p)%previousDotState(:,c), &
- plasticState(p)%previousDotState(:,c) - plasticState(p)%previousDotState2(:,c))
- dot_prod22 = dot_product(plasticState(p)%previousDotState(:,c) - plasticState(p)%previousDotState2(:,c), &
- plasticState(p)%previousDotState(:,c) - plasticState(p)%previousDotState2(:,c))
+ dot_prod12 = dot_product( plasticState(p)%dotState (:,c) &
+ - plasticState(p)%previousDotState (:,c), &
+ plasticState(p)%previousDotState (:,c) &
+ - plasticState(p)%previousDotState2(:,c))
+ dot_prod22 = dot_product( plasticState(p)%previousDotState (:,c) &
+ - plasticState(p)%previousDotState2(:,c), &
+ plasticState(p)%previousDotState (:,c) &
+ - plasticState(p)%previousDotState2(:,c))
if ( dot_prod22 > 0.0_pReal &
.and. ( dot_prod12 < 0.0_pReal &
.or. dot_product(plasticState(p)%dotState(:,c), &
plasticState(p)%previousDotState(:,c)) < 0.0_pReal) ) then
- stateDamper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22)
+ plasticStateDamper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22)
else
- stateDamper = 1.0_pReal
- endif
-
- dot_prod12 = dot_product(damageState(p)%dotState(:,c) - damageState(p)%previousDotState(:,c), &
- damageState(p)%previousDotState(:,c) - damageState(p)%previousDotState2(:,c))
- dot_prod22 = dot_product(damageState(p)%previousDotState(:,c) - damageState(p)%previousDotState2(:,c), &
- damageState(p)%previousDotState(:,c) - damageState(p)%previousDotState2(:,c))
- if ( dot_prod22 > 0.0_pReal &
- .and. ( dot_prod12 < 0.0_pReal &
- .or. dot_product(damageState(p)%dotState(:,c), &
- damageState(p)%previousDotState(:,c)) < 0.0_pReal) ) then
- damageStateDamper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22)
- else
- damageStateDamper = 1.0_pReal
- endif
-
- dot_prod12 = dot_product(thermalState(p)%dotState(:,c) - thermalState(p)%previousDotState(:,c), &
- thermalState(p)%previousDotState(:,c) - thermalState(p)%previousDotState2(:,c))
- dot_prod22 = dot_product(thermalState(p)%previousDotState(:,c) - thermalState(p)%previousDotState2(:,c), &
- thermalState(p)%previousDotState(:,c) - thermalState(p)%previousDotState2(:,c))
- if ( dot_prod22 > 0.0_pReal &
- .and. ( dot_prod12 < 0.0_pReal &
- .or. dot_product(thermalState(p)%dotState(:,c), &
- thermalState(p)%previousDotState(:,c)) < 0.0_pReal) ) then
- thermalStateDamper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22)
- else
- thermalStateDamper = 1.0_pReal
- endif
-
- dot_prod12 = dot_product(vacancyState(p)%dotState(:,c) - vacancyState(p)%previousDotState(:,c), &
- vacancyState(p)%previousDotState(:,c) - vacancyState(p)%previousDotState2(:,c))
- dot_prod22 = dot_product(vacancyState(p)%previousDotState(:,c) - vacancyState(p)%previousDotState2(:,c), &
- vacancyState(p)%previousDotState(:,c) - vacancyState(p)%previousDotState2(:,c))
- if ( dot_prod22 > 0.0_pReal &
- .and. ( dot_prod12 < 0.0_pReal &
- .or. dot_product(vacancyState(p)%dotState(:,c), &
- vacancyState(p)%previousDotState(:,c)) < 0.0_pReal) ) then
- vacancyStateDamper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22)
- else
- vacancyStateDamper = 1.0_pReal
+ plasticStateDamper = 1.0_pReal
endif
! --- get residui ---
- stateResiduum(1:mySizePlasticDotState) = plasticState(p)%state(1:mySizePlasticDotState,c) &
- - plasticState(p)%subState0(1:mySizePlasticDotState,c) &
- - (plasticState(p)%dotState(1:mySizePlasticDotState,c) * stateDamper &
- + plasticState(p)%previousDotState(1:mySizePlasticDotState,c) &
- * (1.0_pReal - stateDamper)) * crystallite_subdt(g,i,e)
+ mySizePlasticDotState = plasticState(p)%sizeDotState
+ plasticStateResiduum(1:mySizePlasticDotState) = &
+ plasticState(p)%state(1:mySizePlasticDotState,c) &
+ - plasticState(p)%subState0(1:mySizePlasticDotState,c) &
+ - ( plasticState(p)%dotState(1:mySizePlasticDotState,c) * plasticStateDamper &
+ + plasticState(p)%previousDotState(1:mySizePlasticDotState,c) &
+ * (1.0_pReal - plasticStateDamper)) * crystallite_subdt(g,i,e)
- damageStateResiduum(1:mySizeDamageDotState) = damageState(p)%state(1:mySizeDamageDotState,c) &
- - damageState(p)%subState0(1:mySizeDamageDotState,c) &
- - (damageState(p)%dotState(1:mySizeDamageDotState,c) * damageStateDamper &
- + damageState(p)%previousDotState(1:mySizeDamageDotState,c) &
- * (1.0_pReal - damageStateDamper)) * crystallite_subdt(g,i,e)
-
- thermalStateResiduum(1:mySizeThermalDotState) = thermalState(p)%state(1:mySizeThermalDotState,c) &
- - thermalState(p)%subState0(1:mySizeThermalDotState,c) &
- - (thermalState(p)%dotState(1:mySizeThermalDotState,c) * thermalStateDamper &
- + thermalState(p)%previousDotState(1:mySizeThermalDotState,c) &
- * (1.0_pReal - thermalStateDamper)) * crystallite_subdt(g,i,e)
- vacancyStateResiduum(1:mySizeVacancyDotState) = vacancyState(p)%state(1:mySizeVacancyDotState,c) &
- - vacancyState(p)%subState0(1:mySizeVacancyDotState,c) &
- - (vacancyState(p)%dotState(1:mySizeVacancyDotState,c) * vacancyStateDamper &
- + vacancyState(p)%previousDotState(1:mySizeVacancyDotState,c) &
- * (1.0_pReal - vacancyStateDamper)) * crystallite_subdt(g,i,e)
! --- correct state with residuum ---
- tempState(1:mySizePlasticDotState) = plasticState(p)%state(1:mySizePlasticDotState,c) &
- - stateResiduum(1:mySizePlasticDotState) ! need to copy to local variable, since we cant flush a pointer in openmp
- tempDamageState(1:mySizeDamageDotState) = damageState(p)%state(1:mySizeDamageDotState,c) &
- - damageStateResiduum(1:mySizeDamageDotState) ! need to copy to local variable, since we cant flush a pointer in openmp
- tempThermalState(1:mySizeThermalDotState) = thermalState(p)%state(1:mySizeThermalDotState,c) &
- - thermalStateResiduum(1:mySizeThermalDotState) ! need to copy to local variable, since we cant flush a pointer in openmp
- tempVacancyState(1:mySizeVacancyDotState) = vacancyState(p)%state(1:mySizeVacancyDotState,c) &
- - vacancyStateResiduum(1:mySizeVacancyDotState) ! need to copy to local variable, since we cant flush a pointer in openmp
+ tempPlasticState(1:mySizePlasticDotState) = &
+ plasticState(p)%state(1:mySizePlasticDotState,c) &
+ - plasticStateResiduum(1:mySizePlasticDotState) ! need to copy to local variable, since we cant flush a pointer in openmp
+
+ ! --- store corrected dotState --- (cannot do this before state update, because not sure how to flush pointers in openmp)
+
+ plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) * plasticStateDamper &
+ + plasticState(p)%previousDotState(:,c) &
+ * (1.0_pReal - plasticStateDamper)
+
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ dot_prod12 = dot_product( sourceState(p)%p(mySource)%dotState (:,c) &
+ - sourceState(p)%p(mySource)%previousDotState (:,c), &
+ sourceState(p)%p(mySource)%previousDotState (:,c) &
+ - sourceState(p)%p(mySource)%previousDotState2(:,c))
+ dot_prod22 = dot_product( sourceState(p)%p(mySource)%previousDotState (:,c) &
+ - sourceState(p)%p(mySource)%previousDotState2(:,c), &
+ sourceState(p)%p(mySource)%previousDotState (:,c) &
+ - sourceState(p)%p(mySource)%previousDotState2(:,c))
+
+ if ( dot_prod22 > 0.0_pReal &
+ .and. ( dot_prod12 < 0.0_pReal &
+ .or. dot_product(sourceState(p)%p(mySource)%dotState(:,c), &
+ sourceState(p)%p(mySource)%previousDotState(:,c)) < 0.0_pReal) ) then
+ sourceStateDamper = 0.75_pReal + 0.25_pReal * tanh(2.0_pReal + 4.0_pReal * dot_prod12 / dot_prod22)
+ else
+ sourceStateDamper = 1.0_pReal
+ endif
+ ! --- get residui ---
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceStateResiduum(1:mySizeSourceDotState,mySource) = &
+ sourceState(p)%p(mySource)%state(1:mySizeSourceDotState,c) &
+ - sourceState(p)%p(mySource)%subState0(1:mySizeSourceDotState,c) &
+ - ( sourceState(p)%p(mySource)%dotState(1:mySizeSourceDotState,c) * sourceStateDamper &
+ + sourceState(p)%p(mySource)%previousDotState(1:mySizeSourceDotState,c) &
+ * (1.0_pReal - sourceStateDamper)) * crystallite_subdt(g,i,e)
+
+ ! --- correct state with residuum ---
+ tempSourceState(1:mySizeSourceDotState,mySource) = &
+ sourceState(p)%p(mySource)%state(1:mySizeSourceDotState,c) &
+ - sourceStateResiduum(1:mySizeSourceDotState,mySource) ! need to copy to local variable, since we cant flush a pointer in openmp
+
+ ! --- store corrected dotState --- (cannot do this before state update, because not sure how to flush pointers in openmp)
+ sourceState(p)%p(mySource)%dotState(:,c) = &
+ sourceState(p)%p(mySource)%dotState(:,c) * sourceStateDamper &
+ + sourceState(p)%p(mySource)%previousDotState(:,c) &
+ * (1.0_pReal - sourceStateDamper)
+ enddo
+
#ifndef _OPENMP
if (iand(debug_level(debug_crystallite), debug_levelExtensive) /= 0_pInt &
.and. ((e == debug_e .and. i == debug_i .and. g == debug_g) &
.or. .not. iand(debug_level(debug_crystallite), debug_levelSelective) /= 0_pInt)) then
write(6,'(a,i8,1x,i2,1x,i3,/)') '<< CRYST >> update state at el ip g ',e,i,g
- write(6,'(a,f6.1,/)') '<< CRYST >> statedamper ',statedamper
- write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> state residuum',stateResiduum(1:mySizePlasticDotState)
- write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> new state',tempState(1:mySizePlasticDotState)
+ write(6,'(a,f6.1,/)') '<< CRYST >> plasticstatedamper ',plasticStatedamper
+ write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> plastic state residuum',plasticStateResiduum(1:mySizePlasticDotState)
+ write(6,'(a,/,(12x,12(e12.5,1x)),/)') '<< CRYST >> new state',tempPlasticState(1:mySizePlasticDotState)
endif
#endif
- ! --- store corrected dotState --- (cannot do this before state update, because not sure how to flush pointers in openmp)
- plasticState(p)%dotState(:,c) = plasticState(p)%dotState(:,c) * stateDamper &
- + plasticState(p)%previousDotState(:,c) &
- * (1.0_pReal - stateDamper)
- damageState( p)%dotState(:,c) = damageState(p)%dotState(:,c) * damageStateDamper &
- + damageState(p)%previousDotState(:,c) &
- * (1.0_pReal - damageStateDamper)
- thermalState(p)%dotState(:,c) = thermalState(p)%dotState(:,c) * thermalStateDamper &
- + thermalState(p)%previousDotState(:,c) &
- * (1.0_pReal - thermalStateDamper)
- vacancyState(p)%dotState(:,c) = vacancyState(p)%dotState(:,c) * vacancyStateDamper &
- + vacancyState(p)%previousDotState(:,c) &
- * (1.0_pReal - vacancyStateDamper)
! --- converged ? ---
- if ( all( abs(stateResiduum(1:mySizePlasticDotState)) < plasticState(p)%aTolState(1:mySizePlasticDotState) &
- .or. abs(stateResiduum(1:mySizePlasticDotState)) < rTol_crystalliteState &
- * abs(tempState(1:mySizePlasticDotState)) ) &
- .and. all( abs(damageStateResiduum(1:mySizeDamageDotState)) < damageState(p)%aTolState(1:mySizeDamageDotState) &
- .or. abs(damageStateResiduum(1:mySizeDamageDotState)) < rTol_crystalliteState &
- * abs(tempDamageState(1:mySizeDamageDotState)) ) &
- .and. all( abs(thermalStateResiduum(1:mySizeThermalDotState)) < thermalState(p)%aTolState(1:mySizeThermalDotState) &
- .or. abs(thermalStateResiduum(1:mySizeThermalDotState)) < rTol_crystalliteState &
- * abs(tempThermalState(1:mySizeThermalDotState)) ) &
- .and. all( abs(vacancyStateResiduum(1:mySizeVacancyDotState)) < vacancyState(p)%aTolState(1:mySizeVacancyDotState) &
- .or. abs(vacancyStateResiduum(1:mySizeVacancyDotState)) < rTol_crystalliteState &
- * abs(tempVacancyState(1:mySizeVacancyDotState)) )) then
+ converged = all( abs(plasticStateResiduum(1:mySizePlasticDotState)) < &
+ plasticState(p)%aTolState(1:mySizePlasticDotState) &
+ .or. abs(plasticStateResiduum(1:mySizePlasticDotState)) < &
+ rTol_crystalliteState * abs(tempPlasticState(1:mySizePlasticDotState)))
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ converged = converged .and. &
+ all( abs(sourceStateResiduum(1:mySizeSourceDotState,mySource)) < &
+ sourceState(p)%p(mySource)%aTolState(1:mySizeSourceDotState) &
+ .or. abs(sourceStateResiduum(1:mySizeSourceDotState,mySource)) < &
+ rTol_crystalliteState * abs(tempSourceState(1:mySizeSourceDotState,mySource)))
+ enddo
+ if (converged) then
crystallite_converged(g,i,e) = .true. ! ... converged per definition
if (iand(debug_level(debug_crystallite), debug_levelBasic) /= 0_pInt) then
@@ -3390,10 +3257,13 @@ subroutine crystallite_integrateStateFPI()
!$OMP END CRITICAL (distributionState)
endif
endif
- plasticState(p)%state(1:mySizePlasticDotState,c) = tempState(1:mySizePlasticDotState)
- damageState( p)%state(1:mySizeDamageDotState, c) = tempDamageState(1:mySizeDamageDotState)
- thermalState(p)%state(1:mySizeThermalDotState,c) = tempThermalState(1:mySizeThermalDotState)
- vacancyState(p)%state(1:mySizeVacancyDotState,c) = tempVacancyState(1:mySizeVacancyDotState)
+ plasticState(p)%state(1:mySizePlasticDotState,c) = &
+ tempPlasticState(1:mySizePlasticDotState)
+ do mySource = 1_pInt, phase_Nsources(p)
+ mySizeSourceDotState = sourceState(p)%p(mySource)%sizeDotState
+ sourceState(p)%p(mySource)%state(1:mySizeSourceDotState,c) = &
+ tempSourceState(1:mySizeSourceDotState,mySource)
+ enddo
endif
enddo; enddo; enddo
!$OMP ENDDO
@@ -3484,7 +3354,7 @@ logical function crystallite_stateJump(g,i,e)
c = mappingConstitutive(1,g,i,e)
p = mappingConstitutive(2,g,i,e)
- if (constitutive_collectDeltaState(crystallite_Tstar_v(1:6,g,i,e), g,i,e)) then
+ if (constitutive_collectDeltaState(crystallite_Tstar_v(1:6,g,i,e), crystallite_Fe(1:3,1:3,g,i,e), g,i,e)) then
mySizePlasticDotState = plasticState(p)%sizeDotState
if( any(plasticState(p)%deltaState(:,c) /= plasticState(p)%deltaState(:,c))) then ! NaN occured in deltaState
crystallite_stateJump = .false.
@@ -3889,7 +3759,7 @@ logical function crystallite_integrateStress(&
!* calculate intermediate velocity gradient and its tangent from constitutive law
call constitutive_LiAndItsTangent(Li_constitutive, dLi_dT3333, dLi_dFi3333, &
- Tstar_v, Fi_new, Lpguess, g, i, e)
+ Tstar_v, Fi_new, g, i, e)
!* update current residuum and check for convergence of loop
@@ -4150,9 +4020,7 @@ function crystallite_postResults(ipc, ip, el)
FE_celltype
use material, only: &
plasticState, &
- damageState, &
- thermalState, &
- vacancyState, &
+ sourceState, &
microstructure_crystallite, &
crystallite_Noutput, &
material_phase, &
@@ -4170,9 +4038,7 @@ function crystallite_postResults(ipc, ip, el)
real(pReal), dimension(1+crystallite_sizePostResults(microstructure_crystallite(mesh_element(4,el))) + &
1+plasticState(material_phase(ipc,ip,el))%sizePostResults + &
- damageState( material_phase(ipc,ip,el))%sizePostResults + &
- thermalState(material_phase(ipc,ip,el))%sizePostResults + &
- vacancyState(material_phase(ipc,ip,el))%sizePostResults) :: &
+ sum(sourceState(material_phase(ipc,ip,el))%p(:)%sizePostResults)) :: &
crystallite_postResults
real(pReal), dimension(3,3) :: &
Ee
diff --git a/code/damage_anisoBrittle.f90 b/code/damage_anisoBrittle.f90
deleted file mode 100644
index 394e48276..000000000
--- a/code/damage_anisoBrittle.f90
+++ /dev/null
@@ -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
- 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
diff --git a/code/damage_anisoDuctile.f90 b/code/damage_anisoDuctile.f90
deleted file mode 100644
index fac1ee1d5..000000000
--- a/code/damage_anisoDuctile.f90
+++ /dev/null
@@ -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
- 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
diff --git a/code/damage_gurson.f90 b/code/damage_gurson.f90
deleted file mode 100644
index e9ff5256a..000000000
--- a/code/damage_gurson.f90
+++ /dev/null
@@ -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
- 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
diff --git a/code/damage_isoBrittle.f90 b/code/damage_isoBrittle.f90
deleted file mode 100644
index 5e431ba18..000000000
--- a/code/damage_isoBrittle.f90
+++ /dev/null
@@ -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
- 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
diff --git a/code/damage_isoDuctile.f90 b/code/damage_isoDuctile.f90
deleted file mode 100644
index 07d3c9708..000000000
--- a/code/damage_isoDuctile.f90
+++ /dev/null
@@ -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
- 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
diff --git a/code/damage_local.f90 b/code/damage_local.f90
new file mode 100644
index 000000000..afc3999a9
--- /dev/null
+++ b/code/damage_local.f90
@@ -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
+ 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
diff --git a/code/damage_none.f90 b/code/damage_none.f90
index 889fee8d0..9bf0f95af 100644
--- a/code/damage_none.f90
+++ b/code/damage_none.f90
@@ -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
diff --git a/code/damage_nonlocal.f90 b/code/damage_nonlocal.f90
new file mode 100644
index 000000000..d0b327234
--- /dev/null
+++ b/code/damage_nonlocal.f90
@@ -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
+ 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
diff --git a/code/damage_phaseField.f90 b/code/damage_phaseField.f90
deleted file mode 100644
index c8a7b190e..000000000
--- a/code/damage_phaseField.f90
+++ /dev/null
@@ -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
- 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
diff --git a/code/homogenization.f90 b/code/homogenization.f90
index 2344db4ad..29c5745c3 100644
--- a/code/homogenization.f90
+++ b/code/homogenization.f90
@@ -37,7 +37,11 @@ module homogenization
integer(pInt), public, protected :: &
materialpoint_sizeResults, &
homogenization_maxSizePostResults, &
- field_maxSizePostResults
+ thermal_maxSizePostResults, &
+ damage_maxSizePostResults, &
+ vacancyflux_maxSizePostResults, &
+ porosity_maxSizePostResults, &
+ hydrogenflux_maxSizePostResults
real(pReal), dimension(:,:,:,:), allocatable, private :: &
materialpoint_subF0, & !< def grad of IP at beginning of homogenization increment
@@ -51,45 +55,11 @@ module homogenization
materialpoint_converged
logical, dimension(:,:,:), allocatable, private :: &
materialpoint_doneAndHappy
- enum, bind(c)
- enumerator :: undefined_ID, &
- temperature_ID, &
- damage_ID, &
- vacancy_concentration_ID
- end enum
- integer(pInt), dimension(:), allocatable, public, protected :: &
- field_sizePostResults
- integer(pInt), dimension(:,:), allocatable, private :: &
- field_sizePostResult
-
- character(len=64), dimension(:,:), allocatable, private :: &
- field_output !< name of each post result output
- integer(pInt), dimension(:), allocatable, private :: &
- field_Noutput !< number of outputs per homog instance
- integer(kind(undefined_ID)), dimension(:,:), allocatable, private :: &
- field_outputID !< ID of each post result output
public :: &
homogenization_init, &
materialpoint_stressAndItsTangent, &
- field_getLocalDamage, &
- field_getFieldDamage, &
- field_putFieldDamage, &
- field_getLocalTemperature, &
- field_putFieldTemperature, &
- field_getHeatGeneration, &
- field_getLocalVacancyConcentration, &
- field_putFieldVacancyConcentration, &
- field_getDamageMobility, &
- field_getDamageDiffusion33, &
- field_getThermalConductivity33, &
- field_getMassDensity, &
- field_getSpecificHeat, &
- field_getVacancyMobility33, &
- field_getVacancyDiffusion33, &
- field_getVacancyEnergy, &
- materialpoint_postResults, &
- field_postResults
+ materialpoint_postResults
private :: &
homogenization_partitionDeformation, &
homogenization_updateState, &
@@ -102,7 +72,7 @@ contains
!--------------------------------------------------------------------------------------------------
!> @brief module initialization
!--------------------------------------------------------------------------------------------------
-subroutine homogenization_init()
+subroutine homogenization_init(temperature_init)
#ifdef HDF
use hdf5, only: &
HID_T
@@ -129,10 +99,8 @@ subroutine homogenization_init()
crystallite_sizePostResults
#else
use constitutive, only: &
- constitutive_maxSizePostResults, &
- constitutive_damage_maxSizePostResults, &
- constitutive_thermal_maxSizePostResults, &
- constitutive_vacancy_maxSizePostResults
+ constitutive_plasticity_maxSizePostResults, &
+ constitutive_source_maxSizePostResults
use crystallite, only: &
crystallite_maxSizePostResults
#endif
@@ -140,30 +108,38 @@ subroutine homogenization_init()
use homogenization_none
use homogenization_isostrain
use homogenization_RGC
+ use thermal_isothermal
+ use thermal_adiabatic
+ use thermal_conduction
+ use damage_none
+ use damage_local
+ use damage_nonlocal
+ use vacancyflux_isoconc
+ use vacancyflux_isochempot
+ use vacancyflux_cahnhilliard
+ use porosity_none
+ use porosity_phasefield
+ use hydrogenflux_isoconc
+ use hydrogenflux_cahnhilliard
use IO
use numerics, only: &
worldrank
implicit none
+ real(pReal), intent(in) :: temperature_init !< initial temperature
integer(pInt), parameter :: FILEUNIT = 200_pInt
- integer(pInt) :: e,i,p,myInstance
+ integer(pInt) :: e,i,p
integer(pInt), dimension(:,:), pointer :: thisSize
integer(pInt), dimension(:) , pointer :: thisNoutput
character(len=64), dimension(:,:), pointer :: thisOutput
character(len=32) :: outputName !< name of output, intermediate fix until HDF5 output is ready
- logical :: knownHomogenization
+ logical :: knownHomogenization, knownThermal, knownDamage, knownVacancyflux, knownPorosity, knownHydrogenflux
#ifdef HDF
integer(pInt), dimension(:,:), allocatable :: mapping
integer(pInt), dimension(:), allocatable :: InstancePosition
allocate(mapping(mesh_ncpelems,4),source=0_pInt)
allocate(InstancePosition(material_Nhomogenization),source=0_pInt)
#endif
- integer(pInt), parameter :: MAXNCHUNKS = 2_pInt
- integer(pInt), dimension(1_pInt+2_pInt*MAXNCHUNKS) :: positions
- integer(pInt) :: section = 0_pInt
- character(len=65536) :: &
- tag = '', &
- line = ''
!--------------------------------------------------------------------------------------------------
! parse homogenization from config file
@@ -178,64 +154,59 @@ subroutine homogenization_init()
close(FILEUNIT)
!--------------------------------------------------------------------------------------------------
-! parse field from config file
- allocate(field_sizePostResults(material_Nhomogenization), source=0_pInt)
- allocate(field_sizePostResult(maxval(homogenization_Noutput),material_Nhomogenization), &
- source=0_pInt)
- allocate(field_Noutput(material_Nhomogenization), source=0_pInt)
- allocate(field_outputID(maxval(homogenization_Noutput),material_Nhomogenization), &
- source=undefined_ID)
- allocate(field_output(maxval(homogenization_Noutput),material_Nhomogenization))
- field_output = ''
-
+! parse thermal from config file
if (.not. IO_open_jobFile_stat(FILEUNIT,material_localFileExt)) & ! no local material configuration present...
call IO_open_file(FILEUNIT,material_configFile) ! ... open material.config file
- rewind(FILEUNIT)
- do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partHomogenization)! wind forward to
- line = IO_read(FILEUNIT)
- enddo
-
- parsingFile: do while (trim(line) /= IO_EOF) ! read through sections of homogenization 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 section
- section = section + 1_pInt
- cycle
- endif
- if (section > 0_pInt ) then ! do not short-circuit here (.and. with next if-statement). 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 ('(output)')
- select case(IO_lc(IO_stringValue(line,positions,2_pInt)))
- case('temperature')
- field_Noutput(section) = field_Noutput(section) + 1_pInt
- field_outputID(field_Noutput(section),section) = temperature_ID
- field_sizePostResult(field_Noutput(section),section) = 1_pInt
- field_sizePostResults(section) = field_sizePostResults(section) + 1_pInt
- field_output(field_Noutput(section),section) = IO_lc(IO_stringValue(line,positions,2_pInt))
- case('damage')
- field_Noutput(section) = field_Noutput(section) + 1_pInt
- field_outputID(field_Noutput(section),section) = damage_ID
- field_sizePostResult(field_Noutput(section),section) = 1_pInt
- field_sizePostResults(section) = field_sizePostResults(section) + 1_pInt
- field_output(field_Noutput(section),section) = IO_lc(IO_stringValue(line,positions,2_pInt))
- case('vacancy_concentration')
- field_Noutput(section) = field_Noutput(section) + 1_pInt
- field_outputID(field_Noutput(section),section) = vacancy_concentration_ID
- field_sizePostResult(field_Noutput(section),section) = 1_pInt
- field_sizePostResults(section) = field_sizePostResults(section) + 1_pInt
- field_output(field_Noutput(section),section) = IO_lc(IO_stringValue(line,positions,2_pInt))
-
- end select
-
- end select
- endif
- enddo parsingFile
+ if (any(thermal_type == THERMAL_isothermal_ID)) &
+ call thermal_isothermal_init(temperature_init)
+ if (any(thermal_type == THERMAL_adiabatic_ID)) &
+ call thermal_adiabatic_init(FILEUNIT,temperature_init)
+ if (any(thermal_type == THERMAL_conduction_ID)) &
+ call thermal_conduction_init(FILEUNIT,temperature_init)
+ close(FILEUNIT)
+
+!--------------------------------------------------------------------------------------------------
+! parse damage from config file
+ if (.not. IO_open_jobFile_stat(FILEUNIT,material_localFileExt)) & ! no local material configuration present...
+ call IO_open_file(FILEUNIT,material_configFile) ! ... open material.config file
+ if (any(damage_type == DAMAGE_none_ID)) &
+ call damage_none_init()
+ if (any(damage_type == DAMAGE_local_ID)) &
+ call damage_local_init(FILEUNIT)
+ if (any(damage_type == DAMAGE_nonlocal_ID)) &
+ call damage_nonlocal_init(FILEUNIT)
+ close(FILEUNIT)
+
+!--------------------------------------------------------------------------------------------------
+! parse vacancy transport from config file
+ if (.not. IO_open_jobFile_stat(FILEUNIT,material_localFileExt)) & ! no local material configuration present...
+ call IO_open_file(FILEUNIT,material_configFile) ! ... open material.config file
+ if (any(vacancyflux_type == VACANCYFLUX_isoconc_ID)) &
+ call vacancyflux_isoconc_init()
+ if (any(vacancyflux_type == VACANCYFLUX_isochempot_ID)) &
+ call vacancyflux_isochempot_init(FILEUNIT)
+ if (any(vacancyflux_type == VACANCYFLUX_cahnhilliard_ID)) &
+ call vacancyflux_cahnhilliard_init(FILEUNIT)
+ close(FILEUNIT)
+
+!--------------------------------------------------------------------------------------------------
+! parse porosity from config file
+ if (.not. IO_open_jobFile_stat(FILEUNIT,material_localFileExt)) & ! no local material configuration present...
+ call IO_open_file(FILEUNIT,material_configFile) ! ... open material.config file
+ if (any(porosity_type == POROSITY_none_ID)) &
+ call porosity_none_init()
+ if (any(porosity_type == POROSITY_phasefield_ID)) &
+ call porosity_phasefield_init(FILEUNIT)
+ close(FILEUNIT)
+
+!--------------------------------------------------------------------------------------------------
+! parse hydrogen transport from config file
+ if (.not. IO_open_jobFile_stat(FILEUNIT,material_localFileExt)) & ! no local material configuration present...
+ call IO_open_file(FILEUNIT,material_configFile) ! ... open material.config file
+ if (any(hydrogenflux_type == HYDROGENFLUX_isoconc_ID)) &
+ call hydrogenflux_isoconc_init()
+ if (any(hydrogenflux_type == HYDROGENFLUX_cahnhilliard_ID)) &
+ call hydrogenflux_cahnhilliard_init(FILEUNIT)
close(FILEUNIT)
!--------------------------------------------------------------------------------------------------
@@ -275,9 +246,141 @@ subroutine homogenization_init()
enddo
endif
endif
- do e = 1_pInt,field_Noutput(p)
- write(FILEUNIT,'(a,i4)') trim(field_output(e,p))//char(9),field_sizePostResult(e,p)
- enddo
+ i = thermal_typeInstance(p) ! which instance of this thermal type
+ knownThermal = .true. ! assume valid
+ select case(thermal_type(p)) ! split per thermal type
+ case (THERMAL_isothermal_ID)
+ outputName = THERMAL_isothermal_label
+ thisNoutput => null()
+ thisOutput => null()
+ thisSize => null()
+ case (THERMAL_adiabatic_ID)
+ outputName = THERMAL_adiabatic_label
+ thisNoutput => thermal_adiabatic_Noutput
+ thisOutput => thermal_adiabatic_output
+ thisSize => thermal_adiabatic_sizePostResult
+ case (THERMAL_conduction_ID)
+ outputName = THERMAL_conduction_label
+ thisNoutput => thermal_conduction_Noutput
+ thisOutput => thermal_conduction_output
+ thisSize => thermal_conduction_sizePostResult
+ case default
+ knownThermal = .false.
+ end select
+ if (knownThermal) then
+ write(FILEUNIT,'(a)') '(thermal)'//char(9)//trim(outputName)
+ if (thermal_type(p) /= THERMAL_isothermal_ID) then
+ do e = 1,thisNoutput(i)
+ write(FILEUNIT,'(a,i4)') trim(thisOutput(e,i))//char(9),thisSize(e,i)
+ enddo
+ endif
+ endif
+ i = damage_typeInstance(p) ! which instance of this damage type
+ knownDamage = .true. ! assume valid
+ select case(damage_type(p)) ! split per damage type
+ case (DAMAGE_none_ID)
+ outputName = DAMAGE_none_label
+ thisNoutput => null()
+ thisOutput => null()
+ thisSize => null()
+ case (DAMAGE_local_ID)
+ outputName = DAMAGE_local_label
+ thisNoutput => damage_local_Noutput
+ thisOutput => damage_local_output
+ thisSize => damage_local_sizePostResult
+ case (DAMAGE_nonlocal_ID)
+ outputName = DAMAGE_nonlocal_label
+ thisNoutput => damage_nonlocal_Noutput
+ thisOutput => damage_nonlocal_output
+ thisSize => damage_nonlocal_sizePostResult
+ case default
+ knownDamage = .false.
+ end select
+ if (knownDamage) then
+ write(FILEUNIT,'(a)') '(damage)'//char(9)//trim(outputName)
+ if (damage_type(p) /= DAMAGE_none_ID) then
+ do e = 1,thisNoutput(i)
+ write(FILEUNIT,'(a,i4)') trim(thisOutput(e,i))//char(9),thisSize(e,i)
+ enddo
+ endif
+ endif
+ i = vacancyflux_typeInstance(p) ! which instance of this vacancy flux type
+ knownVacancyflux = .true. ! assume valid
+ select case(vacancyflux_type(p)) ! split per vacancy flux type
+ case (VACANCYFLUX_isoconc_ID)
+ outputName = VACANCYFLUX_isoconc_label
+ thisNoutput => null()
+ thisOutput => null()
+ thisSize => null()
+ case (VACANCYFLUX_isochempot_ID)
+ outputName = VACANCYFLUX_isochempot_label
+ thisNoutput => vacancyflux_isochempot_Noutput
+ thisOutput => vacancyflux_isochempot_output
+ thisSize => vacancyflux_isochempot_sizePostResult
+ case (VACANCYFLUX_cahnhilliard_ID)
+ outputName = VACANCYFLUX_cahnhilliard_label
+ thisNoutput => vacancyflux_cahnhilliard_Noutput
+ thisOutput => vacancyflux_cahnhilliard_output
+ thisSize => vacancyflux_cahnhilliard_sizePostResult
+ case default
+ knownVacancyflux = .false.
+ end select
+ if (knownVacancyflux) then
+ write(FILEUNIT,'(a)') '(vacancyflux)'//char(9)//trim(outputName)
+ if (vacancyflux_type(p) /= VACANCYFLUX_isoconc_ID) then
+ do e = 1,thisNoutput(i)
+ write(FILEUNIT,'(a,i4)') trim(thisOutput(e,i))//char(9),thisSize(e,i)
+ enddo
+ endif
+ endif
+ i = porosity_typeInstance(p) ! which instance of this porosity type
+ knownPorosity = .true. ! assume valid
+ select case(porosity_type(p)) ! split per porosity type
+ case (POROSITY_none_ID)
+ outputName = POROSITY_none_label
+ thisNoutput => null()
+ thisOutput => null()
+ thisSize => null()
+ case (POROSITY_phasefield_ID)
+ outputName = POROSITY_phasefield_label
+ thisNoutput => porosity_phasefield_Noutput
+ thisOutput => porosity_phasefield_output
+ thisSize => porosity_phasefield_sizePostResult
+ case default
+ knownPorosity = .false.
+ end select
+ if (knownPorosity) then
+ write(FILEUNIT,'(a)') '(porosity)'//char(9)//trim(outputName)
+ if (porosity_type(p) /= POROSITY_none_ID) then
+ do e = 1,thisNoutput(i)
+ write(FILEUNIT,'(a,i4)') trim(thisOutput(e,i))//char(9),thisSize(e,i)
+ enddo
+ endif
+ endif
+ i = hydrogenflux_typeInstance(p) ! which instance of this hydrogen flux type
+ knownHydrogenflux = .true. ! assume valid
+ select case(hydrogenflux_type(p)) ! split per hydrogen flux type
+ case (HYDROGENFLUX_isoconc_ID)
+ outputName = HYDROGENFLUX_isoconc_label
+ thisNoutput => null()
+ thisOutput => null()
+ thisSize => null()
+ case (HYDROGENFLUX_cahnhilliard_ID)
+ outputName = HYDROGENFLUX_cahnhilliard_label
+ thisNoutput => hydrogenflux_cahnhilliard_Noutput
+ thisOutput => hydrogenflux_cahnhilliard_output
+ thisSize => hydrogenflux_cahnhilliard_sizePostResult
+ case default
+ knownHydrogenflux = .false.
+ end select
+ if (knownHydrogenflux) then
+ write(FILEUNIT,'(a)') '(hydrogenflux)'//char(9)//trim(outputName)
+ if (hydrogenflux_type(p) /= HYDROGENFLUX_isoconc_ID) then
+ do e = 1,thisNoutput(i)
+ write(FILEUNIT,'(a,i4)') trim(thisOutput(e,i))//char(9),thisSize(e,i)
+ enddo
+ endif
+ endif
endif
enddo
close(FILEUNIT)
@@ -302,24 +405,30 @@ subroutine homogenization_init()
!--------------------------------------------------------------------------------------------------
! allocate and initialize global state and postresutls variables
+#ifdef HDF
elementLooping: do e = 1,mesh_NcpElems
myInstance = homogenization_typeInstance(mesh_element(3,e))
IpLooping: do i = 1,FE_Nips(FE_geomtype(mesh_element(2,e)))
-#ifdef HDF
InstancePosition(myInstance) = InstancePosition(myInstance)+1_pInt
mapping(e,1:4) = [instancePosition(myinstance),myinstance,e,i]
-#endif
enddo IpLooping
enddo elementLooping
-#ifdef HDF
call HDF5_mappingHomogenization(mapping)
#endif
homogenization_maxSizePostResults = 0_pInt
- field_maxSizePostResults = 0_pInt
+ thermal_maxSizePostResults = 0_pInt
+ damage_maxSizePostResults = 0_pInt
+ vacancyflux_maxSizePostResults = 0_pInt
+ porosity_maxSizePostResults = 0_pInt
+ hydrogenflux_maxSizePostResults = 0_pInt
do p = 1,material_Nhomogenization
- homogenization_maxSizePostResults = max(homogenization_maxSizePostResults,homogState(p)%sizePostResults)
- field_maxSizePostResults = max(field_maxSizePostResults,field_sizePostResults(p))
+ homogenization_maxSizePostResults = max(homogenization_maxSizePostResults,homogState (p)%sizePostResults)
+ thermal_maxSizePostResults = max(thermal_maxSizePostResults, thermalState (p)%sizePostResults)
+ damage_maxSizePostResults = max(damage_maxSizePostResults ,damageState (p)%sizePostResults)
+ vacancyflux_maxSizePostResults = max(vacancyflux_maxSizePostResults ,vacancyfluxState (p)%sizePostResults)
+ porosity_maxSizePostResults = max(porosity_maxSizePostResults ,porosityState (p)%sizePostResults)
+ hydrogenflux_maxSizePostResults = max(hydrogenflux_maxSizePostResults ,hydrogenfluxState(p)%sizePostResults)
enddo
#ifdef FEM
@@ -327,7 +436,12 @@ subroutine homogenization_init()
allocate(crystalliteOutput(material_Ncrystallite, homogenization_maxNgrains))
allocate(phaseOutput (material_Nphase, homogenization_maxNgrains))
do p = 1, material_Nhomogenization
- homogOutput(p)%sizeResults = homogState(p)%sizePostResults + field_sizePostResults(p)
+ homogOutput(p)%sizeResults = homogState (p)%sizePostResults + &
+ thermalState (p)%sizePostResults + &
+ damageState (p)%sizePostResults + &
+ vacancyfluxState (p)%sizePostResults + &
+ porosityState (p)%sizePostResults + &
+ hydrogenfluxState(p)%sizePostResults
homogOutput(p)%sizeIpCells = count(material_homog==p)
allocate(homogOutput(p)%output(homogOutput(p)%sizeResults,homogOutput(p)%sizeIpCells))
enddo
@@ -338,22 +452,22 @@ subroutine homogenization_init()
allocate(crystalliteOutput(p,e)%output(crystalliteOutput(p,e)%sizeResults,crystalliteOutput(p,e)%sizeIpCells))
enddo; enddo
do p = 1, material_Nphase; do e = 1, homogenization_maxNgrains
- phaseOutput(p,e)%sizeResults = plasticState(p)%sizePostResults + &
- damageState (p)%sizePostResults + &
- thermalState(p)%sizePostResults + &
- vacancyState(p)%sizePostResults
+ phaseOutput(p,e)%sizeResults = plasticState (p)%sizePostResults + &
+ sum(sourceState (p)%p(:)%sizePostResults)
phaseOutput(p,e)%sizeIpCells = count(material_phase(e,:,:) == p)
allocate(phaseOutput(p,e)%output(phaseOutput(p,e)%sizeResults,phaseOutput(p,e)%sizeIpCells))
enddo; enddo
#else
materialpoint_sizeResults = 1 & ! grain count
+ 1 + homogenization_maxSizePostResults & ! homogSize & homogResult
- + field_maxSizePostResults & ! field size & field result
+ + thermal_maxSizePostResults &
+ + damage_maxSizePostResults &
+ + vacancyflux_maxSizePostResults &
+ + porosity_maxSizePostResults &
+ + hydrogenflux_maxSizePostResults &
+ homogenization_maxNgrains * (1 + crystallite_maxSizePostResults & ! crystallite size & crystallite results
- + 1 + constitutive_maxSizePostResults & ! constitutive size & constitutive results
- + constitutive_damage_maxSizePostResults &
- + constitutive_thermal_maxSizePostResults &
- + constitutive_vacancy_maxSizePostResults)
+ + 1 + constitutive_plasticity_maxSizePostResults & ! constitutive size & constitutive results
+ + constitutive_source_maxSizePostResults)
allocate(materialpoint_results(materialpoint_sizeResults,mesh_maxNips,mesh_NcpElems))
#endif
@@ -415,10 +529,14 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
mesh_element
use material, only: &
plasticState, &
- damageState, &
- thermalState, &
- vacancyState, &
+ sourceState, &
homogState, &
+ thermalState, &
+ damageState, &
+ vacancyfluxState, &
+ porosityState, &
+ hydrogenfluxState, &
+ phase_Nsources, &
mappingHomogenization, &
mappingConstitutive, &
homogenization_Ngrains
@@ -472,6 +590,7 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
g, & !< grain number
i, & !< integration point number
e, & !< element number
+ mySource, &
myNgrains
!--------------------------------------------------------------------------------------------------
@@ -491,16 +610,14 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
! initialize restoration points of ...
do e = FEsolving_execElem(1),FEsolving_execElem(2)
myNgrains = homogenization_Ngrains(mesh_element(3,e))
- forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), g = 1:myNgrains)
+ do i = FEsolving_execIP(1,e),FEsolving_execIP(2,e); do g = 1,myNgrains
- plasticState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%state0( :,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%state0( :,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%state0( :,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%state0( :,mappingConstitutive(1,g,i,e))
+ plasticState (mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%state0( :,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state0( :,mappingConstitutive(1,g,i,e))
+ enddo
crystallite_partionedFp0(1:3,1:3,g,i,e) = crystallite_Fp0(1:3,1:3,g,i,e) ! ...plastic def grads
crystallite_partionedLp0(1:3,1:3,g,i,e) = crystallite_Lp0(1:3,1:3,g,i,e) ! ...plastic velocity grads
@@ -510,7 +627,7 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
crystallite_partionedF0(1:3,1:3,g,i,e) = crystallite_F0(1:3,1:3,g,i,e) ! ...def grads
crystallite_partionedTstar0_v(1:6,g,i,e) = crystallite_Tstar0_v(1:6,g,i,e) ! ...2nd PK stress
- endforall
+ enddo; enddo
forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e))
materialpoint_subF0(1:3,1:3,i,e) = materialpoint_F0(1:3,1:3,i,e) ! ...def grad
materialpoint_subFrac(i,e) = 0.0_pReal
@@ -521,7 +638,27 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
homogState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
homogState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
- homogState(mappingHomogenization(2,i,e))%State0( :,mappingHomogenization(1,i,e)) ! ...internal homogenization state
+ homogState(mappingHomogenization(2,i,e))%State0( :,mappingHomogenization(1,i,e)) ! ...internal homogenization state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ thermalState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ thermalState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ thermalState(mappingHomogenization(2,i,e))%State0( :,mappingHomogenization(1,i,e)) ! ...internal thermal state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ damageState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ damageState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ damageState(mappingHomogenization(2,i,e))%State0( :,mappingHomogenization(1,i,e)) ! ...internal damage state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ vacancyfluxState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ vacancyfluxState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ vacancyfluxState(mappingHomogenization(2,i,e))%State0( :,mappingHomogenization(1,i,e)) ! ...internal vacancy transport state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ porosityState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ porosityState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ porosityState(mappingHomogenization(2,i,e))%State0( :,mappingHomogenization(1,i,e)) ! ...internal porosity state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ hydrogenfluxState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ hydrogenfluxState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ hydrogenfluxState(mappingHomogenization(2,i,e))%State0( :,mappingHomogenization(1,i,e)) ! ...internal hydrogen transport state
enddo
NiterationHomog = 0_pInt
@@ -549,35 +686,61 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
materialpoint_subFrac(i,e) = materialpoint_subFrac(i,e) + materialpoint_subStep(i,e)
!$OMP FLUSH(materialpoint_subFrac)
materialpoint_subStep(i,e) = min(1.0_pReal-materialpoint_subFrac(i,e), &
- stepIncreaseHomog*materialpoint_subStep(i,e)) ! introduce flexibility for step increase/acceleration
+ stepIncreaseHomog*materialpoint_subStep(i,e)) ! introduce flexibility for step increase/acceleration
!$OMP FLUSH(materialpoint_subStep)
steppingNeeded: if (materialpoint_subStep(i,e) > subStepMinHomog) then
! wind forward grain starting point of...
- crystallite_partionedF0(1:3,1:3,1:myNgrains,i,e) = crystallite_partionedF(1:3,1:3,1:myNgrains,i,e) ! ...def grads
- crystallite_partionedFp0(1:3,1:3,1:myNgrains,i,e) = crystallite_Fp(1:3,1:3,1:myNgrains,i,e) ! ...plastic def grads
- crystallite_partionedLp0(1:3,1:3,1:myNgrains,i,e) = crystallite_Lp(1:3,1:3,1:myNgrains,i,e) ! ...plastic velocity grads
- crystallite_partionedFi0(1:3,1:3,1:myNgrains,i,e) = crystallite_Fi(1:3,1:3,1:myNgrains,i,e) ! ...intermediate def grads
- crystallite_partionedLi0(1:3,1:3,1:myNgrains,i,e) = crystallite_Li(1:3,1:3,1:myNgrains,i,e) ! ...intermediate velocity grads
- crystallite_partioneddPdF0(1:3,1:3,1:3,1:3,1:myNgrains,i,e) = crystallite_dPdF(1:3,1:3,1:3,1:3,1:myNgrains,i,e)! ...stiffness
- crystallite_partionedTstar0_v(1:6,1:myNgrains,i,e) = crystallite_Tstar_v(1:6,1:myNgrains,i,e) ! ...2nd PK stress
- forall (g = 1:myNgrains)
- plasticState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
- end forall
- if (homogState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
- homogState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
- homogState(mappingHomogenization(2,i,e))%state( :,mappingHomogenization(1,i,e))
- materialpoint_subF0(1:3,1:3,i,e) = materialpoint_subF(1:3,1:3,i,e) ! ...def grad
+ crystallite_partionedF0(1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_partionedF(1:3,1:3,1:myNgrains,i,e) ! ...def grads
+ crystallite_partionedFp0(1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_Fp(1:3,1:3,1:myNgrains,i,e) ! ...plastic def grads
+ crystallite_partionedLp0(1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_Lp(1:3,1:3,1:myNgrains,i,e) ! ...plastic velocity grads
+ crystallite_partionedFi0(1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_Fi(1:3,1:3,1:myNgrains,i,e) ! ...intermediate def grads
+ crystallite_partionedLi0(1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_Li(1:3,1:3,1:myNgrains,i,e) ! ...intermediate velocity grads
+ crystallite_partioneddPdF0(1:3,1:3,1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_dPdF(1:3,1:3,1:3,1:3,1:myNgrains,i,e) ! ...stiffness
+ crystallite_partionedTstar0_v(1:6,1:myNgrains,i,e) = &
+ crystallite_Tstar_v(1:6,1:myNgrains,i,e) ! ...2nd PK stress
+ do g = 1,myNgrains
+ plasticState (mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%partionedState0(:,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state( :,mappingConstitutive(1,g,i,e))
+ enddo
+ enddo
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ homogState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ homogState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ homogState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e)) ! ...internal homogenization state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ thermalState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ thermalState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ thermalState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e)) ! ...internal thermal state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ damageState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ damageState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ damageState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e)) ! ...internal damage state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ vacancyfluxState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ vacancyfluxState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ vacancyfluxState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e))! ...internal vacancy transport state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ porosityState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ porosityState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ porosityState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e))! ...internal porosity state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ hydrogenfluxState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ hydrogenfluxState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) = &
+ hydrogenfluxState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e))! ...internal hydrogen transport state
+ materialpoint_subF0(1:3,1:3,i,e) = materialpoint_subF(1:3,1:3,i,e) ! ...def grad
!$OMP FLUSH(materialpoint_subF0)
- elseif (materialpoint_requested(i,e)) then steppingNeeded ! already at final time (??)
+ elseif (materialpoint_requested(i,e)) then steppingNeeded ! already at final time (??)
if (iand(debug_level(debug_homogenization), debug_levelBasic) /= 0_pInt) then
!$OMP CRITICAL (distributionHomog)
debug_MaterialpointLoopDistribution(min(nHomog+1,NiterationHomog)) = &
@@ -587,20 +750,20 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
endif steppingNeeded
else converged
- if ( (myNgrains == 1_pInt .and. materialpoint_subStep(i,e) <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite
- subStepSizeHomog * materialpoint_subStep(i,e) <= subStepMinHomog ) then ! would require too small subStep
- ! cutback makes no sense
+ if ( (myNgrains == 1_pInt .and. materialpoint_subStep(i,e) <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite
+ subStepSizeHomog * materialpoint_subStep(i,e) <= subStepMinHomog ) then ! would require too small subStep
+ ! cutback makes no sense
!$OMP FLUSH(terminallyIll)
- if (.not. terminallyIll) then ! so first signals terminally ill...
+ if (.not. terminallyIll) then ! so first signals terminally ill...
!$OMP CRITICAL (write2out)
write(6,*) 'Integration point ', i,' at element ', e, ' terminally ill'
!$OMP END CRITICAL (write2out)
endif
!$OMP CRITICAL (setTerminallyIll)
- terminallyIll = .true. ! ...and kills all others
+ terminallyIll = .true. ! ...and kills all others
!$OMP END CRITICAL (setTerminallyIll)
- else ! cutback makes sense
- materialpoint_subStep(i,e) = subStepSizeHomog * materialpoint_subStep(i,e) ! crystallite had severe trouble, so do a significant cutback
+ else ! cutback makes sense
+ materialpoint_subStep(i,e) = subStepSizeHomog * materialpoint_subStep(i,e) ! crystallite had severe trouble, so do a significant cutback
!$OMP FLUSH(materialpoint_subStep)
#ifndef _OPENMP
@@ -615,25 +778,50 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
!--------------------------------------------------------------------------------------------------
! restore...
- crystallite_Fp(1:3,1:3,1:myNgrains,i,e) = crystallite_partionedFp0(1:3,1:3,1:myNgrains,i,e) ! ...plastic def grads
- crystallite_Lp(1:3,1:3,1:myNgrains,i,e) = crystallite_partionedLp0(1:3,1:3,1:myNgrains,i,e) ! ...plastic velocity grads
- crystallite_Fi(1:3,1:3,1:myNgrains,i,e) = crystallite_partionedFi0(1:3,1:3,1:myNgrains,i,e) ! ...intermediate def grads
- crystallite_Li(1:3,1:3,1:myNgrains,i,e) = crystallite_partionedLi0(1:3,1:3,1:myNgrains,i,e) ! ...intermediate velocity grads
- crystallite_dPdF(1:3,1:3,1:3,1:3,1:myNgrains,i,e) = crystallite_partioneddPdF0(1:3,1:3,1:3,1:3,1:myNgrains,i,e) ! ...stiffness
- crystallite_Tstar_v(1:6,1:myNgrains,i,e) = crystallite_partionedTstar0_v(1:6,1:myNgrains,i,e) ! ...2nd PK stress
- forall (g = 1:myNgrains)
- plasticState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- plasticState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e))
- damageState( mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- damageState( mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e))
- thermalState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- thermalState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e))
- vacancyState(mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
- vacancyState(mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e))
- end forall
- if (homogState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
- homogState(mappingHomogenization(2,i,e))%state( :,mappingHomogenization(1,i,e)) = &
- homogState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e))
+ crystallite_Fp(1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_partionedFp0(1:3,1:3,1:myNgrains,i,e) ! ...plastic def grads
+ crystallite_Lp(1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_partionedLp0(1:3,1:3,1:myNgrains,i,e) ! ...plastic velocity grads
+ crystallite_Fi(1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_partionedFi0(1:3,1:3,1:myNgrains,i,e) ! ...intermediate def grads
+ crystallite_Li(1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_partionedLi0(1:3,1:3,1:myNgrains,i,e) ! ...intermediate velocity grads
+ crystallite_dPdF(1:3,1:3,1:3,1:3,1:myNgrains,i,e) = &
+ crystallite_partioneddPdF0(1:3,1:3,1:3,1:3,1:myNgrains,i,e) ! ...stiffness
+ crystallite_Tstar_v(1:6,1:myNgrains,i,e) = &
+ crystallite_partionedTstar0_v(1:6,1:myNgrains,i,e) ! ...2nd PK stress
+ do g = 1, myNgrains
+ plasticState (mappingConstitutive(2,g,i,e))%state( :,mappingConstitutive(1,g,i,e)) = &
+ plasticState (mappingConstitutive(2,g,i,e))%partionedState0(:,mappingConstitutive(1,g,i,e))
+ do mySource = 1_pInt, phase_Nsources(mappingConstitutive(2,g,i,e))
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%state( :,mappingConstitutive(1,g,i,e)) = &
+ sourceState(mappingConstitutive(2,g,i,e))%p(mySource)%partionedState0(:,mappingConstitutive(1,g,i,e))
+ enddo
+ enddo
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ homogState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ homogState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e)) = &
+ homogState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) ! ...internal homogenization state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ thermalState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ thermalState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e)) = &
+ thermalState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) ! ...internal thermal state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ damageState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ damageState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e)) = &
+ damageState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e)) ! ...internal damage state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ vacancyfluxState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ vacancyfluxState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e)) = &
+ vacancyfluxState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e))! ...internal vacancy transport state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ porosityState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ porosityState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e)) = &
+ porosityState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e))! ...internal porosity state
+ forall(i = FEsolving_execIP(1,e):FEsolving_execIP(2,e), &
+ hydrogenfluxState(mappingHomogenization(2,i,e))%sizeState > 0_pInt) &
+ hydrogenfluxState(mappingHomogenization(2,i,e))%State( :,mappingHomogenization(1,i,e)) = &
+ hydrogenfluxState(mappingHomogenization(2,i,e))%subState0(:,mappingHomogenization(1,i,e))! ...internal hydrogen transport state
endif
endif converged
@@ -695,7 +883,7 @@ subroutine materialpoint_stressAndItsTangent(updateJaco,dt)
materialpoint_converged(i,e) = .false.
else
materialpoint_doneAndHappy(1:2,i,e) = homogenization_updateState(i,e)
- materialpoint_converged(i,e) = all(homogenization_updateState(i,e)) ! converged if done and happy
+ materialpoint_converged(i,e) = all(materialpoint_doneAndHappy(1:2,i,e)) ! converged if done and happy
endif
!$OMP FLUSH(materialpoint_converged)
if (materialpoint_converged(i,e)) then
@@ -751,21 +939,23 @@ subroutine materialpoint_postResults
homogenization_maxNgrains, &
material_Ncrystallite, &
material_Nphase, &
-#endif
+#else
homogState, &
- plasticState, &
- damageState, &
thermalState, &
- vacancyState, &
+ damageState, &
+ vacancyfluxState, &
+ porosityState, &
+ hydrogenfluxState, &
+#endif
+ plasticState, &
+ sourceState, &
material_phase, &
homogenization_Ngrains, &
microstructure_crystallite
use constitutive, only: &
#ifdef FEM
- constitutive_maxSizePostResults, &
- constitutive_damage_maxSizePostResults, &
- constitutive_thermal_maxSizePostResults, &
- constitutive_vacancy_maxSizePostResults, &
+ constitutive_plasticity_maxSizePostResults, &
+ constitutive_source_maxSizePostResults, &
#endif
constitutive_postResults
use crystallite, only: &
@@ -791,10 +981,8 @@ subroutine materialpoint_postResults
crystalliteCtr(material_Ncrystallite, homogenization_maxNgrains), &
phaseCtr (material_Nphase, homogenization_maxNgrains)
real(pReal), dimension(1+crystallite_maxSizePostResults + &
- 1+constitutive_maxSizePostResults + &
- constitutive_damage_maxSizePostResults + &
- constitutive_thermal_maxSizePostResults + &
- constitutive_vacancy_maxSizePostResults) :: &
+ 1+constitutive_plasticity_maxSizePostResults + &
+ constitutive_source_maxSizePostResults) :: &
crystalliteResults
@@ -807,35 +995,29 @@ subroutine materialpoint_postResults
myHomog = mappingHomogenization(2,i,e)
thePos = mappingHomogenization(1,i,e)
homogOutput(myHomog)%output(1: &
- homogState(myHomog)%sizePostResults, &
+ homogOutput(myHomog)%sizeResults, &
thePos) = homogenization_postResults(i,e)
- homogOutput(myHomog)%output(homogState(myHomog)%sizePostResults+1: &
- homogState(myHomog)%sizePostResults+field_sizePostResults(myHomog), &
- thePos) = field_postResults(i,e)
grainLooping :do g = 1,myNgrains
myPhase = mappingConstitutive(2,g,i,e)
crystalliteResults(1:1+crystallite_sizePostResults(myCrystallite) + &
1+plasticState(myPhase)%sizePostResults + &
- damageState (myPhase)%sizePostResults + &
- thermalState(myPhase)%sizePostResults + &
- vacancyState(myPhase)%sizePostResults) = crystallite_postResults(g,i,e)
+ sum(sourceState(myPhase)%p(:)%sizePostResults)) = crystallite_postResults(g,i,e)
if (microstructure_crystallite(mesh_element(4,e)) == myCrystallite .and. &
homogenization_Ngrains (mesh_element(3,e)) >= g) then
crystalliteCtr(myCrystallite,g) = crystalliteCtr(myCrystallite,g) + 1_pInt
crystalliteOutput(myCrystallite,g)% &
output(1:crystalliteOutput(myCrystallite,g)%sizeResults,crystalliteCtr(myCrystallite,g)) = &
- crystalliteResults(2:1+crystallite_sizePostResults(myCrystallite))
+ crystalliteResults(2:1+crystalliteOutput(myCrystallite,g)%sizeResults)
endif
if (material_phase(g,i,e) == myPhase) then
phaseCtr(myPhase,g) = phaseCtr(myPhase,g) + 1_pInt
phaseOutput(myPhase,g)% &
output(1:phaseOutput(myPhase,g)%sizeResults,phaseCtr(myPhase,g)) = &
- crystalliteResults(3 + crystallite_sizePostResults(myCrystallite): &
- plasticState(myphase)%sizePostResults + &
- damageState (myphase)%sizePostResults + &
- thermalState(myphase)%sizePostResults + &
- vacancyState(myphase)%sizePostResults)
+ crystalliteResults(3 + crystalliteOutput(myCrystallite,g)%sizeResults: &
+ 1 + crystalliteOutput(myCrystallite,g)%sizeResults + &
+ 1 + plasticState (myphase)%sizePostResults + &
+ sum(sourceState(myphase)%p(:)%sizePostResults))
endif
enddo grainLooping
enddo IpLooping
@@ -849,7 +1031,12 @@ subroutine materialpoint_postResults
IpLooping: do i = FEsolving_execIP(1,e),FEsolving_execIP(2,e)
thePos = 0_pInt
- theSize = homogState(mappingHomogenization(2,i,e))%sizePostResults
+ theSize = homogState (mappingHomogenization(2,i,e))%sizePostResults &
+ + thermalState (mappingHomogenization(2,i,e))%sizePostResults &
+ + damageState (mappingHomogenization(2,i,e))%sizePostResults &
+ + vacancyfluxState (mappingHomogenization(2,i,e))%sizePostResults &
+ + porosityState (mappingHomogenization(2,i,e))%sizePostResults &
+ + hydrogenfluxState(mappingHomogenization(2,i,e))%sizePostResults
materialpoint_results(thePos+1,i,e) = real(theSize,pReal) ! tell size of homogenization results
thePos = thePos + 1_pInt
@@ -858,21 +1045,13 @@ subroutine materialpoint_postResults
thePos = thePos + theSize
endif
- theSize = field_sizePostResults(mappingHomogenization(2,i,e))
- if (theSize > 0_pInt) then ! any homogenization results to mention?
- materialpoint_results(thePos+1:thePos+theSize,i,e) = field_postResults(i,e) ! tell field results
- thePos = thePos + theSize
- endif
-
materialpoint_results(thePos+1,i,e) = real(myNgrains,pReal) ! tell number of grains at materialpoint
thePos = thePos + 1_pInt
grainLooping :do g = 1,myNgrains
theSize = 1 + crystallite_sizePostResults(myCrystallite) + &
- 1 + plasticState(material_phase(g,i,e))%sizePostResults + & !ToDo
- damageState(material_phase(g,i,e))%sizePostResults + &
- thermalState(material_phase(g,i,e))%sizePostResults + &
- vacancyState(material_phase(g,i,e))%sizePostResults
+ 1 + plasticState (material_phase(g,i,e))%sizePostResults + & !ToDo
+ sum(sourceState(material_phase(g,i,e))%p(:)%sizePostResults)
materialpoint_results(thePos+1:thePos+theSize,i,e) = crystallite_postResults(g,i,e) ! tell crystallite results
thePos = thePos + theSize
enddo grainLooping
@@ -940,8 +1119,14 @@ function homogenization_updateState(ip,el)
mesh_element
use material, only: &
homogenization_type, &
+ thermal_type, &
+ damage_type, &
+ vacancyflux_type, &
homogenization_maxNgrains, &
- HOMOGENIZATION_RGC_ID
+ HOMOGENIZATION_RGC_ID, &
+ THERMAL_adiabatic_ID, &
+ DAMAGE_local_ID, &
+ VACANCYFLUX_isochempot_ID
use crystallite, only: &
crystallite_P, &
crystallite_dPdF, &
@@ -949,6 +1134,12 @@ function homogenization_updateState(ip,el)
crystallite_partionedF0
use homogenization_RGC, only: &
homogenization_RGC_updateState
+ use thermal_adiabatic, only: &
+ thermal_adiabatic_updateState
+ use damage_local, only: &
+ damage_local_updateState
+ use vacancyflux_isochempot, only: &
+ vacancyflux_isochempot_updateState
implicit none
integer(pInt), intent(in) :: &
@@ -956,23 +1147,60 @@ function homogenization_updateState(ip,el)
el !< element number
logical, dimension(2) :: homogenization_updateState
+ homogenization_updateState = .true.
chosenHomogenization: select case(homogenization_type(mesh_element(3,el)))
-
case (HOMOGENIZATION_RGC_ID) chosenHomogenization
homogenization_updateState = &
-
+ homogenization_updateState .and. &
homogenization_RGC_updateState(crystallite_P(1:3,1:3,1:homogenization_maxNgrains,ip,el), &
- crystallite_partionedF(1:3,1:3,1:homogenization_maxNgrains,ip,el), &
- crystallite_partionedF0(1:3,1:3,1:homogenization_maxNgrains,ip,el),&
- materialpoint_subF(1:3,1:3,ip,el),&
- materialpoint_subdt(ip,el), &
- crystallite_dPdF(1:3,1:3,1:3,1:3,1:homogenization_maxNgrains,ip,el), &
- ip, &
- el)
+ crystallite_partionedF(1:3,1:3,1:homogenization_maxNgrains,ip,el), &
+ crystallite_partionedF0(1:3,1:3,1:homogenization_maxNgrains,ip,el),&
+ materialpoint_subF(1:3,1:3,ip,el),&
+ materialpoint_subdt(ip,el), &
+ crystallite_dPdF(1:3,1:3,1:3,1:3,1:homogenization_maxNgrains,ip,el), &
+ ip, &
+ el)
case default chosenHomogenization
- homogenization_updateState = .true.
+ homogenization_updateState = &
+ homogenization_updateState .and. [.true., .true.]
end select chosenHomogenization
+ chosenThermal: select case (thermal_type(mesh_element(3,el)))
+ case (THERMAL_adiabatic_ID) chosenThermal
+ homogenization_updateState = &
+ homogenization_updateState .and. &
+ thermal_adiabatic_updateState(materialpoint_subdt(ip,el), &
+ ip, &
+ el)
+ case default chosenThermal
+ homogenization_updateState = &
+ homogenization_updateState .and. [.true., .true.]
+ end select chosenThermal
+
+ chosenDamage: select case (damage_type(mesh_element(3,el)))
+ case (DAMAGE_local_ID) chosenDamage
+ homogenization_updateState = &
+ homogenization_updateState .and. &
+ damage_local_updateState(materialpoint_subdt(ip,el), &
+ ip, &
+ el)
+ case default chosenDamage
+ homogenization_updateState = &
+ homogenization_updateState .and. [.true., .true.]
+ end select chosenDamage
+
+ chosenVacancyflux: select case (vacancyflux_type(mesh_element(3,el)))
+ case (VACANCYFLUX_isochempot_ID) chosenVacancyflux
+ homogenization_updateState = &
+ homogenization_updateState .and. &
+ vacancyflux_isochempot_updateState(materialpoint_subdt(ip,el), &
+ ip, &
+ el)
+ case default chosenVacancyflux
+ homogenization_updateState = &
+ homogenization_updateState .and. [.true., .true.]
+ end select chosenVacancyflux
+
end function homogenization_updateState
@@ -1023,557 +1251,6 @@ subroutine homogenization_averageStressAndItsTangent(ip,el)
end subroutine homogenization_averageStressAndItsTangent
-!--------------------------------------------------------------------------------------------------
-!> @brief Returns average specific heat at each integration point
-!--------------------------------------------------------------------------------------------------
-function field_getSpecificHeat(ip,el)
- use mesh, only: &
- mesh_element
- use lattice, only: &
- lattice_specificHeat
- use material, only: &
- material_phase, &
- material_homog, &
- field_thermal_type, &
- FIELD_THERMAL_local_ID, &
- FIELD_THERMAL_nonlocal_ID, &
- homogenization_Ngrains
-
- implicit none
- real(pReal) :: field_getSpecificHeat
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
- field_getSpecificHeat =0.0_pReal
-
- select case(field_thermal_type(material_homog(ip,el)))
-
- case (FIELD_THERMAL_local_ID)
- field_getSpecificHeat = 0.0_pReal
-
- case (FIELD_THERMAL_nonlocal_ID)
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getSpecificHeat = field_getSpecificHeat + lattice_specificHeat(material_phase(ipc,ip,el))
- enddo
-
- end select
-
- field_getSpecificHeat = field_getSpecificHeat /homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getSpecificHeat
-
-!--------------------------------------------------------------------------------------------------
-!> @brief Returns average mass density at each integration point
-!--------------------------------------------------------------------------------------------------
-function field_getMassDensity(ip,el)
- use mesh, only: &
- mesh_element
- use lattice, only: &
- lattice_massDensity
- use material, only: &
- material_phase, &
- material_homog, &
- field_thermal_type, &
- FIELD_THERMAL_local_ID, &
- FIELD_THERMAL_nonlocal_ID, &
- homogenization_Ngrains
-
-
- implicit none
- real(pReal) :: field_getMassDensity
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
- field_getMassDensity =0.0_pReal
-
- select case(field_thermal_type(material_homog(ip,el)))
-
- case (FIELD_THERMAL_local_ID)
- field_getMassDensity = 0.0_pReal
-
- case (FIELD_THERMAL_nonlocal_ID)
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getMassDensity = field_getMassDensity + lattice_massDensity(material_phase(ipc,ip,el))
- enddo
-
- end select
-
- field_getMassDensity = field_getMassDensity /homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getMassDensity
-!-------------------------------------------------------------------------------------------
-!> @brief Returns average conductivity tensor for thermal field at each integration point
-!-------------------------------------------------------------------------------------------
-function field_getThermalConductivity33(ip,el)
- use mesh, only: &
- mesh_element
- use lattice, only: &
- lattice_thermalConductivity33
- use material, only: &
- material_phase, &
- material_homog, &
- field_thermal_type, &
- FIELD_THERMAL_nonlocal_ID, &
- homogenization_Ngrains
- use crystallite, only: &
- crystallite_push33ToRef
-
-
- implicit none
- real(pReal), dimension(3,3) :: field_getThermalConductivity33
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
- field_getThermalConductivity33 =0.0_pReal
-
- select case(field_thermal_type(material_homog(ip,el)))
- case (FIELD_THERMAL_nonlocal_ID)
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getThermalConductivity33 = field_getThermalConductivity33 + &
- crystallite_push33ToRef(ipc,ip,el,lattice_thermalConductivity33(:,:,material_phase(ipc,ip,el)))
- enddo
-
- end select
-
- field_getThermalConductivity33 = field_getThermalConductivity33 /homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getThermalConductivity33
-!--------------------------------------------------------------------------------------------------
-!> @brief Returns average diffusion tensor for damage field at each integration point
-!--------------------------------------------------------------------------------------------------
-function field_getDamageDiffusion33(ip,el)
- use mesh, only: &
- mesh_element
- use material, only: &
- material_homog, &
- field_damage_type, &
- FIELD_DAMAGE_NONLOCAL_ID, &
- homogenization_Ngrains
- use crystallite, only: &
- crystallite_push33ToRef
- use constitutive, only: &
- constitutive_getDamageDiffusion33
-
- implicit none
- real(pReal), dimension(3,3) :: field_getDamageDiffusion33
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
- field_getDamageDiffusion33 =0.0_pReal
-
- select case(field_damage_type(material_homog(ip,el)))
- case (FIELD_DAMAGE_NONLOCAL_ID)
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getDamageDiffusion33 = field_getDamageDiffusion33 + &
- crystallite_push33ToRef(ipc,ip,el,constitutive_getDamageDiffusion33(ipc,ip,el))
- enddo
-
- end select
-
- field_getDamageDiffusion33 = field_getDamageDiffusion33 /homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getDamageDiffusion33
-
-!--------------------------------------------------------------------------------------------------
-!> @brief Returns average mobility for damage field at each integration point
-!--------------------------------------------------------------------------------------------------
-real(pReal) function field_getDamageMobility(ip,el)
- use mesh, only: &
- mesh_element
- use lattice, only: &
- lattice_damageMobility
- use material, only: &
- material_phase, &
- material_homog, &
- field_damage_type, &
- FIELD_DAMAGE_NONLOCAL_ID, &
- homogenization_Ngrains
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
- field_getDamageMobility =0.0_pReal
-
- select case(field_damage_type(material_homog(ip,el)))
- case (FIELD_DAMAGE_NONLOCAL_ID)
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getDamageMobility = field_getDamageMobility + lattice_DamageMobility(material_phase(ipc,ip,el))
- enddo
-
- end select
-
- field_getDamageMobility = field_getDamageMobility /homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getDamageMobility
-
-!--------------------------------------------------------------------------------------------------
-!> @brief Returns average diffusion tensor for vacancy field at each integration point
-!--------------------------------------------------------------------------------------------------
-function field_getVacancyDiffusion33(ip,el)
- use mesh, only: &
- mesh_element
- use material, only: &
- material_homog, &
- field_vacancy_type, &
- FIELD_VACANCY_NONLOCAL_ID, &
- homogenization_Ngrains
- use crystallite, only: &
- crystallite_push33ToRef
- use constitutive, only: &
- constitutive_getVacancyDiffusion33
-
- implicit none
- real(pReal), dimension(3,3) :: field_getVacancyDiffusion33
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
- field_getVacancyDiffusion33 = 0.0_pReal
-
- select case(field_vacancy_type(material_homog(ip,el)))
- case (FIELD_VACANCY_NONLOCAL_ID)
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getVacancyDiffusion33 = field_getVacancyDiffusion33 + &
- crystallite_push33ToRef(ipc,ip,el, &
- constitutive_getVacancyDiffusion33(ipc,ip,el))
- enddo
-
- end select
-
- field_getVacancyDiffusion33 = field_getVacancyDiffusion33/ &
- homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getVacancyDiffusion33
-
-!--------------------------------------------------------------------------------------------------
-!> @brief Returns average mobility for vacancy field at each integration point
-!--------------------------------------------------------------------------------------------------
-function field_getVacancyMobility33(ip,el)
- use mesh, only: &
- mesh_element
- use material, only: &
- material_homog, &
- field_vacancy_type, &
- FIELD_VACANCY_NONLOCAL_ID, &
- homogenization_Ngrains
- use crystallite, only: &
- crystallite_push33ToRef
- use constitutive, only: &
- constitutive_getVacancyMobility33
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- real(pReal), dimension(3,3) :: &
- field_getVacancyMobility33
- integer(pInt) :: &
- ipc
-
-
- field_getVacancyMobility33 = 0.0_pReal
-
- select case(field_vacancy_type(material_homog(ip,el)))
- case (FIELD_VACANCY_NONLOCAL_ID)
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getVacancyMobility33 = field_getVacancyMobility33 + &
- crystallite_push33ToRef(ipc,ip,el, &
- constitutive_getVacancyMobility33(ipc,ip,el))
- enddo
-
- end select
-
- field_getVacancyMobility33 = field_getVacancyMobility33/ &
- homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getVacancyMobility33
-
-!--------------------------------------------------------------------------------------------------
-!> @brief Returns average driving for vacancy chemical potential at each integration point
-!--------------------------------------------------------------------------------------------------
-real(pReal) function field_getVacancyEnergy(ip,el)
- use mesh, only: &
- mesh_element
- use material, only: &
- material_homog, &
- field_vacancy_type, &
- FIELD_VACANCY_NONLOCAL_ID, &
- homogenization_Ngrains
- use constitutive, only: &
- constitutive_getVacancyEnergy
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
-
- field_getVacancyEnergy = 0.0_pReal
-
- select case(field_vacancy_type(material_homog(ip,el)))
- case (FIELD_VACANCY_NONLOCAL_ID)
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getVacancyEnergy = field_getVacancyEnergy + &
- constitutive_getVacancyEnergy(ipc,ip,el)
- enddo
-
- end select
-
- field_getVacancyEnergy = field_getVacancyEnergy/ &
- homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getVacancyEnergy
-
-!--------------------------------------------------------------------------------------------------
-!> @brief ToDo
-!--------------------------------------------------------------------------------------------------
-real(pReal) function field_getLocalDamage(ip,el)
- use mesh, only: &
- mesh_element
- use material, only: &
- homogenization_Ngrains
- use constitutive, only: &
- constitutive_getLocalDamage
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
-!--------------------------------------------------------------------------------------------------
-! computing the damage value needed to be passed to field solver
- field_getLocalDamage =0.0_pReal
-
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getLocalDamage = field_getLocalDamage + constitutive_getLocalDamage(ipc,ip,el)
- enddo
-
- field_getLocalDamage = field_getLocalDamage/homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getLocalDamage
-
-!--------------------------------------------------------------------------------------------------
-!> @brief ToDo
-!--------------------------------------------------------------------------------------------------
-real(pReal) function field_getFieldDamage(ip,el)
- use mesh, only: &
- mesh_element
- use material, only: &
- homogenization_Ngrains
- use constitutive, only: &
- constitutive_getDamage
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
-!--------------------------------------------------------------------------------------------------
-! computing the damage value needed to be passed to field solver
- field_getFieldDamage = 0.0_pReal
-
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getFieldDamage = field_getFieldDamage + constitutive_getDamage(ipc,ip,el)
- enddo
-
- field_getFieldDamage = field_getFieldDamage/homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getFieldDamage
-
-!--------------------------------------------------------------------------------------------------
-!> @brief Sets the regularised damage value in field state
-!--------------------------------------------------------------------------------------------------
-subroutine field_putFieldDamage(ip,el,fieldDamageValue) ! naming scheme
- use material, only: &
- fieldDamage, &
- material_homog, &
- mappingHomogenization, &
- field_damage_type, &
- FIELD_DAMAGE_NONLOCAL_ID
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el
- real(pReal), intent(in) :: &
- fieldDamageValue
-
- select case(field_damage_type(material_homog(ip,el)))
- case (FIELD_DAMAGE_NONLOCAL_ID)
- fieldDamage(material_homog(ip,el))% &
- field(1, mappingHomogenization(1,ip,el)) = fieldDamageValue
-
- end select
-
-end subroutine field_putFieldDamage
-
-!--------------------------------------------------------------------------------------------------
-!> @brief ToDo
-!--------------------------------------------------------------------------------------------------
-real(pReal) function field_getLocalTemperature(ip,el)
- use mesh, only: &
- mesh_element
- use material, only: &
- homogenization_Ngrains
- use constitutive, only: &
- constitutive_getAdiabaticTemperature
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
-
- field_getLocalTemperature = 0.0_pReal
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getLocalTemperature = field_getLocalTemperature + &
- constitutive_getAdiabaticTemperature(ipc,ip,el) ! array/function/subroutine which is faster
- enddo
- field_getLocalTemperature = field_getLocalTemperature/homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getLocalTemperature
-
-!--------------------------------------------------------------------------------------------------
-!> @brief Sets the regularised temperature value in field state
-!--------------------------------------------------------------------------------------------------
-subroutine field_putFieldTemperature(ip,el,fieldThermalValue)
- use material, only: &
- material_homog, &
- fieldThermal, &
- mappingHomogenization, &
- field_thermal_type, &
- FIELD_THERMAL_nonlocal_ID
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el
- real(pReal), intent(in) :: &
- fieldThermalValue
-
- select case(field_thermal_type(material_homog(ip,el)))
- case (FIELD_THERMAL_nonlocal_ID)
- fieldThermal(material_homog(ip,el))% &
- field(1,mappingHomogenization(1,ip,el)) = fieldThermalValue
-
- end select
-
-end subroutine field_putFieldTemperature
-
-!--------------------------------------------------------------------------------------------------
-!> @brief return heat generation rate
-!--------------------------------------------------------------------------------------------------
-real(pReal) function field_getHeatGeneration(ip,el)
- use mesh, only: &
- mesh_element
- use material, only: &
- homogenization_Ngrains
- use crystallite, only: &
- crystallite_Tstar_v, &
- crystallite_Lp
- use constitutive, only: &
- constitutive_getHeatGeneration
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
- field_getHeatGeneration = 0.0_pReal
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getHeatGeneration = field_getHeatGeneration + &
- constitutive_getHeatGeneration(crystallite_Tstar_v(1:6,ipc,ip,el), &
- crystallite_Lp (1:3,1:3,ipc,ip,el), &
- ipc,ip,el)
- enddo
- field_getHeatGeneration = field_getHeatGeneration/homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getHeatGeneration
-
-!--------------------------------------------------------------------------------------------------
-!> @brief ToDo
-!--------------------------------------------------------------------------------------------------
-real(pReal) function field_getLocalVacancyConcentration(ip,el)
- use mesh, only: &
- mesh_element
- use material, only: &
- homogenization_Ngrains
- use constitutive, only: &
- constitutive_getLocalVacancyConcentration
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el !< element number
- integer(pInt) :: &
- ipc
-
-
- field_getLocalVacancyConcentration = 0.0_pReal
- do ipc = 1, homogenization_Ngrains(mesh_element(3,el))
- field_getLocalVacancyConcentration = field_getLocalVacancyConcentration + &
- constitutive_getLocalVacancyConcentration(ipc,ip,el) ! array/function/subroutine which is faster
- enddo
- field_getLocalVacancyConcentration = field_getLocalVacancyConcentration/ &
- homogenization_Ngrains(mesh_element(3,el))
-
-end function field_getLocalVacancyConcentration
-
-!--------------------------------------------------------------------------------------------------
-!> @brief Sets the diffused vacancy concentration in field state
-!--------------------------------------------------------------------------------------------------
-subroutine field_putFieldVacancyConcentration(ip,el,fieldVacancyConcentration)
- use material, only: &
- material_homog, &
- fieldVacancy, &
- mappingHomogenization, &
- field_vacancy_type, &
- FIELD_VACANCY_nonlocal_ID
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point number
- el
- real(pReal), intent(in) :: &
- fieldVacancyConcentration
-
- select case(field_vacancy_type(material_homog(ip,el)))
- case (FIELD_VACANCY_nonlocal_ID)
- fieldVacancy(material_homog(ip,el))% &
- field(1,mappingHomogenization(1,ip,el)) = fieldVacancyConcentration
-
- end select
-
-end subroutine field_putFieldVacancyConcentration
-
!--------------------------------------------------------------------------------------------------
!> @brief return array of homogenization results for post file inclusion. call only,
!> if homogenization_sizePostResults(i,e) > 0 !!
@@ -1584,80 +1261,151 @@ function homogenization_postResults(ip,el)
use material, only: &
mappingHomogenization, &
homogState, &
+ thermalState, &
+ damageState, &
+ vacancyfluxState, &
+ porosityState, &
+ hydrogenfluxState, &
homogenization_type, &
+ thermal_type, &
+ damage_type, &
+ vacancyflux_type, &
+ porosity_type, &
+ hydrogenflux_type, &
HOMOGENIZATION_NONE_ID, &
HOMOGENIZATION_ISOSTRAIN_ID, &
- HOMOGENIZATION_RGC_ID
+ HOMOGENIZATION_RGC_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
use homogenization_isostrain, only: &
homogenization_isostrain_postResults
use homogenization_RGC, only: &
homogenization_RGC_postResults
+ use thermal_adiabatic, only: &
+ thermal_adiabatic_postResults
+ use thermal_conduction, only: &
+ thermal_conduction_postResults
+ use damage_local, only: &
+ damage_local_postResults
+ use damage_nonlocal, only: &
+ damage_nonlocal_postResults
+ use vacancyflux_isochempot, only: &
+ vacancyflux_isochempot_postResults
+ use vacancyflux_cahnhilliard, only: &
+ vacancyflux_cahnhilliard_postResults
+ use porosity_phasefield, only: &
+ porosity_phasefield_postResults
+ use hydrogenflux_cahnhilliard, only: &
+ hydrogenflux_cahnhilliard_postResults
implicit none
integer(pInt), intent(in) :: &
ip, & !< integration point
el !< element number
- real(pReal), dimension(homogState(mappingHomogenization(2,ip,el))%sizePostResults) :: &
+ real(pReal), dimension( homogState (mappingHomogenization(2,ip,el))%sizePostResults &
+ + thermalState (mappingHomogenization(2,ip,el))%sizePostResults &
+ + damageState (mappingHomogenization(2,ip,el))%sizePostResults &
+ + vacancyfluxState (mappingHomogenization(2,ip,el))%sizePostResults &
+ + porosityState (mappingHomogenization(2,ip,el))%sizePostResults &
+ + hydrogenfluxState(mappingHomogenization(2,ip,el))%sizePostResults) :: &
homogenization_postResults
-
+ integer(pInt) :: &
+ startPos, endPos
+
homogenization_postResults = 0.0_pReal
+
+ startPos = 1_pInt
+ endPos = homogState(mappingHomogenization(2,ip,el))%sizePostResults
chosenHomogenization: select case (homogenization_type(mesh_element(3,el)))
case (HOMOGENIZATION_NONE_ID) chosenHomogenization
case (HOMOGENIZATION_ISOSTRAIN_ID) chosenHomogenization
- homogenization_postResults = homogenization_isostrain_postResults(&
+ homogenization_postResults(startPos:endPos) = &
+ homogenization_isostrain_postResults(&
ip, &
el, &
materialpoint_P(1:3,1:3,ip,el), &
materialpoint_F(1:3,1:3,ip,el))
case (HOMOGENIZATION_RGC_ID) chosenHomogenization
- homogenization_postResults = homogenization_RGC_postResults(&
+ homogenization_postResults(startPos:endPos) = &
+ homogenization_RGC_postResults(&
ip, &
el, &
materialpoint_P(1:3,1:3,ip,el), &
materialpoint_F(1:3,1:3,ip,el))
end select chosenHomogenization
+ startPos = endPos + 1_pInt
+ endPos = endPos + thermalState(mappingHomogenization(2,ip,el))%sizePostResults
+ chosenThermal: select case (thermal_type(mesh_element(3,el)))
+ case (THERMAL_isothermal_ID) chosenThermal
+
+ case (THERMAL_adiabatic_ID) chosenThermal
+ homogenization_postResults(startPos:endPos) = &
+ thermal_adiabatic_postResults(ip, el)
+ case (THERMAL_conduction_ID) chosenThermal
+ homogenization_postResults(startPos:endPos) = &
+ thermal_conduction_postResults(ip, el)
+ end select chosenThermal
+
+ startPos = endPos + 1_pInt
+ endPos = endPos + damageState(mappingHomogenization(2,ip,el))%sizePostResults
+ chosenDamage: select case (damage_type(mesh_element(3,el)))
+ case (DAMAGE_none_ID) chosenDamage
+
+ case (DAMAGE_local_ID) chosenDamage
+ homogenization_postResults(startPos:endPos) = &
+ damage_local_postResults(ip, el)
+
+ case (DAMAGE_nonlocal_ID) chosenDamage
+ homogenization_postResults(startPos:endPos) = &
+ damage_nonlocal_postResults(ip, el)
+ end select chosenDamage
+
+ startPos = endPos + 1_pInt
+ endPos = endPos + vacancyfluxState(mappingHomogenization(2,ip,el))%sizePostResults
+ chosenVacancyflux: select case (vacancyflux_type(mesh_element(3,el)))
+ case (VACANCYFLUX_isoconc_ID) chosenVacancyflux
+
+ case (VACANCYFLUX_isochempot_ID) chosenVacancyflux
+ homogenization_postResults(startPos:endPos) = &
+ vacancyflux_isochempot_postResults(ip, el)
+ case (VACANCYFLUX_cahnhilliard_ID) chosenVacancyflux
+ homogenization_postResults(startPos:endPos) = &
+ vacancyflux_cahnhilliard_postResults(ip, el)
+ end select chosenVacancyflux
+
+ startPos = endPos + 1_pInt
+ endPos = endPos + porosityState(mappingHomogenization(2,ip,el))%sizePostResults
+ chosenPorosity: select case (porosity_type(mesh_element(3,el)))
+ case (POROSITY_none_ID) chosenPorosity
+
+ case (POROSITY_phasefield_ID) chosenPorosity
+ homogenization_postResults(startPos:endPos) = &
+ porosity_phasefield_postResults(ip, el)
+ end select chosenPorosity
+
+ startPos = endPos + 1_pInt
+ endPos = endPos + hydrogenfluxState(mappingHomogenization(2,ip,el))%sizePostResults
+ chosenHydrogenflux: select case (hydrogenflux_type(mesh_element(3,el)))
+ case (HYDROGENFLUX_isoconc_ID) chosenHydrogenflux
+
+ case (HYDROGENFLUX_cahnhilliard_ID) chosenHydrogenflux
+ homogenization_postResults(startPos:endPos) = &
+ hydrogenflux_cahnhilliard_postResults(ip, el)
+ end select chosenHydrogenflux
+
end function homogenization_postResults
-!--------------------------------------------------------------------------------------------------
-!> @brief return array of homogenization results for post file inclusion. call only,
-!> if homogenization_sizePostResults(i,e) > 0 !!
-!--------------------------------------------------------------------------------------------------
-function field_postResults(ip,el)
- use material, only: &
- mappingHomogenization, &
- fieldThermal, &
- fieldDamage, &
- fieldVacancy
-
- implicit none
- integer(pInt), intent(in) :: &
- ip, & !< integration point
- el !< element number
- real(pReal), dimension(field_sizePostResults(mappingHomogenization(2,ip,el))) :: &
- field_postResults
- integer(pInt) :: &
- c, homog, pos, o
-
- field_postResults = 0.0_pReal
- homog = mappingHomogenization(2,ip,el)
- pos = mappingHomogenization(1,ip,el)
- c = 0_pInt
- do o = 1_pInt,field_Noutput(homog)
- select case(field_outputID(o,homog))
- case (temperature_ID)
- field_postResults(c+1_pInt) = fieldThermal(homog)%field(1,pos)
- c = c + 1_pInt
- case (damage_ID)
- field_postResults(c+1_pInt) = fieldDamage(homog)%field(1,pos)
- c = c + 1_pInt
- case (vacancy_concentration_ID)
- field_postResults(c+1_pInt) = fieldVacancy(homog)%field(1,pos)
- c = c + 1_pInt
- end select
- enddo
-
-end function field_postResults
-
end module homogenization
diff --git a/code/homogenization_RGC.f90 b/code/homogenization_RGC.f90
index 7a311bd70..8344f97ec 100644
--- a/code/homogenization_RGC.f90
+++ b/code/homogenization_RGC.f90
@@ -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
diff --git a/code/hydrogenflux_cahnhilliard.f90 b/code/hydrogenflux_cahnhilliard.f90
new file mode 100644
index 000000000..b2b4d8734
--- /dev/null
+++ b/code/hydrogenflux_cahnhilliard.f90
@@ -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
+ 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
+ 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
diff --git a/code/hydrogenflux_isoconc.f90 b/code/hydrogenflux_isoconc.f90
new file mode 100644
index 000000000..e5defd029
--- /dev/null
+++ b/code/hydrogenflux_isoconc.f90
@@ -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
diff --git a/code/kinematics_cleavage_opening.f90 b/code/kinematics_cleavage_opening.f90
new file mode 100644
index 000000000..8ff4ca2ba
--- /dev/null
+++ b/code/kinematics_cleavage_opening.f90
@@ -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
+ 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
diff --git a/code/kinematics_hydrogen_strain.f90 b/code/kinematics_hydrogen_strain.f90
new file mode 100644
index 000000000..79f6677e5
--- /dev/null
+++ b/code/kinematics_hydrogen_strain.f90
@@ -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
+ 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
diff --git a/code/kinematics_slipplane_opening.f90 b/code/kinematics_slipplane_opening.f90
new file mode 100644
index 000000000..59de2708b
--- /dev/null
+++ b/code/kinematics_slipplane_opening.f90
@@ -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
+ 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
diff --git a/code/kinematics_thermal_expansion.f90 b/code/kinematics_thermal_expansion.f90
new file mode 100644
index 000000000..f34b3abcb
--- /dev/null
+++ b/code/kinematics_thermal_expansion.f90
@@ -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
+ 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
diff --git a/code/kinematics_vacancy_strain.f90 b/code/kinematics_vacancy_strain.f90
new file mode 100644
index 000000000..403b1b730
--- /dev/null
+++ b/code/kinematics_vacancy_strain.f90
@@ -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
+ 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
diff --git a/code/lattice.f90 b/code/lattice.f90
index bb3c9a3df..93ca65e8e 100644
--- a/code/lattice.f90
+++ b/code/lattice.f90
@@ -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))
!--------------------------------------------------------------------------------------------------
diff --git a/code/material.f90 b/code/material.f90
index 1d7a8eb2d..a00873cac 100644
--- a/code/material.f90
+++ b/code/material.f90
@@ -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
!--------------------------------------------------------------------------------------------------
diff --git a/code/numerics.f90 b/code/numerics.f90
index 19d132f42..9ba61854b 100644
--- a/code/numerics.f90
+++ b/code/numerics.f90
@@ -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
diff --git a/code/porosity_none.f90 b/code/porosity_none.f90
new file mode 100644
index 000000000..738104545
--- /dev/null
+++ b/code/porosity_none.f90
@@ -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
diff --git a/code/porosity_phasefield.f90 b/code/porosity_phasefield.f90
new file mode 100644
index 000000000..3cf832319
--- /dev/null
+++ b/code/porosity_phasefield.f90
@@ -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
+ 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
+ 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
diff --git a/code/prec.f90 b/code/prec.f90
index 189b2c18e..97252c60e 100644
--- a/code/prec.f90
+++ b/code/prec.f90
@@ -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
diff --git a/code/source_damage_anisoBrittle.f90 b/code/source_damage_anisoBrittle.f90
new file mode 100644
index 000000000..6b05876cd
--- /dev/null
+++ b/code/source_damage_anisoBrittle.f90
@@ -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
+ 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
diff --git a/code/source_damage_anisoDuctile.f90 b/code/source_damage_anisoDuctile.f90
new file mode 100644
index 000000000..b78bcc08d
--- /dev/null
+++ b/code/source_damage_anisoDuctile.f90
@@ -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
+ 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
diff --git a/code/source_damage_isoBrittle.f90 b/code/source_damage_isoBrittle.f90
new file mode 100644
index 000000000..cf560e1f4
--- /dev/null
+++ b/code/source_damage_isoBrittle.f90
@@ -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
+ 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
diff --git a/code/source_damage_isoDuctile.f90 b/code/source_damage_isoDuctile.f90
new file mode 100644
index 000000000..af547aaa7
--- /dev/null
+++ b/code/source_damage_isoDuctile.f90
@@ -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
+ 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
diff --git a/code/source_thermal_dissipation.f90 b/code/source_thermal_dissipation.f90
new file mode 100644
index 000000000..04e8c8690
--- /dev/null
+++ b/code/source_thermal_dissipation.f90
@@ -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
+ 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
diff --git a/code/source_vacancy_irradiation.f90 b/code/source_vacancy_irradiation.f90
new file mode 100644
index 000000000..07798df29
--- /dev/null
+++ b/code/source_vacancy_irradiation.f90
@@ -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
+ 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
diff --git a/code/source_vacancy_phenoplasticity.f90 b/code/source_vacancy_phenoplasticity.f90
new file mode 100644
index 000000000..8fca355ea
--- /dev/null
+++ b/code/source_vacancy_phenoplasticity.f90
@@ -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
+ 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
diff --git a/code/source_vacancy_thermalfluc.f90 b/code/source_vacancy_thermalfluc.f90
new file mode 100644
index 000000000..3bfc05884
--- /dev/null
+++ b/code/source_vacancy_thermalfluc.f90
@@ -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
+ 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
diff --git a/code/thermal_adiabatic.f90 b/code/thermal_adiabatic.f90
index e137e1039..3c7888331 100644
--- a/code/thermal_adiabatic.f90
+++ b/code/thermal_adiabatic.f90
@@ -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
+ section = 0_pInt
+ do while (trim(line) /= IO_EOF .and. IO_lc(IO_getTag(line,'<','>')) /= material_partHomogenization)! wind forward to
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
diff --git a/code/thermal_conduction.f90 b/code/thermal_conduction.f90
new file mode 100644
index 000000000..570abe8ae
--- /dev/null
+++ b/code/thermal_conduction.f90
@@ -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
+ 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
diff --git a/code/thermal_isothermal.f90 b/code/thermal_isothermal.f90
index dca088708..d3d033c17 100644
--- a/code/thermal_isothermal.f90
+++ b/code/thermal_isothermal.f90
@@ -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
diff --git a/code/vacancy_constant.f90 b/code/vacancy_constant.f90
deleted file mode 100644
index 5f9913f2b..000000000
--- a/code/vacancy_constant.f90
+++ /dev/null
@@ -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
diff --git a/code/vacancy_generation.f90 b/code/vacancy_generation.f90
deleted file mode 100644
index 2e8053cca..000000000
--- a/code/vacancy_generation.f90
+++ /dev/null
@@ -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
- 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
diff --git a/code/vacancyflux_cahnhilliard.f90 b/code/vacancyflux_cahnhilliard.f90
new file mode 100644
index 000000000..c20a4ad97
--- /dev/null
+++ b/code/vacancyflux_cahnhilliard.f90
@@ -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
+ 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
+ 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
diff --git a/code/vacancyflux_isochempot.f90 b/code/vacancyflux_isochempot.f90
new file mode 100644
index 000000000..44ccb13e6
--- /dev/null
+++ b/code/vacancyflux_isochempot.f90
@@ -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
+ 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
diff --git a/code/vacancyflux_isoconc.f90 b/code/vacancyflux_isoconc.f90
new file mode 100644
index 000000000..c66a8f55f
--- /dev/null
+++ b/code/vacancyflux_isoconc.f90
@@ -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