This commit is contained in:
parent
532d3c2a16
commit
73694790f8
|
@ -0,0 +1,488 @@
|
||||||
|
|
||||||
|
!##############################################################
|
||||||
|
MODULE CPFEM
|
||||||
|
!##############################################################
|
||||||
|
! *** CPFEM engine ***
|
||||||
|
!
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
!
|
||||||
|
! ****************************************************************
|
||||||
|
! *** General variables for the material behaviour calculation ***
|
||||||
|
! ****************************************************************
|
||||||
|
real(pReal) CPFEM_Tp
|
||||||
|
real(pReal), dimension (:,:,:), allocatable :: CPFEM_stress_all
|
||||||
|
real(pReal), dimension (:,:,:,:), allocatable :: CPFEM_jacobi_all
|
||||||
|
real(pReal), dimension (:,:,:,:), allocatable :: CPFEM_ffn_all
|
||||||
|
real(pReal), dimension (:,:,:,:), allocatable :: CPFEM_ffn1_all
|
||||||
|
real(pReal), dimension (:,:,:,:), allocatable :: CPFEM_results
|
||||||
|
real(pReal), dimension (:,:,:,:), allocatable :: CPFEM_ini_ori
|
||||||
|
real(pReal), dimension (:,:,:,:), allocatable :: CPFEM_sigma_old
|
||||||
|
real(pReal), dimension (:,:,:,:), allocatable :: CPFEM_sigma_new
|
||||||
|
real(pReal), dimension (:,:,:,:,:), allocatable :: CPFEM_Fp_old
|
||||||
|
real(pReal), dimension (:,:,:,:,:), allocatable :: CPFEM_Fp_new
|
||||||
|
real(pReal), dimension (:,:,:,:), allocatable :: CPFEM_jaco_old
|
||||||
|
integer(pInt) :: CPFEM_inc_old = 0_pInt
|
||||||
|
integer(pInt) :: CPFEM_subinc_old = 1_pInt
|
||||||
|
integer(pInt) :: CPFEM_Nresults = 3_pInt
|
||||||
|
logical :: CPFEM_first_call = .true.
|
||||||
|
|
||||||
|
CONTAINS
|
||||||
|
|
||||||
|
!*********************************************************
|
||||||
|
!*** allocate the arrays defined in module CPFEM ***
|
||||||
|
!*** and initialize them ***
|
||||||
|
!*********************************************************
|
||||||
|
SUBROUTINE CPFEM_init()
|
||||||
|
!
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
use math, only: math_EulertoR
|
||||||
|
use mesh
|
||||||
|
use constitutive
|
||||||
|
!
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt) e,i,g
|
||||||
|
!
|
||||||
|
! *** mpie.marc parameters ***
|
||||||
|
CPFEM_Tp = 0.0_pReal
|
||||||
|
allocate(CPFEM_ffn_all (3,3,mesh_maxNips,mesh_NcpElems)) ; CPFEM_ffn_all = 0.0_pReal
|
||||||
|
allocate(CPFEM_ffn1_all (3,3,mesh_maxNips,mesh_NcpElems)) ; CPFEM_ffn1_all = 0.0_pReal
|
||||||
|
allocate(CPFEM_stress_all( 6,mesh_maxNips,mesh_NcpElems)) ; CPFEM_stress_all = 0.0_pReal
|
||||||
|
allocate(CPFEM_jacobi_all(6,6,mesh_maxNips,mesh_NcpElems)) ; CPFEM_jacobi_all = 0.0_pReal
|
||||||
|
!
|
||||||
|
! *** User defined results !!! MISSING incorporate consti_Nresults ***
|
||||||
|
allocate(CPFEM_results(CPFEM_Nresults+constitutive_maxNresults,constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems))
|
||||||
|
CPFEM_results = 0.0_pReal
|
||||||
|
!
|
||||||
|
! *** Second Piola-Kirchoff stress tensor at (t=t0) and (t=t1) ***
|
||||||
|
allocate(CPFEM_sigma_old(6,constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems)) ; CPFEM_sigma_old = 0.0_pReal
|
||||||
|
allocate(CPFEM_sigma_new(6,constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems)) ; CPFEM_sigma_new = 0.0_pReal
|
||||||
|
!
|
||||||
|
! *** Plastic deformation gradient at (t=t0) and (t=t1) ***
|
||||||
|
allocate(CPFEM_Fp_old(3,3,constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems))
|
||||||
|
forall (e=1:mesh_NcpElems,i=1:mesh_maxNips,g=1:constitutive_maxNgrains) &
|
||||||
|
CPFEM_Fp_old(:,:,g,i,e) = math_EulerToR(constitutive_EulerAngles(:,g,i,e)) ! plastic def gradient reflects init orientation
|
||||||
|
allocate(CPFEM_Fp_new(3,3,constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems)) ; CPFEM_Fp_new = 0.0_pReal
|
||||||
|
!
|
||||||
|
! *** Old jacobian (consistent tangent) ***
|
||||||
|
allocate(CPFEM_jaco_old(6,6,mesh_maxNips,mesh_NcpElems)) ; CPFEM_jaco_old = 0.0_pReal
|
||||||
|
!
|
||||||
|
! *** Output to MARC output file ***
|
||||||
|
write(6,*)
|
||||||
|
write(6,*) 'Arrays allocated:'
|
||||||
|
write(6,*) 'CPFEM_ffn_all: ', shape(CPFEM_ffn_all)
|
||||||
|
write(6,*) 'CPFEM_ffn1_all: ', shape(CPFEM_ffn1_all)
|
||||||
|
write(6,*) 'CPFEM_stress_all: ', shape(CPFEM_stress_all)
|
||||||
|
write(6,*) 'CPFEM_jacobi_all: ', shape(CPFEM_jacobi_all)
|
||||||
|
write(6,*) 'CPFEM_results: ', shape(CPFEM_results)
|
||||||
|
write(6,*) 'CPFEM_sigma_old: ', shape(CPFEM_sigma_old)
|
||||||
|
write(6,*) 'CPFEM_sigma_new: ', shape(CPFEM_sigma_new)
|
||||||
|
write(6,*) 'CPFEM_Fp_old: ', shape(CPFEM_Fp_old)
|
||||||
|
write(6,*) 'CPFEM_Fp_new: ', shape(CPFEM_Fp_new)
|
||||||
|
write(6,*) 'CPFEM_jaco_old: ', shape(CPFEM_jaco_old)
|
||||||
|
write(6,*)
|
||||||
|
call flush(6)
|
||||||
|
return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
!
|
||||||
|
!
|
||||||
|
!***********************************************************************
|
||||||
|
!*** perform initialization at first call, update variables and ***
|
||||||
|
!*** call the actual material model ***
|
||||||
|
!***********************************************************************
|
||||||
|
SUBROUTINE CPFEM_general(ffn, ffn1, Tp, CPFEM_inc, CPFEM_subinc, CPFEM_cn, CPFEM_dt, CPFEM_en, CPFEM_in)
|
||||||
|
!
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
use math, only: math_init
|
||||||
|
use mesh, only: mesh_init,mesh_FEasCP
|
||||||
|
use constitutive, only: constitutive_init,constitutive_state_old,constitutive_state_new
|
||||||
|
implicit none
|
||||||
|
!
|
||||||
|
real(pReal) ffn(3,3), ffn1(3,3), Tp, CPFEM_dt
|
||||||
|
integer(pInt) CPFEM_inc, CPFEM_subinc, CPFEM_cn, CPFEM_en, CPFEM_in, cp_en
|
||||||
|
!
|
||||||
|
! initialization step
|
||||||
|
if (CPFEM_first_call) then
|
||||||
|
! three dimensional stress state ?
|
||||||
|
call math_init()
|
||||||
|
call mesh_init()
|
||||||
|
call constitutive_init()
|
||||||
|
call crystal_init()
|
||||||
|
call CPFEM_init()
|
||||||
|
CPFEM_first_call = .false.
|
||||||
|
endif
|
||||||
|
if (CPFEM_inc==CPFEM_inc_old) then ! not a new increment
|
||||||
|
! case of a new subincrement:update starting with subinc 2
|
||||||
|
if (CPFEM_subinc > CPFEM_subinc_old) then
|
||||||
|
CPFEM_sigma_old = CPFEM_sigma_new
|
||||||
|
CPFEM_Fp_old = CPFEM_Fp_new
|
||||||
|
constitutive_state_old = constitutive_state_new
|
||||||
|
CPFEM_subinc_old = CPFEM_subinc
|
||||||
|
endif
|
||||||
|
else ! new increment
|
||||||
|
CPFEM_sigma_old = CPFEM_sigma_new
|
||||||
|
CPFEM_Fp_old = CPFEM_Fp_new
|
||||||
|
constitutive_state_old = constitutive_state_new
|
||||||
|
CPFEM_inc_old = CPFEM_inc
|
||||||
|
CPFEM_subinc_old = 1_pInt
|
||||||
|
endif
|
||||||
|
|
||||||
|
cp_en = mesh_FEasCP('elem',CPFEM_en)
|
||||||
|
CPFEM_Tp = Tp
|
||||||
|
CPFEM_ffn_all(:,:,CPFEM_in, cp_en) = ffn
|
||||||
|
CPFEM_ffn1_all(:,:,CPFEM_in, cp_en) = ffn1
|
||||||
|
call CPFEM_stressIP(CPFEM_cn, CPFEM_dt, cp_en, CPFEM_in)
|
||||||
|
return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!**********************************************************
|
||||||
|
!*** calculate the material behaviour at IP level ***
|
||||||
|
!**********************************************************
|
||||||
|
SUBROUTINE CPFEM_stressIP(&
|
||||||
|
CPFEM_cn,& ! Cycle number
|
||||||
|
CPFEM_dt,& ! Time increment (dt)
|
||||||
|
cp_en,& ! Element number
|
||||||
|
CPFEM_in) ! Integration point number
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt,ijaco,nCutback
|
||||||
|
use math, only: math_pDecomposition,math_RtoEuler
|
||||||
|
use IO, only: IO_error
|
||||||
|
use mesh, only: mesh_element
|
||||||
|
use constitutive
|
||||||
|
!
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt), parameter :: i_now = 1_pInt,i_then = 2_pInt
|
||||||
|
character(len=128) msg
|
||||||
|
integer(pInt) CPFEM_cn,cp_en,CPFEM_in,grain,i
|
||||||
|
logical updateJaco,error
|
||||||
|
real(pReal) CPFEM_dt,dt,t,volfrac
|
||||||
|
real(pReal), dimension(6) :: cs,Tstar_v
|
||||||
|
real(pReal), dimension(6,6) :: cd
|
||||||
|
real(pReal), dimension(3,3) :: Fe,U,R,deltaFg
|
||||||
|
real(pReal), dimension(3,3,2) :: Fg,Fp
|
||||||
|
real(pReal), dimension(constitutive_maxNstatevars,2) :: state
|
||||||
|
|
||||||
|
updateJaco = (mod(CPFEM_cn,ijaco)==0) ! update consistent tangent every ijaco'th iteration
|
||||||
|
|
||||||
|
CPFEM_stress_all(:,CPFEM_in,cp_en) = 0.0_pReal ! average Cauchy stress
|
||||||
|
if (updateJaco) CPFEM_jaco_old(:,:,CPFEM_in,cp_en) = 0.0_pReal ! average consistent tangent
|
||||||
|
|
||||||
|
! -------------- grain loop -----------------
|
||||||
|
do grain = 1,texture_Ngrains(mesh_element(4,cp_en))
|
||||||
|
! -------------------------------------------
|
||||||
|
|
||||||
|
i = 0_pInt ! cutback counter
|
||||||
|
state(:,i_now) = constitutive_state_old(:,grain,CPFEM_in,cp_en)
|
||||||
|
Fg(:,:,i_now) = CPFEM_ffn_all(:,:,CPFEM_in,cp_en)
|
||||||
|
Fp(:,:,i_now) = CPFEM_Fp_old(:,:,grain,CPFEM_in,cp_en)
|
||||||
|
|
||||||
|
deltaFg = CPFEM_ffn1_all(:,:,CPFEM_in,cp_en)-CPFEM_ffn_all(:,:,CPFEM_in,cp_en)
|
||||||
|
dt = CPFEM_dt
|
||||||
|
|
||||||
|
Tstar_v = CPFEM_sigma_old(:,grain,CPFEM_in,cp_en) ! use last result as initial guess
|
||||||
|
Fg(:,:,i_then) = Fg(:,:,i_now)
|
||||||
|
state(:,i_then) = 0.0_pReal ! state_old as initial guess
|
||||||
|
t = 0.0_pReal
|
||||||
|
|
||||||
|
! ------- crystallite integration -----------
|
||||||
|
do
|
||||||
|
! -------------------------------------------
|
||||||
|
if (t+dt < CPFEM_dt) then ! intermediate solution
|
||||||
|
t = t+dt ! next time inc
|
||||||
|
Fg(:,:,i_then) = Fg(:,:,i_then)+deltaFg ! corresponding Fg
|
||||||
|
else ! full step solution
|
||||||
|
t = CPFEM_dt ! final time
|
||||||
|
Fg(:,:,i_then) = CPFEM_ffn1_all(:,:,CPFEM_in,cp_en) ! final Fg
|
||||||
|
endif
|
||||||
|
|
||||||
|
call CPFEM_stressCrystallite(msg,cs,cd,Tstar_v,Fp(:,:,i_then),Fe,state(:,i_then),&
|
||||||
|
dt,cp_en,CPFEM_in,grain,updateJaco .and. t==CPFEM_dt,&
|
||||||
|
Fg(:,:,i_now),Fg(:,:,i_then),Fp(:,:,i_now),state(:,i_now))
|
||||||
|
if (msg == 'ok') then ! solution converged
|
||||||
|
if (t == CPFEM_dt) exit ! reached final "then"
|
||||||
|
else ! solution not found
|
||||||
|
i = i+1_pInt ! inc cutback counter
|
||||||
|
! write(6,*) 'ncut:', i
|
||||||
|
if (i > nCutback) then ! limit exceeded?
|
||||||
|
write(6,*) 'cutback limit --> '//msg
|
||||||
|
write(6,*) 'Grain: ',grain
|
||||||
|
write(6,*) 'Integration point: ',CPFEM_in
|
||||||
|
write(6,*) 'Element: ',mesh_element(1,cp_en)
|
||||||
|
call IO_error(600)
|
||||||
|
return ! byebye
|
||||||
|
else
|
||||||
|
t = t-dt ! rewind time
|
||||||
|
Fg(:,:,i_then) = Fg(:,:,i_then)-deltaFg ! rewind Fg
|
||||||
|
dt = 0.5_pReal*dt ! cut time-step in half
|
||||||
|
deltaFg = 0.5_pReal*deltaFg ! cut Fg-step in half
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
enddo ! crystallite integration (cutback loop)
|
||||||
|
|
||||||
|
! ---- update crystallite matrices at t = t1 ----
|
||||||
|
CPFEM_Fp_new(:,:,grain,CPFEM_in,cp_en) = Fp(:,:,i_then)
|
||||||
|
constitutive_state_new(:,grain,CPFEM_in,cp_en) = state(:,i_then)
|
||||||
|
CPFEM_sigma_new(:,grain,CPFEM_in,cp_en) = Tstar_v
|
||||||
|
! ---- update results plotted in MENTAT ----
|
||||||
|
call math_pDecomposition(Fe,U,R,error) ! polar decomposition
|
||||||
|
if (error) then
|
||||||
|
write(6,*) 'polar decomposition'
|
||||||
|
write(6,*) 'Grain: ',grain
|
||||||
|
write(6,*) 'Integration point: ',CPFEM_in
|
||||||
|
write(6,*) 'Element: ',mesh_element(1,cp_en)
|
||||||
|
call IO_error(600)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
CPFEM_results(1:3,grain,CPFEM_in,cp_en) = math_RtoEuler(transpose(R)) ! orientation
|
||||||
|
CPFEM_results(4:3+constitutive_Nresults(grain,CPFEM_in,cp_en),grain,CPFEM_in,cp_en) = &
|
||||||
|
constitutive_post_results(Tstar_v,state(:,i_then),CPFEM_dt,CPFEM_Tp,grain,CPFEM_in,cp_en)
|
||||||
|
|
||||||
|
! ---- contribute to IP result ----
|
||||||
|
volfrac = constitutive_matVolFrac(grain,CPFEM_in,cp_en)*constitutive_texVolFrac(grain,CPFEM_in,cp_en)
|
||||||
|
CPFEM_stress_all(:,CPFEM_in,cp_en) = CPFEM_stress_all(:,CPFEM_in,cp_en)+volfrac*cs ! average Cauchy stress
|
||||||
|
if (updateJaco) CPFEM_jaco_old(:,:,CPFEM_in,cp_en) = CPFEM_jaco_old(:,:,CPFEM_in,cp_en)+volfrac*cd ! average consistent tangent
|
||||||
|
|
||||||
|
enddo ! grain loop
|
||||||
|
|
||||||
|
return
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! Calculates the stress for a single component
|
||||||
|
! it is based on the paper by Kalidindi et al.:
|
||||||
|
! J. Mech. Phys, Solids Vol. 40, No. 3, pp. 537-569, 1992
|
||||||
|
! it is modified to use anisotropic elasticity matrix
|
||||||
|
!********************************************************************
|
||||||
|
subroutine CPFEM_stressCrystallite(&
|
||||||
|
msg,& ! return message
|
||||||
|
cs,& ! Cauchy stress vector
|
||||||
|
dcs_de,& ! consistent tangent
|
||||||
|
Tstar_v,& ! second Piola-Kirchoff stress tensor
|
||||||
|
Fp_new,& ! new plastic deformation gradient
|
||||||
|
Fe_new,& ! new "elastic" deformation gradient
|
||||||
|
state_new,& ! new state variable array
|
||||||
|
!
|
||||||
|
dt,& ! time increment
|
||||||
|
cp_en,& ! element number
|
||||||
|
CPFEM_in,& ! integration point number
|
||||||
|
grain,& ! grain number
|
||||||
|
updateJaco,& ! boolean to calculate Jacobi matrix
|
||||||
|
Fg_old,& ! old global deformation gradient
|
||||||
|
Fg_new,& ! new global deformation gradient
|
||||||
|
Fp_old,& ! old plastic deformation gradient
|
||||||
|
state_old) ! old state variable array
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt,pert_e
|
||||||
|
use constitutive, only: constitutive_Nstatevars
|
||||||
|
use math, only: math_Mandel6to33,mapMandel
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) msg
|
||||||
|
logical updateJaco
|
||||||
|
integer(pInt) cp_en,CPFEM_in,grain,i
|
||||||
|
real(pReal) dt
|
||||||
|
real(pReal), dimension(3,3) :: Fg_old,Fg_new,Fg_pert,Fp_old,Fp_new,Fp_pert,Fe_new,Fe_pert,E_pert
|
||||||
|
real(pReal), dimension(6) :: cs,Tstar_v,Tstar_v_pert
|
||||||
|
real(pReal), dimension(6,6) :: dcs_de
|
||||||
|
real(pReal), dimension(constitutive_Nstatevars(grain,CPFEM_in,cp_en)) :: state_old,state_new,state_pert
|
||||||
|
|
||||||
|
call CPFEM_timeIntegration(msg,Fp_new,Fe_new,Tstar_v,state_new, & ! def gradients and PK2 at end of time step
|
||||||
|
dt,cp_en,CPFEM_in,grain,Fg_new,Fp_old,state_old)
|
||||||
|
if (msg /= 'ok') return
|
||||||
|
cs = CPFEM_CauchyStress(Tstar_v,Fe_new) ! Cauchy stress
|
||||||
|
|
||||||
|
if (updateJaco) then ! consistent tangent using numerical perturbation of Fg
|
||||||
|
do i = 1,6 ! Fg component
|
||||||
|
E_pert = 0.0_pReal
|
||||||
|
E_pert(mapMandel(1,i),mapMandel(2,i)) = E_pert(mapMandel(1,i),mapMandel(2,i)) + pert_e/2.0_pReal
|
||||||
|
E_pert(mapMandel(2,i),mapMandel(1,i)) = E_pert(mapMandel(2,i),mapMandel(1,i)) + pert_e/2.0_pReal
|
||||||
|
|
||||||
|
Fg_pert = Fg_new+matmul(E_pert,Fg_old) ! perturbated Fg
|
||||||
|
Tstar_v_pert = Tstar_v ! initial guess from end of time step
|
||||||
|
state_pert = state_new ! initial guess from end of time step
|
||||||
|
call CPFEM_timeIntegration(msg,Fp_pert,Fe_pert,Tstar_v_pert,state_pert, &
|
||||||
|
dt,cp_en,CPFEM_in,grain,Fg_pert,Fp_old,state_old)
|
||||||
|
if (msg /= 'ok') then
|
||||||
|
msg = 'consistent tangent --> '//msg
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
! Remark: (perturbated) Cauchy stress is Mandel hence dcs_de(:,4:6) is too large by sqrt(2)
|
||||||
|
dcs_de(:,i) = (CPFEM_CauchyStress(Tstar_v_pert,Fe_pert)-cs)/pert_e
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!***********************************************************************
|
||||||
|
!*** fully-implicit two-level time integration ***
|
||||||
|
!***********************************************************************
|
||||||
|
SUBROUTINE CPFEM_timeIntegration(&
|
||||||
|
msg,& ! return message
|
||||||
|
Fp_new,& ! new plastic deformation gradient
|
||||||
|
Fe_new,& ! new "elastic" deformation gradient
|
||||||
|
Tstar_v,& ! 2nd PK stress (taken as initial guess if /= 0)
|
||||||
|
state_new,& ! current microstructure at end of time inc (taken as guess if /= 0)
|
||||||
|
!
|
||||||
|
dt,& ! time increment
|
||||||
|
cp_en,& ! element number
|
||||||
|
CPFEM_in,& ! integration point number
|
||||||
|
grain,& ! grain number
|
||||||
|
Fg_new,& ! new total def gradient
|
||||||
|
Fp_old,& ! former plastic def gradient
|
||||||
|
state_old) ! former microstructure
|
||||||
|
|
||||||
|
use prec
|
||||||
|
use constitutive, only: constitutive_Nstatevars,&
|
||||||
|
constitutive_HomogenizedC,constitutive_dotState,constitutive_LpAndItsTangent,&
|
||||||
|
constitutive_Microstructure
|
||||||
|
use math
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) msg
|
||||||
|
integer(pInt) cp_en, CPFEM_in, grain
|
||||||
|
integer(pInt) iState,iStress,dummy, i,j,k,l,m
|
||||||
|
real(pReal) dt,det, p_hydro
|
||||||
|
real(pReal), dimension(6) :: Tstar_v,dTstar_v,Rstress, E, T_elastic, Rstress_old
|
||||||
|
real(pReal), dimension(6,6) :: C_66,Jacobi,invJacobi
|
||||||
|
real(pReal), dimension(3,3) :: Fg_new,Fp_old,Fp_new,Fe_new,invFp_old,invFp_new,Lp,A,B,AB
|
||||||
|
real(pReal), dimension(3,3,3,3) :: dLp, LTL
|
||||||
|
real(pReal), dimension(constitutive_Nstatevars(grain, CPFEM_in, cp_en)) :: state_old,state_new,dstate,Rstate,RstateS
|
||||||
|
logical failed
|
||||||
|
|
||||||
|
msg = 'ok' ! error-free so far
|
||||||
|
|
||||||
|
call math_invert3x3(Fp_old,invFp_old,det,failed) ! inversion of Fp
|
||||||
|
if (failed) then
|
||||||
|
msg = 'inversion Fp_old'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
C_66 = constitutive_HomogenizedC(grain, CPFEM_in, cp_en)
|
||||||
|
A = matmul(Fg_new,invFp_old) ! actually Fe
|
||||||
|
A = matmul(transpose(A), A)
|
||||||
|
|
||||||
|
! former state guessed, if none specified
|
||||||
|
if (all(state_new == 0.0_pReal)) state_new = state_old
|
||||||
|
RstateS = state_new
|
||||||
|
iState = 0_pInt
|
||||||
|
|
||||||
|
Rstress = Tstar_v
|
||||||
|
Rstress_old=Rstress
|
||||||
|
|
||||||
|
state: do ! outer iteration: state
|
||||||
|
iState = iState+1
|
||||||
|
if (iState > nState) then
|
||||||
|
msg = 'limit state iteration'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
call constitutive_Microstructure(state_new,CPFEM_Tp,grain,CPFEM_in,cp_en)
|
||||||
|
iStress = 0_pInt
|
||||||
|
stress: do ! inner iteration: stress
|
||||||
|
iStress = iStress+1
|
||||||
|
if (iStress > nStress) then ! too many loops required
|
||||||
|
msg = 'limit stress iteration'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
p_hydro=(Tstar_v(1)+Tstar_v(2)+Tstar_v(3))/3.0_pReal
|
||||||
|
forall(i=1:3) Tstar_v(i)=Tstar_v(i)-p_hydro
|
||||||
|
call constitutive_LpAndItsTangent(Lp,dLp,Tstar_v,state_new,CPFEM_Tp,grain,CPFEM_in,cp_en)
|
||||||
|
B = math_I3-dt*Lp
|
||||||
|
! B = B / math_det3x3(B)**(1.0_pReal/3.0_pReal)
|
||||||
|
AB = matmul(A,B)
|
||||||
|
T_elastic= 0.5_pReal*matmul(C_66,math_Mandel33to6(matmul(transpose(B),AB)-math_I3))
|
||||||
|
p_hydro=(T_elastic(1)+T_elastic(2)+T_elastic(3))/3.0_pReal
|
||||||
|
forall(i=1:3) T_elastic(i)=T_elastic(i)-p_hydro
|
||||||
|
Rstress = Tstar_v - T_elastic
|
||||||
|
! step size control: if residuum does not improve redo iteration with reduced step size
|
||||||
|
if(maxval(abs(Rstress)) > maxval(abs(Rstress_old)) .and. &
|
||||||
|
maxval(abs(Rstress)) > 1.0e-6 .and. iStress > 1) then
|
||||||
|
! write(6,*) 'Hallo', iStress
|
||||||
|
Tstar_v=Tstar_v+0.5*dTstar_v
|
||||||
|
dTstar_v=0.5*dTstar_v
|
||||||
|
cycle
|
||||||
|
endif
|
||||||
|
if (iStress > 1 .and. (maxval(abs(Tstar_v)) < 1.0e-3_pReal .or. maxval(abs(Rstress/maxval(abs(Tstar_v)))) < tol_Stress)) exit stress
|
||||||
|
|
||||||
|
! update stress guess using inverse of dRes/dTstar (Newton--Raphson)
|
||||||
|
LTL = 0.0_pReal
|
||||||
|
do i=1,3
|
||||||
|
do j=1,3
|
||||||
|
do k=1,3
|
||||||
|
do l=1,3
|
||||||
|
do m=1,3
|
||||||
|
LTL(i,j,k,l) = LTL(i,j,k,l) + dLp(j,i,m,k)*AB(m,l) + AB(m,i)*dLp(m,j,k,l)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
Jacobi = math_identity2nd(6) + 0.5_pReal*dt*matmul(C_66,math_Mandel3333to66(LTL))
|
||||||
|
j = 0_pInt
|
||||||
|
call math_invert6x6(Jacobi,invJacobi,dummy,failed)
|
||||||
|
do while (failed .and. j <= nReg)
|
||||||
|
forall (i=1:6) Jacobi(i,i) = 1.05_pReal*maxval(Jacobi(i,:)) ! regularization
|
||||||
|
call math_invert6x6(Jacobi,invJacobi,dummy,failed)
|
||||||
|
j = j+1
|
||||||
|
enddo
|
||||||
|
if (failed) then
|
||||||
|
msg = 'regularization Jacobi'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
dTstar_v = matmul(invJacobi,Rstress) ! correction to Tstar
|
||||||
|
Rstress_old=Rstress
|
||||||
|
Tstar_v = Tstar_v-dTstar_v
|
||||||
|
! write(999,*) Tstar_v, dTstar_v, Rstress
|
||||||
|
|
||||||
|
enddo stress
|
||||||
|
! write(6,*) 'istress', istress
|
||||||
|
Tstar_v = 0.5_pReal*matmul(C_66,math_Mandel33to6(matmul(transpose(B),AB)-math_I3))
|
||||||
|
dstate = dt*constitutive_dotState(Tstar_v,state_new,CPFEM_Tp,grain,CPFEM_in,cp_en) ! evolution of microstructure
|
||||||
|
Rstate = state_new - (state_old+dstate)
|
||||||
|
RstateS = 0.0_pReal
|
||||||
|
forall (i=1:constitutive_Nstatevars(grain,CPFEM_in,cp_en), state_new(i)/=0.0_pReal) &
|
||||||
|
RstateS(i) = Rstate(i)/state_new(i)
|
||||||
|
state_new = state_old+dstate
|
||||||
|
if (maxval(abs(RstateS)) < tol_State) exit state
|
||||||
|
|
||||||
|
enddo state
|
||||||
|
! write(6,*) 'istate', istate
|
||||||
|
! write(999,*) 'Tstar_v raus', Tstar_v
|
||||||
|
! write(999,*)
|
||||||
|
|
||||||
|
invFp_new = matmul(invFp_old,B)
|
||||||
|
call math_invert3x3(invFp_new,Fp_new,det,failed)
|
||||||
|
if (failed) then
|
||||||
|
msg = 'inversion Fp_new'
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
Fp_new = Fp_new*det**(1.0_pReal/3.0_pReal) ! det = det(InvFp_new) !!
|
||||||
|
Fe_new = matmul(Fg_new,invFp_new)
|
||||||
|
return
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
FUNCTION CPFEM_CauchyStress(PK_v,Fe)
|
||||||
|
!***********************************************************************
|
||||||
|
!*** Cauchy stress calculation ***
|
||||||
|
!***********************************************************************
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
use math, only: math_Mandel33to6,math_Mandel6to33,math_det3x3
|
||||||
|
implicit none
|
||||||
|
! *** Subroutine parameters ***
|
||||||
|
real(pReal) PK_v(6), Fe(3,3), CPFEM_CauchyStress(6)
|
||||||
|
|
||||||
|
CPFEM_CauchyStress = math_Mandel33to6(matmul(matmul(Fe,math_Mandel6to33(PK_v)),transpose(Fe))/math_det3x3(Fe))
|
||||||
|
return
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
END MODULE
|
|
@ -0,0 +1,555 @@
|
||||||
|
|
||||||
|
!##############################################################
|
||||||
|
MODULE IO
|
||||||
|
!##############################################################
|
||||||
|
|
||||||
|
CONTAINS
|
||||||
|
!---------------------------
|
||||||
|
! function IO_open_file(unit,relPath)
|
||||||
|
! function IO_open_inputFile(unit)
|
||||||
|
! function IO_hybridIA(Nast,ODFfileName)
|
||||||
|
! private function hybridIA_reps(dV_V,steps,C)
|
||||||
|
! function IO_stringPos(line,maxN)
|
||||||
|
! function IO_stringValue(line,positions,pos)
|
||||||
|
! function IO_floatValue(line,positions,pos)
|
||||||
|
! function IO_intValue(line,positions,pos)
|
||||||
|
! function IO_fixedStringValue(line,ends,pos)
|
||||||
|
! function IO_fixedFloatValue(line,ends,pos)
|
||||||
|
! function IO_fixedFloatNoEValue(line,ends,pos)
|
||||||
|
! function IO_fixedIntValue(line,ends,pos)
|
||||||
|
! function IO_continousTntValues(unit,maxN)
|
||||||
|
! function IO_lc(line)
|
||||||
|
! subroutine IO_lcInplace(line)
|
||||||
|
! subroutine IO_error(ID)
|
||||||
|
!---------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! open existing file to given unit
|
||||||
|
! path to file is relative to working directory
|
||||||
|
!********************************************************************
|
||||||
|
logical FUNCTION IO_open_file(unit,relPath)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*), parameter :: pathSep = achar(47)//achar(92) ! /, \
|
||||||
|
character(len=*) relPath
|
||||||
|
integer(pInt) unit
|
||||||
|
character(256) path
|
||||||
|
|
||||||
|
inquire(6, name=path) ! determine outputfile
|
||||||
|
open(unit,status='old',err=100,file=path(1:scan(path,pathSep,back=.true.))//relPath)
|
||||||
|
IO_open_file = .true.
|
||||||
|
return
|
||||||
|
100 IO_open_file = .false.
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! open FEM inputfile to given unit
|
||||||
|
!********************************************************************
|
||||||
|
logical FUNCTION IO_open_inputFile(unit)
|
||||||
|
|
||||||
|
use prec, only: pReal, pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(256) outName
|
||||||
|
integer(pInt) unit, extPos
|
||||||
|
character(3) ext
|
||||||
|
|
||||||
|
inquire(6, name=outName) ! determine outputfileName
|
||||||
|
extPos = len_trim(outName)-2
|
||||||
|
if(outName(extPos:extPos+2)=='out') then
|
||||||
|
ext='dat' ! MARC
|
||||||
|
else
|
||||||
|
ext='inp' ! ABAQUS
|
||||||
|
end if
|
||||||
|
open(unit,status='old',err=100,file=outName(1:extPos-1)//ext)
|
||||||
|
IO_open_inputFile = .true.
|
||||||
|
return
|
||||||
|
100 IO_open_inputFile = .false.
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! hybrid IA repetition counter
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION hybridIA_reps(dV_V,steps,C)
|
||||||
|
|
||||||
|
use prec, only: pReal, pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt), intent(in), dimension(3) :: steps
|
||||||
|
integer(pInt) hybridIA_reps, phi1,Phi,phi2
|
||||||
|
real(pReal), intent(in), dimension(steps(3),steps(2),steps(1)) :: dV_V
|
||||||
|
real(pReal), intent(in) :: C
|
||||||
|
|
||||||
|
hybridIA_reps = 0_pInt
|
||||||
|
do phi1=1,steps(1)
|
||||||
|
do Phi =1,steps(2)
|
||||||
|
do phi2=1,steps(3)
|
||||||
|
hybridIA_reps = hybridIA_reps+nint(C*dV_V(phi2,Phi,phi1), pInt)
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! hybrid IA sampling of ODFfile
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_hybridIA(Nast,ODFfileName)
|
||||||
|
|
||||||
|
use prec, only: pReal, pInt
|
||||||
|
use math, only: inRad
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) ODFfileName
|
||||||
|
character(len=80) line
|
||||||
|
character(len=*), parameter :: fileFormat = '(A80)'
|
||||||
|
integer(pInt) i,j,bin,Nast,NnonZero,Nset,Nreps,reps,phi1,Phi,phi2
|
||||||
|
integer(pInt), dimension(7) :: pos
|
||||||
|
integer(pInt), dimension(3) :: steps
|
||||||
|
integer(pInt), dimension(:), allocatable :: binSet
|
||||||
|
real(pReal) center,sum_dV_V,prob,dg_0,C,lowerC,upperC,rnd
|
||||||
|
real(pReal), dimension(3) :: limits,deltas
|
||||||
|
real(pReal), dimension(:,:,:), allocatable :: dV_V
|
||||||
|
real(pReal), dimension(3,Nast) :: IO_hybridIA
|
||||||
|
|
||||||
|
if (.not. IO_open_file(999,ODFfileName)) goto 100
|
||||||
|
|
||||||
|
!--- parse header of ODF file ---
|
||||||
|
!--- limits in phi1, Phi, phi2 ---
|
||||||
|
read(999,fmt=fileFormat,end=100) line
|
||||||
|
pos = IO_stringPos(line,3)
|
||||||
|
if (pos(1).ne.3) goto 100
|
||||||
|
do i=1,3
|
||||||
|
limits(i) = IO_intValue(line,pos,i)*inRad
|
||||||
|
end do
|
||||||
|
|
||||||
|
!--- deltas in phi1, Phi, phi2 ---
|
||||||
|
read(999,fmt=fileFormat,end=100) line
|
||||||
|
pos = IO_stringPos(line,3)
|
||||||
|
if (pos(1).ne.3) goto 100
|
||||||
|
do i=1,3
|
||||||
|
deltas(i) = IO_intValue(line,pos,i)*inRad
|
||||||
|
end do
|
||||||
|
steps = nint(limits/deltas,pInt)
|
||||||
|
allocate(dV_V(steps(3),steps(2),steps(1)))
|
||||||
|
|
||||||
|
!--- box boundary/center at origin? ---
|
||||||
|
read(999,fmt=fileFormat,end=100) line
|
||||||
|
if (index(IO_lc(line),'bound')>0) then
|
||||||
|
center = 0.5_pReal
|
||||||
|
else
|
||||||
|
center = 0.0_pReal
|
||||||
|
end if
|
||||||
|
|
||||||
|
!--- skip blank line ---
|
||||||
|
read(999,fmt=fileFormat,end=100) line
|
||||||
|
|
||||||
|
sum_dV_V = 0.0_pReal
|
||||||
|
dV_V = 0.0_pReal
|
||||||
|
dg_0 = deltas(1)*deltas(3)*2.0_pReal*sin(deltas(2)/2.0_pReal)
|
||||||
|
NnonZero = 0_pInt
|
||||||
|
|
||||||
|
do phi1=1,steps(1)
|
||||||
|
do Phi=1,steps(2)
|
||||||
|
do phi2=1,steps(3)
|
||||||
|
read(999,fmt='(F)',end=100) prob
|
||||||
|
if (prob > 0.0_pReal) then
|
||||||
|
NnonZero = NnonZero+1
|
||||||
|
sum_dV_V = sum_dV_V+prob
|
||||||
|
else
|
||||||
|
prob = 0.0_pReal
|
||||||
|
end if
|
||||||
|
dV_V(phi2,Phi,phi1) = prob*dg_0*sin((Phi-1.0_pReal+center)*deltas(2))
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
|
||||||
|
dV_V = dV_V/sum_dV_V ! normalize to 1
|
||||||
|
|
||||||
|
!--- now fix bounds ---
|
||||||
|
Nset = max(Nast,NnonZero)
|
||||||
|
lowerC = 0.0_pReal
|
||||||
|
upperC = real(Nset, pReal)
|
||||||
|
|
||||||
|
do while (hybridIA_reps(dV_V,steps,upperC) < Nset)
|
||||||
|
lowerC = upperC
|
||||||
|
upperC = upperC*2.0_pReal
|
||||||
|
end do
|
||||||
|
!--- binary search for best C ---
|
||||||
|
do
|
||||||
|
C = (upperC+lowerC)/2.0_pReal
|
||||||
|
Nreps = hybridIA_reps(dV_V,steps,C)
|
||||||
|
if (abs(upperC-lowerC) < upperC*1.0e-14_pReal) then
|
||||||
|
C = upperC
|
||||||
|
Nreps = hybridIA_reps(dV_V,steps,C)
|
||||||
|
exit
|
||||||
|
elseif (Nreps < Nset) then
|
||||||
|
lowerC = C
|
||||||
|
elseif (Nreps > Nset) then
|
||||||
|
upperC = C
|
||||||
|
else
|
||||||
|
exit
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
|
||||||
|
allocate(binSet(Nreps))
|
||||||
|
bin = 0 ! bin counter
|
||||||
|
i = 1 ! set counter
|
||||||
|
do phi1=1,steps(1)
|
||||||
|
do Phi=1,steps(2)
|
||||||
|
do phi2=1,steps(3)
|
||||||
|
reps = nint(C*dV_V(phi2,Phi,phi1), pInt)
|
||||||
|
binSet(i:i+reps-1) = bin
|
||||||
|
bin = bin+1 ! advance bin
|
||||||
|
i = i+reps ! advance set
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
|
||||||
|
do i=1,Nast
|
||||||
|
if (i < Nast) then
|
||||||
|
call random_number(rnd)
|
||||||
|
j = nint(rnd*(Nast-i)+i+0.5_pReal,pInt)
|
||||||
|
else
|
||||||
|
j = i
|
||||||
|
end if
|
||||||
|
bin = binSet(j)
|
||||||
|
IO_hybridIA(1,i) = deltas(1)*(mod(bin/(steps(3)*steps(2)),steps(1))+center) ! phi1
|
||||||
|
IO_hybridIA(2,i) = deltas(2)*(mod(bin/ steps(3) ,steps(2))+center) ! Phi
|
||||||
|
IO_hybridIA(3,i) = deltas(3)*(mod(bin ,steps(3))+center) ! phi2
|
||||||
|
binSet(j) = binSet(i)
|
||||||
|
end do
|
||||||
|
close(999)
|
||||||
|
return
|
||||||
|
|
||||||
|
! on error
|
||||||
|
100 IO_hybridIA = -1
|
||||||
|
close(999)
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! locate at most N space-separated parts in line
|
||||||
|
! return array containing number of parts found and
|
||||||
|
! their left/right positions to be used by IO_xxxVal
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_stringPos (line,N)
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) line
|
||||||
|
character(len=*), parameter :: sep=achar(32)//achar(9)//achar(10)//achar(13) ! whitespaces
|
||||||
|
integer(pInt) N, part
|
||||||
|
integer(pInt) IO_stringPos(1+N*2)
|
||||||
|
|
||||||
|
IO_stringPos = -1
|
||||||
|
IO_stringPos(1) = 0
|
||||||
|
part = 1
|
||||||
|
do while ((N<1 .or. part<=N) .and. verify(line(IO_stringPos(part*2-1)+1:),sep)>0)
|
||||||
|
IO_stringPos(part*2) = IO_stringPos(part*2-1)+verify(line(IO_stringPos(part*2-1)+1:),sep)
|
||||||
|
IO_stringPos(part*2+1) = IO_stringPos(part*2)+scan(line(IO_stringPos(part*2):),sep)-2
|
||||||
|
part = part+1
|
||||||
|
end do
|
||||||
|
IO_stringPos(1) = part-1
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! read string value at pos from line
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_stringValue (line,positions,pos)
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) line
|
||||||
|
integer(pInt) positions(*),pos
|
||||||
|
character(len=1+positions(pos*2+1)-positions(pos*2)) IO_stringValue
|
||||||
|
|
||||||
|
if (positions(1) < pos) then
|
||||||
|
IO_stringValue = ''
|
||||||
|
else
|
||||||
|
IO_stringValue = line(positions(pos*2):positions(pos*2+1))
|
||||||
|
endif
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! read string value at pos from fixed format line
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_fixedStringValue (line,ends,pos)
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) line
|
||||||
|
integer(pInt) ends(*),pos
|
||||||
|
character(len=ends(pos+1)-ends(pos)) IO_fixedStringValue
|
||||||
|
|
||||||
|
IO_fixedStringValue = line(ends(pos)+1:ends(pos+1))
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! read float value at pos from line
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_floatValue (line,positions,pos)
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) line
|
||||||
|
real(pReal) IO_floatValue
|
||||||
|
integer(pInt) positions(*),pos
|
||||||
|
|
||||||
|
if (positions(1) >= pos) then
|
||||||
|
read(UNIT=line(positions(pos*2):positions(pos*2+1)),ERR=100,FMT=*) IO_floatValue
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
100 IO_floatValue = huge(1.0_pReal)
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! read float value at pos from fixed format line
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_fixedFloatValue (line,ends,pos)
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) line
|
||||||
|
real(pReal) IO_fixedFloatValue
|
||||||
|
integer(pInt) ends(*),pos
|
||||||
|
|
||||||
|
read(UNIT=line(ends(pos-1)+1:ends(pos)),ERR=100,FMT=*) IO_fixedFloatValue
|
||||||
|
return
|
||||||
|
100 IO_fixedFloatValue = huge(1.0_pReal)
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! read float x.y+z value at pos from format line line
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_fixedNoEFloatValue (line,ends,pos)
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) line
|
||||||
|
real(pReal) IO_fixedNoEFloatValue,base
|
||||||
|
integer(pInt) ends(*),pos,pos_exp,expon
|
||||||
|
|
||||||
|
pos_exp = scan(line(ends(pos)+1:ends(pos+1)),'+-',back=.true.)
|
||||||
|
if (pos_exp > 1) then
|
||||||
|
read(UNIT=line(ends(pos)+1:ends(pos)+pos_exp-1),ERR=100,FMT='(F)') base
|
||||||
|
read(UNIT=line(ends(pos)+pos_exp:ends(pos+1)),ERR=100,FMT='(I)') expon
|
||||||
|
else
|
||||||
|
read(UNIT=line(ends(pos)+1:ends(pos+1)),ERR=100,FMT=*) base
|
||||||
|
expon = 0_pInt
|
||||||
|
endif
|
||||||
|
IO_fixedNoEFloatValue = base*10.0_pReal**expon
|
||||||
|
return
|
||||||
|
100 IO_fixedNoEFloatValue = huge(1.0_pReal)
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! read int value at pos from line
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_intValue (line,positions,pos)
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) line
|
||||||
|
integer(pInt) IO_intValue
|
||||||
|
integer(pInt) positions(*),pos
|
||||||
|
|
||||||
|
if (positions(1) >= pos) then
|
||||||
|
read(UNIT=line(positions(pos*2):positions(pos*2+1)),ERR=100,FMT='(I)') IO_intValue
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
100 IO_intValue = huge(1_pInt)
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! read int value at pos from fixed format line
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_fixedIntValue (line,ends,pos)
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*) line
|
||||||
|
integer(pInt) IO_fixedIntValue
|
||||||
|
integer(pInt) ends(*),pos
|
||||||
|
|
||||||
|
read(UNIT=line(ends(pos)+1:ends(pos+1)),ERR=100,FMT='(I)') IO_fixedIntValue
|
||||||
|
return
|
||||||
|
100 IO_fixedIntValue = huge(1_pInt)
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! change character in line to lower case
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_lc (line)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character (len=*) line
|
||||||
|
character (len=len(line)) IO_lc
|
||||||
|
integer(pInt) i
|
||||||
|
|
||||||
|
IO_lc = line
|
||||||
|
do i=1,len(line)
|
||||||
|
if(64<iachar(line(i:i)) .and. iachar(line(i:i))<91) IO_lc(i:i)=achar(iachar(line(i:i))+32)
|
||||||
|
enddo
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! in place change of character in line to lower case
|
||||||
|
!********************************************************************
|
||||||
|
SUBROUTINE IO_lcInplace (line)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character (len=*) line
|
||||||
|
character (len=len(line)) IO_lc
|
||||||
|
integer(pInt) i
|
||||||
|
|
||||||
|
IO_lc = line
|
||||||
|
do i=1,len(line)
|
||||||
|
if(64<iachar(line(i:i)) .and. iachar(line(i:i))<91) IO_lc(i:i)=achar(iachar(line(i:i))+32)
|
||||||
|
enddo
|
||||||
|
line = IO_lc
|
||||||
|
return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! read consecutive lines of ints concatenatred by "c" as last char
|
||||||
|
! or range of values a "to" b
|
||||||
|
!********************************************************************
|
||||||
|
FUNCTION IO_continousIntValues (unit,maxN)
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt) unit,maxN,i
|
||||||
|
integer(pInt), dimension(1+maxN) :: IO_continousIntValues
|
||||||
|
integer(pInt), dimension(67) :: pos ! allow for 32 values excl "c"
|
||||||
|
character(len=300) line
|
||||||
|
|
||||||
|
IO_continousIntValues(1) = 0
|
||||||
|
do
|
||||||
|
read(unit,'(A300)',end=100) line
|
||||||
|
pos = IO_stringPos(line,33)
|
||||||
|
if (IO_lc(IO_stringValue(line,pos,2)) == 'to' ) then ! found range indicator
|
||||||
|
do i = IO_intValue(line,pos,1),IO_intValue(line,pos,3)
|
||||||
|
IO_continousIntValues(1) = IO_continousIntValues(1)+1
|
||||||
|
IO_continousIntValues(1+IO_continousIntValues(1)) = i
|
||||||
|
enddo
|
||||||
|
exit
|
||||||
|
else
|
||||||
|
do i = 1,pos(1)-1 ! interpret up to second to last value
|
||||||
|
IO_continousIntValues(1) = IO_continousIntValues(1)+1
|
||||||
|
IO_continousIntValues(1+IO_continousIntValues(1)) = IO_intValue(line,pos,i)
|
||||||
|
enddo
|
||||||
|
if ( IO_lc(IO_stringValue(line,pos,pos(1))) /= 'c' ) then ! line finished, read last value
|
||||||
|
IO_continousIntValues(1) = IO_continousIntValues(1)+1
|
||||||
|
IO_continousIntValues(1+IO_continousIntValues(1)) = IO_intValue(line,pos,pos(1))
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
100 return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! write error statements to standard out
|
||||||
|
! and terminate the Marc run with exit #9xxx
|
||||||
|
! in ABAQUS either time step is reduced or execution terminated
|
||||||
|
!********************************************************************
|
||||||
|
SUBROUTINE IO_error(ID)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt) ID
|
||||||
|
character(len=80) msg
|
||||||
|
|
||||||
|
select case (ID)
|
||||||
|
case (100)
|
||||||
|
msg='Unable to open input file.'
|
||||||
|
case (200)
|
||||||
|
msg='Error reading from material+texture file'
|
||||||
|
case (300)
|
||||||
|
msg='This material can only be used with &
|
||||||
|
&elements with three direct stress components'
|
||||||
|
case (400)
|
||||||
|
msg='Unknown alloy number specified'
|
||||||
|
case (500)
|
||||||
|
msg='Unknown lattice type specified'
|
||||||
|
case (600)
|
||||||
|
msg='Stress iteration did not converge'
|
||||||
|
case (700)
|
||||||
|
msg='Singular matrix in stress iteration'
|
||||||
|
case default
|
||||||
|
msg='Unknown error number'
|
||||||
|
end select
|
||||||
|
|
||||||
|
write(6,*) 'MPIE Material Routine Ver. 0.0 by the coding team'
|
||||||
|
write(6,*)
|
||||||
|
write(6,*) msg
|
||||||
|
call flush(6)
|
||||||
|
call quit(9000+ID)
|
||||||
|
! ABAQUS returns in some cases
|
||||||
|
return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
END MODULE IO
|
|
@ -0,0 +1,962 @@
|
||||||
|
|
||||||
|
!************************************
|
||||||
|
!* Module: CONSTITUTIVE *
|
||||||
|
!************************************
|
||||||
|
!* contains: *
|
||||||
|
!* - parameters definition *
|
||||||
|
!* - constitutive equations *
|
||||||
|
!* - orientations *
|
||||||
|
!************************************
|
||||||
|
|
||||||
|
MODULE constitutive
|
||||||
|
|
||||||
|
!*** Include other modules ***
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
! MISSING consistency check after reading 'mattex.mpie'
|
||||||
|
character(len=300), parameter :: mattexFile = 'mattex.mpie'
|
||||||
|
|
||||||
|
!*************************************
|
||||||
|
!* Definition of material properties *
|
||||||
|
!*************************************
|
||||||
|
!* Physical parameter, attack_frequency != Debye frequency
|
||||||
|
real(pReal), parameter :: attack_frequency = 1.0e10_pReal
|
||||||
|
!* Physical parameter, Boltzman constant in mJ/Kelvin
|
||||||
|
real(pReal), parameter :: Kb = 1.38e-20_pReal
|
||||||
|
|
||||||
|
!*************************************
|
||||||
|
!* Definition of material properties *
|
||||||
|
!*************************************
|
||||||
|
!* Number of materials
|
||||||
|
integer(pInt) material_maxN
|
||||||
|
!* Crystal structure and number of selected slip systems per material
|
||||||
|
integer(pInt), dimension(:) , allocatable :: material_CrystalStructure
|
||||||
|
integer(pInt), dimension(:) , allocatable :: material_Nslip
|
||||||
|
!* Maximum number of selected slip systems over materials
|
||||||
|
integer(pInt) material_maxNslip
|
||||||
|
!* Elastic constants and matrices
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_C11
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_C12
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_C13
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_C33
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_C44
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_Gmod
|
||||||
|
real(pReal), dimension(:,:,:), allocatable :: material_Cslip_66
|
||||||
|
!* Visco-plastic material parameters
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_rho0
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_bg
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_Qedge
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_tau0
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_c1
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_c2
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_c3
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_c4
|
||||||
|
real(pReal), dimension(:) , allocatable :: material_c5
|
||||||
|
real(pReal), dimension(:,:) , allocatable :: material_SlipIntCoeff
|
||||||
|
|
||||||
|
!************************************
|
||||||
|
!* Definition of texture properties *
|
||||||
|
!************************************
|
||||||
|
!* Number of textures, maximum number of Gauss and Fiber components
|
||||||
|
integer(pInt) texture_maxN
|
||||||
|
integer(pInt) texture_maxNGauss
|
||||||
|
integer(pInt) texture_maxNFiber
|
||||||
|
!* Textures definition
|
||||||
|
character(len=80), dimension(:), allocatable :: texture_ODFfile
|
||||||
|
character(len=80), dimension(:), allocatable :: texture_symmetry
|
||||||
|
integer(pInt), dimension(:) , allocatable :: texture_Ngrains
|
||||||
|
integer(pInt), dimension(:) , allocatable :: texture_NGauss
|
||||||
|
integer(pInt),dimension(:) , allocatable :: texture_NFiber
|
||||||
|
integer(pInt),dimension(:) , allocatable :: texture_NRandom
|
||||||
|
integer(pInt),dimension(:) , allocatable :: texture_totalNgrains
|
||||||
|
real(pReal), dimension(:,:,:) , allocatable :: texture_Gauss
|
||||||
|
real(pReal), dimension(:,:,:) , allocatable :: texture_Fiber
|
||||||
|
real(pReal), dimension(:,:,:,:), allocatable :: constitutive_EulerAngles
|
||||||
|
|
||||||
|
!************************************
|
||||||
|
!* Grains *
|
||||||
|
!************************************
|
||||||
|
integer(pInt) constitutive_maxNgrains
|
||||||
|
integer(pInt), dimension(:,:) , allocatable :: constitutive_Ngrains
|
||||||
|
integer(pInt), dimension(:,:,:) , allocatable :: constitutive_matID
|
||||||
|
real(pReal), dimension(:,:,:) , allocatable :: constitutive_matVolFrac
|
||||||
|
integer(pInt), dimension(:,:,:) , allocatable :: constitutive_texID
|
||||||
|
real(pReal), dimension(:,:,:) , allocatable :: constitutive_texVolFrac
|
||||||
|
|
||||||
|
!************************************
|
||||||
|
!* State variables *
|
||||||
|
!************************************
|
||||||
|
integer(pInt) constitutive_maxNstatevars
|
||||||
|
integer(pInt), dimension(:,:,:), allocatable :: constitutive_Nstatevars
|
||||||
|
real(pReal), dimension(:,:,:,:), allocatable :: constitutive_state_old
|
||||||
|
real(pReal), dimension(:,:,:,:), allocatable :: constitutive_state_new
|
||||||
|
real(pReal), dimension(:) , allocatable :: constitutive_passing_stress
|
||||||
|
real(pReal), dimension(:) , allocatable :: constitutive_jump_width
|
||||||
|
real(pReal), dimension(:) , allocatable :: constitutive_activation_volume
|
||||||
|
real(pReal), dimension(:) , allocatable :: constitutive_rho_m
|
||||||
|
real(pReal), dimension(:) , allocatable :: constitutive_rho_f
|
||||||
|
real(pReal), dimension(:) , allocatable :: constitutive_rho_p
|
||||||
|
real(pReal), dimension(:) , allocatable :: constitutive_g0_slip
|
||||||
|
|
||||||
|
!************************************
|
||||||
|
!* Interaction matrices *
|
||||||
|
!************************************
|
||||||
|
real(pReal), dimension(:,:,:), allocatable :: constitutive_Pforest
|
||||||
|
real(pReal), dimension(:,:,:), allocatable :: constitutive_Pparallel
|
||||||
|
|
||||||
|
!************************************
|
||||||
|
!* Results *
|
||||||
|
!************************************
|
||||||
|
integer(pInt) constitutive_maxNresults
|
||||||
|
integer(pInt), dimension(:,:,:), allocatable :: constitutive_Nresults
|
||||||
|
real(pReal), dimension(:,:,:,:), allocatable :: constitutive_results
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CONTAINS
|
||||||
|
!****************************************
|
||||||
|
!* - constitutive_Init
|
||||||
|
!* - constitutive_CountSections
|
||||||
|
!* - constitutive_Parse_UnknownPart
|
||||||
|
!* - constitutive_Parse_MaterialPart
|
||||||
|
!* - constitutive_Parse_TexturePart
|
||||||
|
!* - constitutive_Parse_MatTexDat
|
||||||
|
!* - constitutive_Assignment
|
||||||
|
!* - constitutive_HomogenizedC
|
||||||
|
!* - constitutive_Microstructure
|
||||||
|
!* - constitutive_LpAndItsTangent
|
||||||
|
!* - consistutive_DotState
|
||||||
|
!****************************************
|
||||||
|
|
||||||
|
|
||||||
|
subroutine constitutive_Init()
|
||||||
|
!**************************************
|
||||||
|
!* Module initialization *
|
||||||
|
!**************************************
|
||||||
|
call constitutive_Parse_MatTexDat(mattexFile)
|
||||||
|
call constitutive_Assignment()
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
|
||||||
|
subroutine constitutive_CountSections(file,count,part)
|
||||||
|
!*********************************************************************
|
||||||
|
!* This subroutine reads a "part" from the input file until the next *
|
||||||
|
!* part is reached and counts the number of "sections" in the part *
|
||||||
|
!* INPUT: *
|
||||||
|
!* - file : file ID *
|
||||||
|
!* OUTPUT: *
|
||||||
|
!* - part : name of the next "part" *
|
||||||
|
!* - count : number of sections inside the current "part" *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO, only: IO_stringPos,IO_stringValue,IO_lc
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
character(len=80) part,line,tag
|
||||||
|
integer(pInt) file,count
|
||||||
|
integer(pInt), dimension(3) :: positions
|
||||||
|
|
||||||
|
count=0
|
||||||
|
part=''
|
||||||
|
|
||||||
|
do
|
||||||
|
read(file,'(a80)',END=100) line
|
||||||
|
positions=IO_stringPos(line,1)
|
||||||
|
tag=IO_lc(IO_stringValue(line,positions,1))
|
||||||
|
if (tag(1:1)=='#' .OR. positions(1)==0) then ! skip comment and empty lines
|
||||||
|
cycle
|
||||||
|
elseif (tag(1:1)=='<'.AND.tag(len_trim(tag):len_trim(tag))=='>') then
|
||||||
|
part=tag(2:len_trim(tag)-1)
|
||||||
|
exit
|
||||||
|
elseif (tag(1:1)=='[') then
|
||||||
|
count=count+1
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
100 return
|
||||||
|
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
|
||||||
|
character(len=80) function constitutive_assignNGaussAndFiber(file)
|
||||||
|
!*********************************************************************
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO, only: IO_stringPos,IO_stringValue,IO_lc
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
character(len=80) line,tag
|
||||||
|
integer(pInt) file,section
|
||||||
|
integer(pInt), dimension(3) :: positions
|
||||||
|
|
||||||
|
constitutive_assignNGaussAndFiber=''
|
||||||
|
section = 0_pInt
|
||||||
|
|
||||||
|
do
|
||||||
|
read(file,'(a80)',END=100) line
|
||||||
|
positions=IO_stringPos(line,1)
|
||||||
|
tag=IO_lc(IO_stringValue(line,positions,1))
|
||||||
|
if (tag(1:1)=='#' .OR. positions(1)==0) then ! skip comment and empty lines
|
||||||
|
cycle
|
||||||
|
elseif (tag(1:1)=='<'.AND.tag(len_trim(tag):len_trim(tag))=='>') then
|
||||||
|
constitutive_assignNGaussAndFiber=tag(2:len_trim(tag)-1)
|
||||||
|
exit
|
||||||
|
elseif (tag(1:1)=='[') then
|
||||||
|
section=section+1
|
||||||
|
texture_NGauss(section) = 0_pInt
|
||||||
|
texture_NFiber(section) = 0_pInt
|
||||||
|
elseif (tag=='(gauss)') then
|
||||||
|
texture_NGauss(section)=texture_NGauss(section)+1
|
||||||
|
elseif (tag=='(fiber)') then
|
||||||
|
texture_NFiber(section)=texture_NFiber(section)+1
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
100 return
|
||||||
|
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
character(len=80) function constitutive_Parse_UnknownPart(file)
|
||||||
|
!*********************************************************************
|
||||||
|
!* read an unknown "part" from the input file until *
|
||||||
|
!* the next part is reached *
|
||||||
|
!* INPUT: *
|
||||||
|
!* - file : file ID *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO, only: IO_stringPos,IO_stringValue,IO_lc
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
character(len=80) line,tag
|
||||||
|
integer(pInt), parameter :: maxNchunks = 1
|
||||||
|
integer(pInt) file
|
||||||
|
integer(pInt), dimension(1+2*maxNchunks) :: positions
|
||||||
|
|
||||||
|
constitutive_parse_unknownPart=''
|
||||||
|
|
||||||
|
do
|
||||||
|
read(file,'(a80)',END=100) line
|
||||||
|
positions=IO_stringPos(line,maxNchunks)
|
||||||
|
tag=IO_lc(IO_stringValue(line,positions,1))
|
||||||
|
if (tag(1:1)=='#' .OR. positions(1)==0) then ! skip comment and empty lines
|
||||||
|
cycle
|
||||||
|
elseif (tag(1:1)=='<'.AND.tag(len_trim(tag):len_trim(tag))=='>') then
|
||||||
|
constitutive_Parse_UnknownPart=tag(2:len_trim(tag)-1)
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
100 return
|
||||||
|
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
character(len=80) function constitutive_Parse_MaterialPart(file)
|
||||||
|
!*********************************************************************
|
||||||
|
!* This function reads a material "part" from the input file until *
|
||||||
|
!* the next part is reached *
|
||||||
|
!* INPUT: *
|
||||||
|
!* - file : file ID *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pInt,pReal
|
||||||
|
use IO
|
||||||
|
use crystal, only: crystal_MaxMaxNslipOfStructure
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
character(len=80) line,tag
|
||||||
|
integer(pInt), parameter :: maxNchunks = 2
|
||||||
|
integer(pInt) i,file,section
|
||||||
|
integer(pInt), dimension(1+2*maxNchunks) :: positions
|
||||||
|
|
||||||
|
section = 0
|
||||||
|
constitutive_parse_materialPart = ''
|
||||||
|
|
||||||
|
do while(.true.)
|
||||||
|
read(file,'(a80)',END=100) line
|
||||||
|
positions=IO_stringPos(line,maxNchunks) ! parse leading chunks
|
||||||
|
tag=IO_lc(IO_stringValue(line,positions,1))
|
||||||
|
if (tag(1:1)=='#' .OR. positions(1)==0) then ! skip comment and empty lines
|
||||||
|
cycle
|
||||||
|
elseif (tag(1:1)=='<'.AND.tag(len_trim(tag):len_trim(tag))=='>') then
|
||||||
|
constitutive_parse_materialPart=tag(2:len_trim(tag)-1)
|
||||||
|
exit
|
||||||
|
elseif (tag(1:1)=='[') then
|
||||||
|
section=section+1
|
||||||
|
else
|
||||||
|
if (section>0) then
|
||||||
|
select case(tag)
|
||||||
|
case ('crystal_structure')
|
||||||
|
material_CrystalStructure(section)=IO_intValue(line,positions,2)
|
||||||
|
case ('nslip')
|
||||||
|
material_Nslip(section)=IO_intValue(line,positions,2)
|
||||||
|
case ('c11')
|
||||||
|
material_C11(section)=IO_floatValue(line,positions,2)
|
||||||
|
case ('c12')
|
||||||
|
material_C12(section)=IO_floatValue(line,positions,2)
|
||||||
|
case ('c13')
|
||||||
|
material_C13(section)=IO_floatValue(line,positions,2)
|
||||||
|
case ('c33')
|
||||||
|
material_C33(section)=IO_floatValue(line,positions,2)
|
||||||
|
case ('c44')
|
||||||
|
material_C44(section)=IO_floatValue(line,positions,2)
|
||||||
|
case ('rho0') !* conversion in 1/mm²
|
||||||
|
material_rho0(section)=IO_floatValue(line,positions,2)/1.0e6_pReal
|
||||||
|
case ('interaction_coefficient')
|
||||||
|
do i=1,crystal_MaxMaxNslipOfStructure
|
||||||
|
material_SlipIntCoeff(i,section)=IO_floatValue(line,positions,i+1)
|
||||||
|
enddo
|
||||||
|
case ('bg') !* conversion in mm
|
||||||
|
material_bg(section)=IO_floatValue(line,positions,2)*1.0e3_pReal
|
||||||
|
case ('Qedge') !* conversion in mJ/Kelvin
|
||||||
|
material_Qedge(section)=IO_floatValue(line,positions,2)*1.0e3_pReal
|
||||||
|
case ('tau0')
|
||||||
|
material_tau0(section)=IO_floatValue(line,positions,2)
|
||||||
|
case ('c1')
|
||||||
|
material_c1(section)=IO_floatValue(line,positions,2)
|
||||||
|
case ('c2')
|
||||||
|
material_c2(section)=IO_floatValue(line,positions,2)
|
||||||
|
case ('c3')
|
||||||
|
material_c3(section)=IO_floatValue(line,positions,2)
|
||||||
|
case ('c4')
|
||||||
|
material_c4(section)=IO_floatValue(line,positions,2)
|
||||||
|
case ('c5')
|
||||||
|
material_c5(section)=IO_floatValue(line,positions,2)
|
||||||
|
end select
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
100 return
|
||||||
|
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
character(len=80) function constitutive_Parse_TexturePart(file)
|
||||||
|
!*********************************************************************
|
||||||
|
!* This function reads a texture "part" from the input file until *
|
||||||
|
!* the next part is reached *
|
||||||
|
!* INPUT: *
|
||||||
|
!* - file : file ID *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO
|
||||||
|
use math, only: inRad
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
character(len=80) line,tag
|
||||||
|
integer(pInt), parameter :: maxNchunks = 13 ! may be more than 10 chunks ..?
|
||||||
|
integer(pInt) file,section,gaussCount,fiberCount,i
|
||||||
|
integer(pInt), dimension(1+2*maxNchunks) :: positions
|
||||||
|
|
||||||
|
section = 0
|
||||||
|
gaussCount = 0
|
||||||
|
fiberCount = 0
|
||||||
|
constitutive_parse_texturePart = ''
|
||||||
|
|
||||||
|
do while(.true.)
|
||||||
|
read(file,'(a80)',END=100) line
|
||||||
|
positions=IO_stringPos(line,maxNchunks) ! parse leading chunks
|
||||||
|
tag=IO_lc(IO_stringValue(line,positions,1))
|
||||||
|
if (tag(1:1)=='#' .OR. positions(1)==0) then ! skip comment and empty lines
|
||||||
|
cycle
|
||||||
|
elseif (tag(1:1)=='<'.AND.tag(len_trim(tag):len_trim(tag))=='>') then
|
||||||
|
constitutive_parse_texturePart=tag(2:len_trim(tag)-1)
|
||||||
|
exit
|
||||||
|
elseif (tag(1:1)=='[') then
|
||||||
|
section=section+1
|
||||||
|
gaussCount=0
|
||||||
|
fiberCount=0
|
||||||
|
else
|
||||||
|
if (section>0) then
|
||||||
|
select case(tag)
|
||||||
|
case ('hybridIA')
|
||||||
|
texture_ODFfile(section)=IO_stringValue(line,positions,2)
|
||||||
|
case ('(gauss)')
|
||||||
|
gaussCount=gaussCount+1
|
||||||
|
do i=2,10,2
|
||||||
|
tag=IO_lc(IO_stringValue(line,positions,i))
|
||||||
|
select case (tag)
|
||||||
|
case('phi1')
|
||||||
|
texture_Gauss(1,gaussCount,section)=IO_floatValue(line,positions,i+1)*inRad
|
||||||
|
case('phi')
|
||||||
|
texture_Gauss(2,gaussCount,section)=IO_floatValue(line,positions,i+1)*inRad
|
||||||
|
case('phi2')
|
||||||
|
texture_Gauss(3,gaussCount,section)=IO_floatValue(line,positions,i+1)*inRad
|
||||||
|
case('scatter')
|
||||||
|
texture_Gauss(4,gaussCount,section)=IO_floatValue(line,positions,i+1)*inRad
|
||||||
|
case('fraction')
|
||||||
|
texture_Gauss(5,gaussCount,section)=IO_floatValue(line,positions,i+1)
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
case ('(fiber)')
|
||||||
|
fiberCount=fiberCount+1
|
||||||
|
do i=2,12,2
|
||||||
|
tag=IO_lc(IO_stringValue(line,positions,i))
|
||||||
|
select case (tag)
|
||||||
|
case('alpha1')
|
||||||
|
texture_fiber(1,fiberCount,section)=IO_floatValue(line,positions,i+1)*inRad
|
||||||
|
case('alpha2')
|
||||||
|
texture_fiber(2,fiberCount,section)=IO_floatValue(line,positions,i+1)*inRad
|
||||||
|
case('beta1')
|
||||||
|
texture_fiber(3,fiberCount,section)=IO_floatValue(line,positions,i+1)*inRad
|
||||||
|
case('beta2')
|
||||||
|
texture_fiber(4,fiberCount,section)=IO_floatValue(line,positions,i+1)*inRad
|
||||||
|
case('scatter')
|
||||||
|
texture_fiber(5,fiberCount,section)=IO_floatValue(line,positions,i+1)*inRad
|
||||||
|
case('fraction')
|
||||||
|
texture_fiber(6,fiberCount,section)=IO_floatValue(line,positions,i+1)
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
case ('ngrains')
|
||||||
|
texture_Ngrains(section)=IO_intValue(line,positions,2)
|
||||||
|
case ('symmetry')
|
||||||
|
texture_symmetry(section)=IO_stringValue(line,positions,2)
|
||||||
|
end select
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
100 return
|
||||||
|
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
subroutine constitutive_Parse_MatTexDat(filename)
|
||||||
|
!*********************************************************************
|
||||||
|
!* This function reads the material and texture input file *
|
||||||
|
!* INPUT: *
|
||||||
|
!* - filename : name of input file *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
use IO, only: IO_error, IO_open_file
|
||||||
|
use math, only: math_Mandel3333to66, math_Voigt66to3333
|
||||||
|
use crystal, only: crystal_MaxMaxNslipOfStructure
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
character(len=*) filename
|
||||||
|
character(len=80) part,formerPart
|
||||||
|
integer(pInt) sectionCount,i,j,k, fileunit
|
||||||
|
|
||||||
|
! set fileunit
|
||||||
|
fileunit=200
|
||||||
|
!-----------------------------
|
||||||
|
!* First reading: number of materials and textures
|
||||||
|
!-----------------------------
|
||||||
|
!* determine material_maxN and texture_maxN from last respective parts
|
||||||
|
if(IO_open_file(fileunit,filename)==.false.) goto 100
|
||||||
|
part = '_dummy_'
|
||||||
|
do while (part/='')
|
||||||
|
formerPart = part
|
||||||
|
call constitutive_CountSections(fileunit,sectionCount,part)
|
||||||
|
select case (formerPart)
|
||||||
|
case ('materials')
|
||||||
|
material_maxN = sectionCount
|
||||||
|
case ('textures')
|
||||||
|
texture_maxN = sectionCount
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
!* Array allocation
|
||||||
|
allocate(material_CrystalStructure(material_maxN)) ; material_CrystalStructure=0_pInt
|
||||||
|
allocate(material_Nslip(material_maxN)) ; material_Nslip=0_pInt
|
||||||
|
allocate(material_C11(material_maxN)) ; material_C11=0.0_pReal
|
||||||
|
allocate(material_C12(material_maxN)) ; material_C12=0.0_pReal
|
||||||
|
allocate(material_C13(material_maxN)) ; material_C13=0.0_pReal
|
||||||
|
allocate(material_C33(material_maxN)) ; material_C33=0.0_pReal
|
||||||
|
allocate(material_C44(material_maxN)) ; material_C44=0.0_pReal
|
||||||
|
allocate(material_Gmod(material_maxN)) ; material_Gmod=0.0_pReal
|
||||||
|
allocate(material_Cslip_66(6,6,material_maxN)) ; material_Cslip_66=0.0_pReal
|
||||||
|
allocate(material_rho0(material_maxN)) ; material_rho0=0.0_pReal
|
||||||
|
allocate(material_SlipIntCoeff(crystal_MaxMaxNslipOfStructure,material_maxN)) ; material_SlipIntCoeff=0.0_pReal
|
||||||
|
allocate(material_bg(material_maxN)) ; material_bg=0.0_pReal
|
||||||
|
allocate(material_Qedge(material_maxN)) ; material_Qedge=0.0_pReal
|
||||||
|
allocate(material_tau0(material_maxN)) ; material_tau0=0.0_pReal
|
||||||
|
allocate(material_c1(material_maxN)) ; material_c1=0.0_pReal
|
||||||
|
allocate(material_c2(material_maxN)) ; material_c2=0.0_pReal
|
||||||
|
allocate(material_c3(material_maxN)) ; material_c3=0.0_pReal
|
||||||
|
allocate(material_c4(material_maxN)) ; material_c4=0.0_pReal
|
||||||
|
allocate(material_c5(material_maxN)) ; material_c5=0.0_pReal
|
||||||
|
allocate(texture_ODFfile(texture_maxN)) ; texture_ODFfile=''
|
||||||
|
allocate(texture_Ngrains(texture_maxN)) ; texture_Ngrains=0_pInt
|
||||||
|
allocate(texture_symmetry(texture_maxN)) ; texture_symmetry=''
|
||||||
|
allocate(texture_NGauss(texture_maxN)) ; texture_NGauss=0_pInt
|
||||||
|
allocate(texture_NFiber(texture_maxN)) ; texture_NFiber=0_pInt
|
||||||
|
allocate(texture_NRandom(texture_maxN)) ; texture_NRandom=0_pInt
|
||||||
|
|
||||||
|
!-----------------------------
|
||||||
|
!* Second reading: number of Gauss and Fiber
|
||||||
|
!-----------------------------
|
||||||
|
rewind(fileunit)
|
||||||
|
part = '_dummy_'
|
||||||
|
do while (part/='')
|
||||||
|
select case (part)
|
||||||
|
case ('textures')
|
||||||
|
part = constitutive_assignNGaussAndFiber(fileunit)
|
||||||
|
case default
|
||||||
|
part = constitutive_Parse_UnknownPart(fileunit)
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
!* Array allocation
|
||||||
|
texture_maxNGauss=maxval(texture_NGauss)
|
||||||
|
texture_maxNFiber=maxval(texture_NFiber)
|
||||||
|
allocate(texture_Gauss(5,texture_maxNGauss,texture_maxN)) ; texture_Gauss=0.0_pReal
|
||||||
|
allocate(texture_Fiber(6,texture_maxNFiber,texture_maxN)) ; texture_Fiber=0.0_pReal
|
||||||
|
|
||||||
|
!-----------------------------
|
||||||
|
!* Third reading: materials and textures are stored
|
||||||
|
!-----------------------------
|
||||||
|
rewind(fileunit)
|
||||||
|
part='_dummy_'
|
||||||
|
do while (part/='')
|
||||||
|
select case (part)
|
||||||
|
case ('materials')
|
||||||
|
part=constitutive_Parse_MaterialPart(fileunit)
|
||||||
|
case ('textures')
|
||||||
|
part=constitutive_Parse_TexturePart(fileunit)
|
||||||
|
case default
|
||||||
|
part=constitutive_Parse_UnknownPart(fileunit)
|
||||||
|
end select
|
||||||
|
enddo
|
||||||
|
close(fileunit)
|
||||||
|
|
||||||
|
|
||||||
|
!* Construction of the elasticity matrices
|
||||||
|
do i=1,material_maxN
|
||||||
|
material_Gmod(i)=material_C44(i)
|
||||||
|
select case (material_CrystalStructure(i))
|
||||||
|
case(1:2) ! cubic(s)
|
||||||
|
do k=1,3
|
||||||
|
do j=1,3
|
||||||
|
material_Cslip_66(k,j,i)=material_C12(i)
|
||||||
|
enddo
|
||||||
|
material_Cslip_66(k,k,i)=material_C11(i)
|
||||||
|
material_Cslip_66(k+3,k+3,i)=material_C44(i)
|
||||||
|
enddo
|
||||||
|
case(3) ! hcp
|
||||||
|
material_Cslip_66(1,1,i)=material_C11(i)
|
||||||
|
material_Cslip_66(2,2,i)=material_C11(i)
|
||||||
|
material_Cslip_66(3,3,i)=material_C33(i)
|
||||||
|
material_Cslip_66(1,2,i)=material_C12(i)
|
||||||
|
material_Cslip_66(2,1,i)=material_C12(i)
|
||||||
|
material_Cslip_66(1,3,i)=material_C13(i)
|
||||||
|
material_Cslip_66(3,1,i)=material_C13(i)
|
||||||
|
material_Cslip_66(2,3,i)=material_C13(i)
|
||||||
|
material_Cslip_66(3,2,i)=material_C13(i)
|
||||||
|
material_Cslip_66(4,4,i)=material_C44(i)
|
||||||
|
material_Cslip_66(5,5,i)=material_C44(i)
|
||||||
|
material_Cslip_66(6,6,i)=0.5_pReal*(material_C11(i)-material_C12(i))
|
||||||
|
end select
|
||||||
|
material_Cslip_66(:,:,i) = math_Mandel3333to66(math_Voigt66to3333(material_Cslip_66(:,:,i)))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
|
||||||
|
! MISSING some consistency checks may be..?
|
||||||
|
! if ODFfile present then set NGauss NFiber =0
|
||||||
|
return
|
||||||
|
100 call IO_error(200) ! corrupt materials_textures file
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
|
||||||
|
subroutine constitutive_Assignment()
|
||||||
|
!*********************************************************************
|
||||||
|
!* This subroutine assign material parameters according to ipc,ip,el *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
use math, only: math_sampleGaussOri,math_sampleFiberOri,math_sampleRandomOri,math_symmetricEulers,math_EulerToR
|
||||||
|
use mesh, only: mesh_NcpElems,FE_Nips,FE_mapElemtype,mesh_maxNips,mesh_element
|
||||||
|
use IO, only: IO_hybridIA
|
||||||
|
use crystal, only: crystal_MaxNslipOfStructure,crystal_SlipIntType,crystal_sn,crystal_st
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
integer(pInt) e,i,j,k,l,m,o,g,s
|
||||||
|
integer(pInt) matID,texID
|
||||||
|
real(pReal) K_inter,x,y
|
||||||
|
integer(pInt), dimension(:,:,:), allocatable :: hybridIA_population
|
||||||
|
integer(pInt), dimension(texture_maxN) :: Ncomponents,Nsym,multiplicity,sumVolfrac,ODFmap,sampleCount
|
||||||
|
real(pReal), dimension(3,4*(1+texture_maxNGauss+texture_maxNfiber)) :: Euler
|
||||||
|
real(pReal), dimension(4*(1+texture_maxNGauss+texture_maxNfiber)) :: texVolfrac
|
||||||
|
|
||||||
|
! process textures
|
||||||
|
o = 0_pInt ! ODF counter
|
||||||
|
ODFmap = 0_pInt ! blank mapping
|
||||||
|
sampleCount = 0_pInt ! count orientations assigned per texture
|
||||||
|
|
||||||
|
do texID=1,texture_maxN
|
||||||
|
if (texture_ODFfile(texID)=='') then
|
||||||
|
sumVolfrac(texID) = sum(texture_gauss(5,:,texID))+sum(texture_fiber(6,:,texID))
|
||||||
|
if (sumVolfrac(texID)<1.0_pReal) texture_NRandom(texID) = 1_pInt ! check whether random component missing
|
||||||
|
select case (texture_symmetry(texID)) ! set symmetry factor
|
||||||
|
case ('orthotropic')
|
||||||
|
Nsym(texID) = 4_pInt
|
||||||
|
case ('monoclinic')
|
||||||
|
Nsym(texID) = 2_pInt
|
||||||
|
case default
|
||||||
|
Nsym(texID) = 1_pInt
|
||||||
|
end select
|
||||||
|
Ncomponents(texID) = texture_NGauss(texID)+texture_NFiber(texID)+texture_NRandom(texID)
|
||||||
|
else ! hybrid IA
|
||||||
|
o = o+1
|
||||||
|
ODFmap(texID) = o ! remember mapping
|
||||||
|
Ncomponents(texID) = 1_pInt ! single "component"
|
||||||
|
Nsym(texID) = 1_pInt ! no symmetry (use full ODF instead)
|
||||||
|
endif
|
||||||
|
! adjust multiplicity and number of grains per IP of components
|
||||||
|
multiplicity(texID) = max(1_pInt,texture_Ngrains(texID)/Ncomponents(texID)/Nsym(texID))
|
||||||
|
if (mod(texture_Ngrains(texID),Ncomponents(texID)*Nsym(texID)) /= 0_pInt) then
|
||||||
|
texture_Ngrains(texID) = multiplicity(texID)*Ncomponents(texID)*Nsym(texID)
|
||||||
|
write (6,*) 'changed Ngrains to',texture_Ngrains(texID),' for texture',texID
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
!* publish globals
|
||||||
|
constitutive_maxNgrains = maxval(texture_Ngrains)
|
||||||
|
constitutive_maxNstatevars = maxval(material_Nslip) + 0_pInt
|
||||||
|
constitutive_maxNresults = 1_pInt
|
||||||
|
|
||||||
|
!* calc texture_totalNgrains
|
||||||
|
allocate(texture_totalNgrains(texture_maxN)) ; texture_totalNgrains=0_pInt
|
||||||
|
do i=1,mesh_NcpElems
|
||||||
|
texID = mesh_element(4,i)
|
||||||
|
texture_totalNgrains(texID) = texture_totalNgrains(texID) + FE_Nips(FE_mapElemtype(mesh_element(2,i)))*texture_Ngrains(texID)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
! generate hybridIA samplings for ODFfile textures to later draw from these populations
|
||||||
|
allocate(hybridIA_population(3,maxval(texture_totalNgrains,ODFmap /= 0),o))
|
||||||
|
do texID = 1,texture_maxN
|
||||||
|
if (ODFmap(texID) > 0) &
|
||||||
|
hybridIA_population(:,:,ODFmap(texID)) = IO_hybridIA(texture_totalNgrains(texID),texture_ODFfile(texID))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
!* Array allocation
|
||||||
|
allocate(constitutive_Ngrains(mesh_maxNips,mesh_NcpElems)) ; constitutive_Ngrains=0_pInt
|
||||||
|
allocate(constitutive_matID(constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems)) ; constitutive_matID=0_pInt
|
||||||
|
allocate(constitutive_texID(constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems)) ; constitutive_texID=0_pInt
|
||||||
|
allocate(constitutive_MatVolFrac(constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems)) ; constitutive_MatVolFrac=0.0_pReal
|
||||||
|
allocate(constitutive_TexVolFrac(constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems)) ; constitutive_TexVolFrac=0.0_pReal
|
||||||
|
allocate(constitutive_EulerAngles(3,constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems)) ; constitutive_EulerAngles=0.0_pReal
|
||||||
|
allocate(constitutive_Nresults(constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems)) ; constitutive_Nresults=0_pInt
|
||||||
|
allocate(constitutive_results(constitutive_maxNresults,constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems))
|
||||||
|
constitutive_results=0.0_pReal
|
||||||
|
allocate(constitutive_Nstatevars(constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems)) ; constitutive_Nstatevars=0_pInt
|
||||||
|
allocate(constitutive_state_old(constitutive_maxNstatevars,constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems))
|
||||||
|
constitutive_state_old=0.0_pReal
|
||||||
|
allocate(constitutive_state_new(constitutive_maxNstatevars,constitutive_maxNgrains,mesh_maxNips,mesh_NcpElems))
|
||||||
|
constitutive_state_new=0.0_pReal
|
||||||
|
allocate(constitutive_Pforest(constitutive_maxNstatevars,constitutive_maxNstatevars,material_maxN))
|
||||||
|
constitutive_Pforest=0.0_pReal
|
||||||
|
allocate(constitutive_Pparallel(constitutive_maxNstatevars,constitutive_maxNstatevars,material_maxN))
|
||||||
|
constitutive_Pparallel=0.0_pReal
|
||||||
|
allocate(constitutive_rho_p(constitutive_maxNstatevars)) ; constitutive_rho_p=0.0_pReal
|
||||||
|
allocate(constitutive_rho_f(constitutive_maxNstatevars)) ; constitutive_rho_f=0.0_pReal
|
||||||
|
allocate(constitutive_rho_m(constitutive_maxNstatevars)) ; constitutive_rho_m=0.0_pReal
|
||||||
|
allocate(constitutive_passing_stress(constitutive_maxNstatevars)) ; constitutive_passing_stress=0.0_pReal
|
||||||
|
allocate(constitutive_jump_width(constitutive_maxNstatevars)) ; constitutive_jump_width=0.0_pReal
|
||||||
|
allocate(constitutive_activation_volume(constitutive_maxNstatevars)) ; constitutive_activation_volume=0.0_pReal
|
||||||
|
allocate(constitutive_g0_slip(constitutive_maxNstatevars)) ; constitutive_g0_slip=0.0_pReal
|
||||||
|
|
||||||
|
!* Assignment of all grains in all IPs of all cp-elements
|
||||||
|
do e=1,mesh_NcpElems
|
||||||
|
matID=mesh_element(3,e)
|
||||||
|
texID=mesh_element(4,e)
|
||||||
|
do i=1,FE_Nips(FE_mapElemtype(mesh_element(2,e)))
|
||||||
|
g = 0_pInt ! grain counter
|
||||||
|
do m = 1,multiplicity(texID)
|
||||||
|
o = 0_pInt ! component counter
|
||||||
|
if (texture_ODFfile(texID)=='') then
|
||||||
|
do k = 1,texture_nGauss(texID) ! *** gauss ***
|
||||||
|
o = o+1
|
||||||
|
Euler(:,o) = math_sampleGaussOri(texture_Gauss(1:3,k,texID),texture_Gauss(4,k,texID))
|
||||||
|
texVolFrac(o) = texture_Gauss(5,k,texID)
|
||||||
|
enddo
|
||||||
|
do k = 1,texture_nFiber(texID) ! *** fiber ***
|
||||||
|
o = o+1
|
||||||
|
Euler(:,o) = math_sampleFiberOri(texture_Fiber(1:2,k,texID),texture_Fiber(3:4,k,texID),texture_Fiber(5,k,texID))
|
||||||
|
texVolFrac(o) = texture_Fiber(6,k,texID)
|
||||||
|
enddo
|
||||||
|
do k = 1,texture_nRandom(texID) ! *** random ***
|
||||||
|
o = o+1
|
||||||
|
Euler(:,o) = math_sampleRandomOri()
|
||||||
|
texVolfrac(o) = 1.0_pReal-sumVolfrac(texID)
|
||||||
|
enddo
|
||||||
|
else ! *** hybrid IA ***
|
||||||
|
o = 1 ! only singular orientation, i.e. single "component"
|
||||||
|
Euler(:,o) = hybridIA_population(:,1+sampleCount(texID),ODFmap(texID))
|
||||||
|
texVolfrac(o) = 1.0_pReal
|
||||||
|
endif
|
||||||
|
if (Nsym(texID) > 1) then ! symmetry generates additional orientations
|
||||||
|
forall (k=1:o)
|
||||||
|
Euler(:,1+o+(Nsym(texID)-1)*(k-1):3+o+(Nsym(texID)-1)*(k-1)) = &
|
||||||
|
math_symmetricEulers(texture_symmetry(texID),Euler(:,k))
|
||||||
|
texVolfrac(1+o+(Nsym(texID)-1)*(k-1):3+o+(Nsym(texID)-1)*(k-1)) = texVolfrac(k)
|
||||||
|
end forall
|
||||||
|
endif
|
||||||
|
do s = 1,Nsym(texID)*o ! loop over orientations to be assigned to ip (ex multiplicity)
|
||||||
|
g = g+1 ! next "grain"
|
||||||
|
sampleCount(texID) = sampleCount(texID)+1 ! next member of population
|
||||||
|
constitutive_matID(g,i,e) = matID ! copy matID of element
|
||||||
|
constitutive_texID(g,i,e) = texID ! copy texID of element
|
||||||
|
constitutive_MatVolFrac(g,i,e) = 1.0_pReal ! singular material (so far)
|
||||||
|
constitutive_TexVolFrac(g,i,e) = texVolfrac(s)/multiplicity(texID)/Nsym(texID)
|
||||||
|
constitutive_Nstatevars(g,i,e) = material_Nslip(matID) ! number of state variables (i.e. tau_c of each slip system)
|
||||||
|
constitutive_Nresults(g,i,e) = 0 ! number of constitutive results
|
||||||
|
constitutive_EulerAngles(:,g,i,e) = Euler(:,s) ! store initial orientation
|
||||||
|
forall (l=1:constitutive_Nstatevars(g,i,e)) ! initialize state variables
|
||||||
|
constitutive_state_old(l,g,i,e) = material_rho0(matID)
|
||||||
|
constitutive_state_new(l,g,i,e) = material_rho0(matID)
|
||||||
|
end forall
|
||||||
|
enddo ! components
|
||||||
|
enddo ! multiplicity
|
||||||
|
enddo ! ip
|
||||||
|
enddo ! cp_element
|
||||||
|
|
||||||
|
|
||||||
|
!* Construction of the hardening matrices
|
||||||
|
do i=1,material_maxN
|
||||||
|
!* Iteration over the systems
|
||||||
|
do j=1,constitutive_maxNstatevars
|
||||||
|
do k=1,constitutive_maxNstatevars
|
||||||
|
!* Hardening type *
|
||||||
|
select case (crystal_SlipIntType(j,k,i))
|
||||||
|
case (0)
|
||||||
|
K_inter=0.0_pReal
|
||||||
|
case (1)
|
||||||
|
K_inter=material_SlipIntCoeff(1,i)
|
||||||
|
case (2)
|
||||||
|
K_inter=material_SlipIntCoeff(2,i)
|
||||||
|
case (3)
|
||||||
|
K_inter=material_SlipIntCoeff(3,i)
|
||||||
|
case (4)
|
||||||
|
K_inter=material_SlipIntCoeff(4,i)
|
||||||
|
case (5)
|
||||||
|
K_inter=material_SlipIntCoeff(5,i)
|
||||||
|
case (6)
|
||||||
|
K_inter=material_SlipIntCoeff(6,i)
|
||||||
|
end select
|
||||||
|
!* Projection of the dislocation *
|
||||||
|
x=dot_product(crystal_sn(:,j,i),crystal_st(:,k,i))
|
||||||
|
y=1.0_pReal-x**(2.0_pReal)
|
||||||
|
!* Interaction matrix *
|
||||||
|
constitutive_Pforest(j,k,i)=abs(x)*K_inter
|
||||||
|
if (y>0.0_pReal) then
|
||||||
|
constitutive_Pparallel(j,k,i)=sqrt(y)*K_inter
|
||||||
|
else
|
||||||
|
constitutive_Pparallel(j,k,i)=0.0_pReal
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
|
||||||
|
function constitutive_HomogenizedC(ipc,ip,el)
|
||||||
|
!*********************************************************************
|
||||||
|
!* This function returns the homogenized elacticity matrix *
|
||||||
|
!* INPUT: *
|
||||||
|
!* - ipc : component-ID of current integration point *
|
||||||
|
!* - ip : current integration point *
|
||||||
|
!* - el : current element *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
integer(pInt) ipc,ip,el
|
||||||
|
real(pReal), dimension(6,6) :: constitutive_homogenizedC
|
||||||
|
|
||||||
|
!* Homogenization scheme
|
||||||
|
constitutive_homogenizedC=constitutive_MatVolFrac(ipc,ip,el)*material_Cslip_66(:,:,constitutive_matID(ipc,ip,el))
|
||||||
|
|
||||||
|
return
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
subroutine constitutive_Microstructure(state,Tp,ipc,ip,el)
|
||||||
|
!*********************************************************************
|
||||||
|
!* This function calculates from state needed variables *
|
||||||
|
!* INPUT: *
|
||||||
|
!* - state : state variables *
|
||||||
|
!* - Tp : temperature *
|
||||||
|
!* - ipc : component-ID of current integration point *
|
||||||
|
!* - ip : current integration point *
|
||||||
|
!* - el : current element *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
integer(pInt) ipc,ip,el
|
||||||
|
integer(pInt) matID,i
|
||||||
|
real(pReal) Tp
|
||||||
|
real(pReal), dimension(constitutive_Nstatevars(ipc,ip,el)) :: state
|
||||||
|
|
||||||
|
!* Get the material-ID from the triplet(ipc,ip,el)
|
||||||
|
matID = constitutive_matID(ipc,ip,el)
|
||||||
|
|
||||||
|
!* Quantities derivated from state
|
||||||
|
constitutive_rho_f=matmul(constitutive_Pforest(1:constitutive_Nstatevars(ipc,ip,el),&
|
||||||
|
1:constitutive_Nstatevars(ipc,ip,el),matID),state)
|
||||||
|
constitutive_rho_p=matmul(constitutive_Pparallel(1:constitutive_Nstatevars(ipc,ip,el),&
|
||||||
|
1:constitutive_Nstatevars(ipc,ip,el),matID),state)
|
||||||
|
do i=1,material_Nslip(matID)
|
||||||
|
constitutive_passing_stress(i)=material_tau0(matID)+material_c1(matID)*material_Gmod(matID)*material_bg(matID)*&
|
||||||
|
sqrt(constitutive_rho_p(i))
|
||||||
|
constitutive_jump_width(i)=material_c2(matID)/sqrt(constitutive_rho_f(i))
|
||||||
|
constitutive_activation_volume(i)=material_c3(matID)*constitutive_jump_width(i)*material_bg(matID)**2.0_pReal
|
||||||
|
constitutive_rho_m(i)=(2.0_pReal*Kb*Tp*sqrt(constitutive_rho_p(i)))/&
|
||||||
|
(material_c1(matID)*material_c3(matID)*material_Gmod(matID)*constitutive_jump_width(i)*material_bg(matID)**3.0_pReal)
|
||||||
|
constitutive_g0_slip(i)=constitutive_rho_m(i)*material_bg(matID)*attack_frequency*constitutive_jump_width(i)*&
|
||||||
|
exp(-(material_Qedge(matID)+constitutive_passing_stress(i)*constitutive_activation_volume(i))/&
|
||||||
|
(Kb*Tp))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
|
||||||
|
subroutine constitutive_LpAndItsTangent(Lp,dLp_dTstar,Tstar_v,state,Tp,ipc,ip,el)
|
||||||
|
!*********************************************************************
|
||||||
|
!* This subroutine contains the constitutive equation for *
|
||||||
|
!* calculating the velocity gradient *
|
||||||
|
!* INPUT: *
|
||||||
|
!* - Tstar_v : 2nd Piola Kirchhoff stress tensor (Mandel) *
|
||||||
|
!* - state : current microstructure *
|
||||||
|
!* - Tp : temperature *
|
||||||
|
!* - ipc : component-ID of current integration point *
|
||||||
|
!* - ip : current integration point *
|
||||||
|
!* - el : current element *
|
||||||
|
!* OUTPUT: *
|
||||||
|
!* - Lp : plastic velocity gradient *
|
||||||
|
!* - dLp_dTstar : derivative of Lp (4th-order tensor) *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
use crystal, only: crystal_Sslip,crystal_Sslip_v
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
integer(pInt) ipc,ip,el
|
||||||
|
integer(pInt) matID,i,k,l,m,n
|
||||||
|
real(pReal) Tp
|
||||||
|
real(pReal), dimension(6) :: Tstar_v
|
||||||
|
real(pReal), dimension(3,3) :: Lp
|
||||||
|
real(pReal), dimension(3,3,3,3) :: dLp_dTstar
|
||||||
|
real(pReal), dimension(constitutive_Nstatevars(ipc,ip,el)) :: state,gdot_slip,dgdot_dtauslip,tau_slip
|
||||||
|
|
||||||
|
!* Get the material-ID from the triplet(ipc,ip,el)
|
||||||
|
matID = constitutive_matID(ipc,ip,el)
|
||||||
|
|
||||||
|
!* Calculation of Lp
|
||||||
|
Lp = 0.0_pReal
|
||||||
|
do i=1,material_Nslip(matID)
|
||||||
|
tau_slip(i)=dot_product(Tstar_v,crystal_Sslip_v(:,i,material_CrystalStructure(matID)))
|
||||||
|
gdot_slip(i)=constitutive_g0_slip(i)*sinh((abs(tau_slip(i))*constitutive_activation_volume(i))/(Kb*Tp))*&
|
||||||
|
sign(1.0_pReal,tau_slip(i))
|
||||||
|
Lp=Lp+gdot_slip(i)*crystal_Sslip(:,:,i,material_CrystalStructure(matID))
|
||||||
|
enddo
|
||||||
|
|
||||||
|
!* Calculation of the tangent of Lp
|
||||||
|
dLp_dTstar=0.0_pReal
|
||||||
|
do i=1,material_Nslip(matID)
|
||||||
|
dgdot_dtauslip(i)=((constitutive_g0_slip(i)*constitutive_activation_volume(i))/(Kb*Tp))*&
|
||||||
|
cosh((abs(tau_slip(i))*constitutive_activation_volume(i))/(Kb*Tp))
|
||||||
|
forall (k=1:3,l=1:3,m=1:3,n=1:3)
|
||||||
|
dLp_dTstar(k,l,m,n) = dLp_dTstar(k,l,m,n)+ &
|
||||||
|
dgdot_dtauslip(i)*crystal_Sslip(k,l,i,material_CrystalStructure(matID))* &
|
||||||
|
(crystal_Sslip(m,n,i,material_CrystalStructure(matID))+ &
|
||||||
|
crystal_Sslip(n,m,i,material_CrystalStructure(matID)))/2.0_pReal ! force m,n symmetry
|
||||||
|
endforall
|
||||||
|
enddo
|
||||||
|
|
||||||
|
return
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
|
||||||
|
function constitutive_dotState(Tstar_v,state,Tp,ipc,ip,el)
|
||||||
|
!*********************************************************************
|
||||||
|
!* This subroutine contains the constitutive equation for *
|
||||||
|
!* calculating the velocity gradient *
|
||||||
|
!* INPUT: *
|
||||||
|
!* - Tstar_v : 2nd Piola Kirchhoff stress tensor (Mandel) *
|
||||||
|
!* - state : current microstructure *
|
||||||
|
!* - Tp : temperature *
|
||||||
|
!* - ipc : component-ID of current integration point *
|
||||||
|
!* - ip : current integration point *
|
||||||
|
!* - el : current element *
|
||||||
|
!* OUTPUT: *
|
||||||
|
!* - constitutive_DotState : evolution of state variable *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
use crystal, only: crystal_Sslip_v
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
integer(pInt) ipc,ip,el
|
||||||
|
integer(pInt) matID,i
|
||||||
|
real(pReal) Tp,tau_slip,gdot_slip
|
||||||
|
real(pReal), dimension(6) :: Tstar_v
|
||||||
|
real(pReal), dimension(constitutive_Nstatevars(ipc,ip,el)) :: constitutive_dotState,state,lock,recovery
|
||||||
|
|
||||||
|
!* Get the material-ID from the triplet(ipc,ip,el)
|
||||||
|
matID = constitutive_matID(ipc,ip,el)
|
||||||
|
|
||||||
|
!* Hardening of each system
|
||||||
|
do i=1,constitutive_Nstatevars(ipc,ip,el)
|
||||||
|
tau_slip = dot_product(Tstar_v,crystal_Sslip_v(:,i,material_CrystalStructure(matID)))
|
||||||
|
gdot_slip = constitutive_g0_slip(i)*sinh((abs(tau_slip)*constitutive_activation_volume(i))/(Kb*Tp))*&
|
||||||
|
sign(1.0_pReal,tau_slip)
|
||||||
|
if (abs(tau_slip)>1.0e-20_pReal) then
|
||||||
|
lock(i)=(material_c4(matID)*sqrt(constitutive_rho_f(i))*abs(gdot_slip))/material_bg(matID)
|
||||||
|
recovery(i)=material_c5(matID)*state(i)*abs(gdot_slip)
|
||||||
|
constitutive_dotState(i)=lock(i)-recovery(i)
|
||||||
|
else
|
||||||
|
constitutive_dotState(i)=0.0_pReal
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
return
|
||||||
|
end function
|
||||||
|
|
||||||
|
|
||||||
|
function constitutive_post_results(Tstar_v,state,dt,Tp,ipc,ip,el)
|
||||||
|
!*********************************************************************
|
||||||
|
!* return array of constitutive results *
|
||||||
|
!* INPUT: *
|
||||||
|
!* - Tstar_v : 2nd Piola Kirchhoff stress tensor (Mandel) *
|
||||||
|
!* - state : current microstructure *
|
||||||
|
!* - dt : current time increment *
|
||||||
|
!* - Tp : temperature *
|
||||||
|
!* - ipc : component-ID of current integration point *
|
||||||
|
!* - ip : current integration point *
|
||||||
|
!* - el : current element *
|
||||||
|
!*********************************************************************
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
use crystal, only: crystal_Sslip_v
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
integer(pInt) ipc,ip,el
|
||||||
|
integer(pInt) matID,i
|
||||||
|
real(pReal) dt,Tp,tau_slip
|
||||||
|
real(pReal), dimension(6) :: Tstar_v
|
||||||
|
real(pReal), dimension(constitutive_Nstatevars(ipc,ip,el)) :: state
|
||||||
|
real(pReal), dimension(constitutive_Nresults(ipc,ip,el)) :: constitutive_post_results
|
||||||
|
|
||||||
|
!* Get the material-ID from the triplet(ipc,ip,el)
|
||||||
|
matID = constitutive_matID(ipc,ip,el)
|
||||||
|
|
||||||
|
if(constitutive_Nresults(ipc,ip,el)==0) return
|
||||||
|
|
||||||
|
do i=1,material_Nslip(matID)
|
||||||
|
constitutive_post_results(i) = state(i)
|
||||||
|
tau_slip=dot_product(Tstar_v,crystal_Sslip_v(:,i,material_CrystalStructure(matID)))
|
||||||
|
constitutive_post_results(i+material_Nslip(matID)) = &
|
||||||
|
dt*constitutive_g0_slip(i)*sinh((abs(tau_slip)*constitutive_activation_volume(i))/(Kb*Tp))*&
|
||||||
|
sign(1.0_pReal,tau_slip)
|
||||||
|
enddo
|
||||||
|
return
|
||||||
|
|
||||||
|
end function
|
||||||
|
|
||||||
|
END MODULE
|
|
@ -0,0 +1,282 @@
|
||||||
|
|
||||||
|
!************************************
|
||||||
|
!* Module: CRYSTAL *
|
||||||
|
!************************************
|
||||||
|
!* contains: *
|
||||||
|
!* - Crystal structure definition *
|
||||||
|
!* - Slip system definition *
|
||||||
|
!* - Schmid matrices calculation *
|
||||||
|
!* - Hardening matrices calculation *
|
||||||
|
!************************************
|
||||||
|
|
||||||
|
MODULE crystal
|
||||||
|
|
||||||
|
!*** Include other modules ***
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!************************************
|
||||||
|
!* Crystal structures *
|
||||||
|
!************************************
|
||||||
|
!* Number of crystal structures (1-FCC,2-BCC,3-HCP)
|
||||||
|
integer(pInt), parameter :: crystal_MaxCrystalStructure = 3
|
||||||
|
!* Total number of slip systems per crystal structure
|
||||||
|
!* (as to be changed according the definition of slip systems)
|
||||||
|
integer(pInt), dimension(crystal_MaxCrystalStructure), parameter :: crystal_MaxNslipOfStructure = &
|
||||||
|
reshape((/12,48,12/),(/crystal_MaxCrystalStructure/))
|
||||||
|
!* Maximum number of slip systems over crystal structures
|
||||||
|
integer(pInt), parameter :: crystal_MaxMaxNslipOfStructure = 48
|
||||||
|
!* Slip direction, slip normales and Schmid matrices
|
||||||
|
real(pReal), dimension(3,3,crystal_MaxMaxNslipOfStructure,crystal_MaxCrystalStructure) :: crystal_Sslip
|
||||||
|
real(pReal), dimension(6,crystal_MaxMaxNslipOfStructure,crystal_MaxCrystalStructure) :: crystal_Sslip_v
|
||||||
|
real(pReal), dimension(3,crystal_MaxMaxNslipOfStructure,crystal_MaxCrystalStructure) :: crystal_sn
|
||||||
|
real(pReal), dimension(3,crystal_MaxMaxNslipOfStructure,crystal_MaxCrystalStructure) :: crystal_sd
|
||||||
|
real(pReal), dimension(3,crystal_MaxMaxNslipOfStructure,crystal_MaxCrystalStructure) :: crystal_st
|
||||||
|
!* Slip_slip interaction matrices
|
||||||
|
integer(pInt), dimension(crystal_MaxMaxNslipOfStructure,crystal_MaxMaxNslipOfStructure,crystal_MaxCrystalStructure) :: &
|
||||||
|
crystal_SlipIntType
|
||||||
|
|
||||||
|
!*** Slip systems for FCC structures (1) ***
|
||||||
|
!* System {111}<110> Sort according Eisenlohr&Hantcherli
|
||||||
|
data crystal_sd(:, 1,1)/ 0, 1,-1/ ; data crystal_sn(:, 1,1)/ 1, 1, 1/
|
||||||
|
data crystal_sd(:, 2,1)/-1, 0, 1/ ; data crystal_sn(:, 2,1)/ 1, 1, 1/
|
||||||
|
data crystal_sd(:, 3,1)/ 1,-1, 0/ ; data crystal_sn(:, 3,1)/ 1, 1, 1/
|
||||||
|
data crystal_sd(:, 4,1)/ 0,-1,-1/ ; data crystal_sn(:, 4,1)/-1,-1, 1/
|
||||||
|
data crystal_sd(:, 5,1)/ 1, 0, 1/ ; data crystal_sn(:, 5,1)/-1,-1, 1/
|
||||||
|
data crystal_sd(:, 6,1)/-1, 1, 0/ ; data crystal_sn(:, 6,1)/-1,-1, 1/
|
||||||
|
data crystal_sd(:, 7,1)/ 0,-1, 1/ ; data crystal_sn(:, 7,1)/ 1,-1,-1/
|
||||||
|
data crystal_sd(:, 8,1)/-1, 0,-1/ ; data crystal_sn(:, 8,1)/ 1,-1,-1/
|
||||||
|
data crystal_sd(:, 9,1)/ 1, 1, 0/ ; data crystal_sn(:, 9,1)/ 1,-1,-1/
|
||||||
|
data crystal_sd(:,10,1)/ 0, 1, 1/ ; data crystal_sn(:,10,1)/-1, 1,-1/
|
||||||
|
data crystal_sd(:,11,1)/ 1, 0,-1/ ; data crystal_sn(:,11,1)/-1, 1,-1/
|
||||||
|
data crystal_sd(:,12,1)/-1,-1, 0/ ; data crystal_sn(:,12,1)/-1, 1,-1/
|
||||||
|
|
||||||
|
!*** Slip-Slip interactions for FCC structures (1) ***
|
||||||
|
data crystal_SlipIntType( 1,:,1)/1,2,2,4,6,5,3,5,5,4,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 2,:,1)/2,1,2,6,4,5,5,4,6,5,3,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 3,:,1)/2,2,1,5,5,3,5,6,4,6,5,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 4,:,1)/4,6,5,1,2,2,4,5,6,3,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 5,:,1)/6,4,5,2,1,2,5,3,5,5,4,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 6,:,1)/5,5,3,2,2,1,6,5,4,5,6,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 7,:,1)/3,5,5,4,5,6,1,2,2,4,6,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 8,:,1)/5,4,6,5,3,5,2,1,2,6,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 9,:,1)/5,6,4,6,5,4,2,2,1,5,5,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType(10,:,1)/4,5,6,3,5,5,4,6,5,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType(11,:,1)/5,3,5,5,4,6,6,4,5,2,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType(12,:,1)/6,5,4,5,6,4,5,5,3,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
|
||||||
|
!*** Slip systems for BCC structures (2) ***
|
||||||
|
!* System {110}<111>
|
||||||
|
!* Sort?
|
||||||
|
data crystal_sd(:, 1,2)/ 1,-1, 1/ ; data crystal_sn(:, 1,2)/ 0, 1, 1/
|
||||||
|
data crystal_sd(:, 2,2)/-1,-1, 1/ ; data crystal_sn(:, 2,2)/ 0, 1, 1/
|
||||||
|
data crystal_sd(:, 3,2)/ 1, 1, 1/ ; data crystal_sn(:, 3,2)/ 0,-1, 1/
|
||||||
|
data crystal_sd(:, 4,2)/-1, 1, 1/ ; data crystal_sn(:, 4,2)/ 0,-1, 1/
|
||||||
|
data crystal_sd(:, 5,2)/-1, 1, 1/ ; data crystal_sn(:, 5,2)/ 1, 0, 1/
|
||||||
|
data crystal_sd(:, 6,2)/-1,-1, 1/ ; data crystal_sn(:, 6,2)/ 1, 0, 1/
|
||||||
|
data crystal_sd(:, 7,2)/ 1, 1, 1/ ; data crystal_sn(:, 7,2)/-1, 0, 1/
|
||||||
|
data crystal_sd(:, 8,2)/ 1,-1, 1/ ; data crystal_sn(:, 8,2)/-1, 0, 1/
|
||||||
|
data crystal_sd(:, 9,2)/-1, 1, 1/ ; data crystal_sn(:, 9,2)/ 1, 1, 0/
|
||||||
|
data crystal_sd(:,10,2)/-1, 1,-1/ ; data crystal_sn(:,10,2)/ 1, 1, 0/
|
||||||
|
data crystal_sd(:,11,2)/ 1, 1, 1/ ; data crystal_sn(:,11,2)/-1, 1, 0/
|
||||||
|
data crystal_sd(:,12,2)/ 1, 1,-1/ ; data crystal_sn(:,12,2)/-1, 1, 0/
|
||||||
|
!* System {112}<111>
|
||||||
|
!* Sort?
|
||||||
|
data crystal_sd(:,13,2)/-1, 1, 1/ ; data crystal_sn(:,13,2)/ 2, 1, 1/
|
||||||
|
data crystal_sd(:,14,2)/ 1, 1, 1/ ; data crystal_sn(:,14,2)/-2, 1, 1/
|
||||||
|
data crystal_sd(:,15,2)/ 1, 1,-1/ ; data crystal_sn(:,15,2)/ 2,-1, 1/
|
||||||
|
data crystal_sd(:,16,2)/ 1,-1, 1/ ; data crystal_sn(:,16,2)/ 2, 1,-1/
|
||||||
|
data crystal_sd(:,17,2)/ 1,-1, 1/ ; data crystal_sn(:,17,2)/ 1, 2, 1/
|
||||||
|
data crystal_sd(:,18,2)/ 1, 1,-1/ ; data crystal_sn(:,18,2)/-1, 2, 1/
|
||||||
|
data crystal_sd(:,19,2)/ 1, 1, 1/ ; data crystal_sn(:,19,2)/ 1,-2, 1/
|
||||||
|
data crystal_sd(:,20,2)/-1, 1, 1/ ; data crystal_sn(:,20,2)/ 1, 2,-1/
|
||||||
|
data crystal_sd(:,21,2)/ 1, 1,-1/ ; data crystal_sn(:,21,2)/ 1, 1, 2/
|
||||||
|
data crystal_sd(:,22,2)/ 1,-1, 1/ ; data crystal_sn(:,22,2)/-1, 1, 2/
|
||||||
|
data crystal_sd(:,23,2)/-1, 1, 1/ ; data crystal_sn(:,23,2)/ 1,-1, 2/
|
||||||
|
data crystal_sd(:,24,2)/ 1, 1, 1/ ; data crystal_sn(:,24,2)/ 1, 1,-2/
|
||||||
|
!* System {123}<111>
|
||||||
|
!* Sort?
|
||||||
|
data crystal_sd(:,25,2)/ 1, 1,-1/ ; data crystal_sn(:,25,2)/ 1, 2, 3/
|
||||||
|
data crystal_sd(:,26,2)/ 1,-1, 1/ ; data crystal_sn(:,26,2)/-1, 2, 3/
|
||||||
|
data crystal_sd(:,27,2)/-1, 1, 1/ ; data crystal_sn(:,27,2)/ 1,-2, 3/
|
||||||
|
data crystal_sd(:,28,2)/ 1, 1, 1/ ; data crystal_sn(:,28,2)/ 1, 2,-3/
|
||||||
|
data crystal_sd(:,29,2)/ 1,-1, 1/ ; data crystal_sn(:,29,2)/ 1, 3, 2/
|
||||||
|
data crystal_sd(:,30,2)/ 1, 1,-1/ ; data crystal_sn(:,30,2)/-1, 3, 2/
|
||||||
|
data crystal_sd(:,31,2)/ 1, 1, 1/ ; data crystal_sn(:,31,2)/ 1,-3, 2/
|
||||||
|
data crystal_sd(:,32,2)/-1, 1, 1/ ; data crystal_sn(:,32,2)/ 1, 3,-2/
|
||||||
|
data crystal_sd(:,33,2)/ 1, 1,-1/ ; data crystal_sn(:,33,2)/ 2, 1, 3/
|
||||||
|
data crystal_sd(:,34,2)/ 1,-1, 1/ ; data crystal_sn(:,34,2)/-2, 1, 3/
|
||||||
|
data crystal_sd(:,35,2)/-1, 1, 1/ ; data crystal_sn(:,35,2)/ 2,-1, 3/
|
||||||
|
data crystal_sd(:,36,2)/ 1, 1, 1/ ; data crystal_sn(:,36,2)/ 2, 1,-3/
|
||||||
|
data crystal_sd(:,37,2)/ 1,-1, 1/ ; data crystal_sn(:,37,2)/ 2, 3, 1/
|
||||||
|
data crystal_sd(:,38,2)/ 1, 1,-1/ ; data crystal_sn(:,38,2)/-2, 3, 1/
|
||||||
|
data crystal_sd(:,39,2)/ 1, 1, 1/ ; data crystal_sn(:,39,2)/ 2,-3, 1/
|
||||||
|
data crystal_sd(:,40,2)/-1, 1, 1/ ; data crystal_sn(:,40,2)/ 2, 3,-1/
|
||||||
|
data crystal_sd(:,41,2)/-1, 1, 1/ ; data crystal_sn(:,41,2)/ 3, 1, 2/
|
||||||
|
data crystal_sd(:,42,2)/ 1, 1, 1/ ; data crystal_sn(:,42,2)/-3, 1, 2/
|
||||||
|
data crystal_sd(:,43,2)/ 1, 1,-1/ ; data crystal_sn(:,43,2)/ 3,-1, 2/
|
||||||
|
data crystal_sd(:,44,2)/ 1,-1, 1/ ; data crystal_sn(:,44,2)/ 3, 1,-2/
|
||||||
|
data crystal_sd(:,45,2)/-1, 1, 1/ ; data crystal_sn(:,45,2)/ 3, 2, 1/
|
||||||
|
data crystal_sd(:,46,2)/ 1, 1, 1/ ; data crystal_sn(:,46,2)/-3, 2, 1/
|
||||||
|
data crystal_sd(:,47,2)/ 1, 1,-1/ ; data crystal_sn(:,47,2)/ 3,-2, 1/
|
||||||
|
data crystal_sd(:,48,2)/ 1,-1, 1/ ; data crystal_sn(:,48,2)/ 3, 2,-1/
|
||||||
|
|
||||||
|
!*** Slip-Slip interactions for BCC structures (2) ***
|
||||||
|
data crystal_SlipIntType( 1,:,2)/1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType( 2,:,2)/2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType( 3,:,2)/2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType( 4,:,2)/2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType( 5,:,2)/2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType( 6,:,2)/2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType( 7,:,2)/2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType( 8,:,2)/2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType( 9,:,2)/2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(10,:,2)/2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(11,:,2)/2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(12,:,2)/2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(13,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(14,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(15,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(16,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(17,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(18,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(19,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(20,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(21,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(22,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(23,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(24,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(25,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(26,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(27,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(28,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(29,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(30,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(31,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(32,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(33,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(34,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(35,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(36,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(37,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(38,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(39,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(40,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(41,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(42,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(43,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(44,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2/
|
||||||
|
data crystal_SlipIntType(45,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2/
|
||||||
|
data crystal_SlipIntType(46,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2/
|
||||||
|
data crystal_SlipIntType(47,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2/
|
||||||
|
data crystal_SlipIntType(48,:,2)/2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1/
|
||||||
|
|
||||||
|
!*** Slip systems for HCP structures (3) ***
|
||||||
|
!* Basal systems {0001}<1120> (independent of c/a-ratio)
|
||||||
|
!* 1- (0 0 0 1)[-2 1 1 0]
|
||||||
|
!* 2- (0 0 0 1)[ 1 -2 1 0]
|
||||||
|
!* 3- (0 0 0 1)[ 1 1 -2 0]
|
||||||
|
!* Plane (hkil)->(hkl)
|
||||||
|
!* Direction [uvtw]->[(u-t) (v-t) w]
|
||||||
|
!* Automatical transformation from Bravais to Miller
|
||||||
|
!* not done for the moment
|
||||||
|
!* Sort?
|
||||||
|
data crystal_sd(:, 1,3)/-1, 0, 0/ ; data crystal_sn(:, 1,3)/ 0, 0, 1/
|
||||||
|
data crystal_sd(:, 2,3)/ 0,-1, 0/ ; data crystal_sn(:, 2,3)/ 0, 0, 1/
|
||||||
|
data crystal_sd(:, 3,3)/ 1, 1, 0/ ; data crystal_sn(:, 3,3)/ 0, 0, 1/
|
||||||
|
!* 1st type prismatic systems {1010}<1120> (independent of c/a-ratio)
|
||||||
|
!* 1- ( 0 1 -1 0)[-2 1 1 0]
|
||||||
|
!* 2- ( 1 0 -1 0)[ 1 -2 1 0]
|
||||||
|
!* 3- (-1 1 0 0)[ 1 1 -2 0]
|
||||||
|
!* Sort?
|
||||||
|
data crystal_sd(:, 4,3)/-1, 0, 0/ ; data crystal_sn(:, 4,3)/ 0, 1, 0/
|
||||||
|
data crystal_sd(:, 5,3)/ 0,-1, 0/ ; data crystal_sn(:, 5,3)/ 1, 0, 0/
|
||||||
|
data crystal_sd(:, 6,3)/ 1, 1, 0/ ; data crystal_sn(:, 6,3)/-1, 1, 0/
|
||||||
|
!* 1st type 1st order pyramidal systems {1011}<1120>
|
||||||
|
!* plane normales depend on the c/a-ratio
|
||||||
|
!* 1- ( 0 -1 1 1)[-2 1 1 0]
|
||||||
|
!* 2- ( 0 1 -1 1)[-2 1 1 0]
|
||||||
|
!* 3- (-1 0 1 1)[ 1 -2 1 0]
|
||||||
|
!* 4- ( 1 0 -1 1)[ 1 -2 1 0]
|
||||||
|
!* 5- (-1 1 0 1)[ 1 1 -2 0]
|
||||||
|
!* 6- ( 1 -1 0 1)[ 1 1 -2 0]
|
||||||
|
!* Sort?
|
||||||
|
data crystal_sd(:, 7,3)/-1, 0, 0/ ; data crystal_sn(:, 7,3)/ 0,-1, 1/
|
||||||
|
data crystal_sd(:, 8,3)/ 0,-1, 0/ ; data crystal_sn(:, 8,3)/ 0, 1, 1/
|
||||||
|
data crystal_sd(:, 9,3)/ 1, 1, 0/ ; data crystal_sn(:, 9,3)/-1, 0, 1/
|
||||||
|
data crystal_sd(:,10,3)/-1, 0, 0/ ; data crystal_sn(:,10,3)/ 1, 0, 1/
|
||||||
|
data crystal_sd(:,11,3)/ 0,-1, 0/ ; data crystal_sn(:,11,3)/-1, 1, 1/
|
||||||
|
data crystal_sd(:,12,3)/ 1, 1, 0/ ; data crystal_sn(:,12,3)/ 1,-1, 1/
|
||||||
|
|
||||||
|
!*** Slip-Slip interactions for HCP structures (3) ***
|
||||||
|
data crystal_SlipIntType( 1,:,3)/1,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 2,:,3)/2,1,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 3,:,3)/2,2,1,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 4,:,3)/2,2,2,1,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 5,:,3)/2,2,2,2,1,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 6,:,3)/2,2,2,2,2,1,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 7,:,3)/2,2,2,2,2,2,1,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 8,:,3)/2,2,2,2,2,2,2,1,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType( 9,:,3)/2,2,2,2,2,2,2,2,1,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType(10,:,3)/2,2,2,2,2,2,2,2,2,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType(11,:,3)/2,2,2,2,2,2,2,2,2,2,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
data crystal_SlipIntType(12,:,3)/2,2,2,2,2,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0/
|
||||||
|
|
||||||
|
CONTAINS
|
||||||
|
!****************************************
|
||||||
|
!* - crystal_Init
|
||||||
|
!* - crystal_SchmidMatrices
|
||||||
|
!* - crystal_HardeningMatrices
|
||||||
|
!****************************************
|
||||||
|
|
||||||
|
|
||||||
|
subroutine crystal_Init()
|
||||||
|
!**************************************
|
||||||
|
!* Module initialization *
|
||||||
|
!**************************************
|
||||||
|
call crystal_SchmidMatrices()
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
|
||||||
|
subroutine crystal_SchmidMatrices()
|
||||||
|
!**************************************
|
||||||
|
!* Calculation of Schmid matrices *
|
||||||
|
!**************************************
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
!* Definition of variables
|
||||||
|
integer(pInt) i,j,k,l
|
||||||
|
real(pReal) invNorm
|
||||||
|
|
||||||
|
!* Iteration over the crystal structures
|
||||||
|
do l=1,3
|
||||||
|
!* Iteration over the systems
|
||||||
|
do k=1,crystal_MaxNslipOfStructure(l)
|
||||||
|
!* Definition of transverse direction st for the frame (sd,st,sn)
|
||||||
|
crystal_st(1,k,l)=crystal_sn(2,k,l)*crystal_sd(3,k,l)-crystal_sn(3,k,l)*crystal_sd(2,k,l)
|
||||||
|
crystal_st(2,k,l)=crystal_sn(3,k,l)*crystal_sd(1,k,l)-crystal_sn(1,k,l)*crystal_sd(3,k,l)
|
||||||
|
crystal_st(3,k,l)=crystal_sn(1,k,l)*crystal_sd(2,k,l)-crystal_sn(2,k,l)*crystal_sd(1,k,l)
|
||||||
|
!* Defintion of Schmid matrix
|
||||||
|
forall (i=1:3,j=1:3)
|
||||||
|
crystal_Sslip(i,j,k,l)=crystal_sd(i,k,l)*crystal_sn(j,k,l)
|
||||||
|
endforall
|
||||||
|
!* Normalization of Schmid matrix
|
||||||
|
invNorm=dsqrt(1.0_pReal/((crystal_sn(1,k,l)**2+crystal_sn(2,k,l)**2+crystal_sn(3,k,l)**2)*&
|
||||||
|
(crystal_sd(1,k,l)**2+crystal_sd(2,k,l)**2+crystal_sd(3,k,l)**2)))
|
||||||
|
crystal_Sslip(:,:,k,l)=crystal_Sslip(:,:,k,l)*invNorm
|
||||||
|
!* Vectorization of normalized Schmid matrix
|
||||||
|
crystal_Sslip_v(1,k,l)=crystal_Sslip(1,1,k,l)
|
||||||
|
crystal_Sslip_v(2,k,l)=crystal_Sslip(2,2,k,l)
|
||||||
|
crystal_Sslip_v(3,k,l)=crystal_Sslip(3,3,k,l)
|
||||||
|
!* be compatible with Mandel notation of Tstar
|
||||||
|
crystal_Sslip_v(4,k,l)=(crystal_Sslip(1,2,k,l)+crystal_Sslip(2,1,k,l))/dsqrt(2.0_pReal)
|
||||||
|
crystal_Sslip_v(5,k,l)=(crystal_Sslip(2,3,k,l)+crystal_Sslip(3,2,k,l))/dsqrt(2.0_pReal)
|
||||||
|
crystal_Sslip_v(6,k,l)=(crystal_Sslip(1,3,k,l)+crystal_Sslip(3,1,k,l))/dsqrt(2.0_pReal)
|
||||||
|
enddo
|
||||||
|
enddo
|
||||||
|
|
||||||
|
end subroutine
|
||||||
|
|
||||||
|
|
||||||
|
END MODULE
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,24 @@
|
||||||
|
<materials>
|
||||||
|
[Aluminium]
|
||||||
|
temperature 293
|
||||||
|
crystal_structure 1
|
||||||
|
Nslip 12
|
||||||
|
C11 106.75e3
|
||||||
|
C12 60.41e3
|
||||||
|
C44 28.34e3
|
||||||
|
rho0 1.5e11
|
||||||
|
bg 2.86e-10
|
||||||
|
Qedge 3.0e-19
|
||||||
|
tau0 0.0
|
||||||
|
c1 0.1
|
||||||
|
c2 2.0
|
||||||
|
c3 0.4
|
||||||
|
c4 0.05
|
||||||
|
c5 10.0
|
||||||
|
interaction_coefficients 1.0 2.2 3.0 1.6 3.8 4.5
|
||||||
|
|
||||||
|
<textures>
|
||||||
|
[cube SX]
|
||||||
|
symmetry monoclinic
|
||||||
|
Ngrains 1
|
||||||
|
(gauss) phi1 0.0 phi 0.0 phi2 0.0 scatter 0.0 fraction 1.0
|
|
@ -0,0 +1,702 @@
|
||||||
|
|
||||||
|
!##############################################################
|
||||||
|
MODULE mesh
|
||||||
|
!##############################################################
|
||||||
|
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
! ---------------------------
|
||||||
|
! _Nelems : total number of elements in mesh
|
||||||
|
! _NcpElems : total number of CP elements in mesh
|
||||||
|
! _Nnodes : total number of nodes in mesh
|
||||||
|
! _maxNnodes : max number of nodes in any CP element
|
||||||
|
! _maxNips : max number of IPs in any CP element
|
||||||
|
! _maxNipNeighbors : max number of IP neighbors in any CP element
|
||||||
|
! _maxNsharedElems : max number of CP elements sharing a node
|
||||||
|
!
|
||||||
|
! _element : FEid, type, material, texture, node indices
|
||||||
|
! _node : x,y,z coordinates (initially!)
|
||||||
|
! _sharedElem : entryCount and list of elements containing node
|
||||||
|
!
|
||||||
|
! _mapFEtoCPelem : [sorted FEid, corresponding CPid]
|
||||||
|
! _mapFEtoCPnode : [sorted FEid, corresponding CPid]
|
||||||
|
!
|
||||||
|
! MISSING: these definitions should actually reside in the
|
||||||
|
! FE-solver specific part (different for MARC/ABAQUS)..!
|
||||||
|
! Hence, I suggest to prefix with "FE_"
|
||||||
|
!
|
||||||
|
! _mapElementtype : map MARC/ABAQUS elemtype to 1-maxN
|
||||||
|
!
|
||||||
|
! _Nnodes : # nodes in a specific type of element
|
||||||
|
! _Nips : # IPs in a specific type of element
|
||||||
|
! _NipNeighbors : # IP neighbors in a specific type of element
|
||||||
|
! _ipNeighbor : +x,-x,+y,-y,+z,-z list of intra-element IPs and
|
||||||
|
! (negative) neighbor faces per own IP in a specific type of element
|
||||||
|
! _NfaceNodes : # nodes per face in a specific type of element
|
||||||
|
! _nodeOnFace : list of node indices on each face of a specific type of element
|
||||||
|
! _ipAtNode : map node index to IP index in a specific type of element
|
||||||
|
! _nodeAtIP : map IP index to node index in a specific type of element
|
||||||
|
! _ipNeighborhood : 6 or less neighboring IPs as [element_num, IP_index]
|
||||||
|
! order is +x,-x,+y,-y,+z,-z but meaning strongly depends on Elemtype
|
||||||
|
! ---------------------------
|
||||||
|
integer(pInt) mesh_Nelems,mesh_NcpElems
|
||||||
|
integer(pInt) mesh_Nnodes,mesh_maxNnodes,mesh_maxNips,mesh_maxNipNeighbors,mesh_maxNsharedElems
|
||||||
|
integer(pInt), dimension(:,:), allocatable, target :: mesh_mapFEtoCPelem,mesh_mapFEtoCPnode
|
||||||
|
integer(pInt), dimension(:,:), allocatable :: mesh_element, mesh_sharedElem
|
||||||
|
integer(pInt), dimension(:,:,:,:), allocatable :: mesh_ipNeighborhood
|
||||||
|
real(pReal), allocatable :: mesh_node (:,:)
|
||||||
|
|
||||||
|
integer(pInt) :: hypoelasticTableStyle = 0
|
||||||
|
integer(pInt), parameter :: FE_Nelemtypes = 2
|
||||||
|
integer(pInt), parameter :: FE_maxNnodes = 8
|
||||||
|
integer(pInt), parameter :: FE_maxNips = 8
|
||||||
|
integer(pInt), parameter :: FE_maxNneighbors = 6
|
||||||
|
integer(pInt), parameter :: FE_maxNfaceNodes = 4
|
||||||
|
integer(pInt), parameter :: FE_maxNfaces = 6
|
||||||
|
integer(pInt), dimension(200):: FE_mapElemtype
|
||||||
|
integer(pInt), dimension(FE_Nelemtypes), parameter :: FE_Nnodes = &
|
||||||
|
(/8, & ! element 7
|
||||||
|
4 & ! element 134
|
||||||
|
/)
|
||||||
|
integer(pInt), dimension(FE_Nelemtypes), parameter :: FE_Nips = &
|
||||||
|
(/8, & ! element 7
|
||||||
|
1 & ! element 134
|
||||||
|
/)
|
||||||
|
integer(pInt), dimension(FE_Nelemtypes), parameter :: FE_NipNeighbors = &
|
||||||
|
(/6, & ! element 7
|
||||||
|
4 & ! element 134
|
||||||
|
/)
|
||||||
|
integer(pInt), dimension(FE_maxNfaces,FE_Nelemtypes), parameter :: FE_NfaceNodes = &
|
||||||
|
reshape((/&
|
||||||
|
4,4,4,4,4,4, & ! element 7
|
||||||
|
3,3,3,3,0,0 & ! element 134
|
||||||
|
/),(/FE_maxNfaces,FE_Nelemtypes/))
|
||||||
|
integer(pInt), dimension(FE_maxNips,FE_Nelemtypes), parameter :: FE_nodeAtIP = &
|
||||||
|
reshape((/&
|
||||||
|
1,2,4,3,5,6,8,7, & ! element 7
|
||||||
|
1,0,0,0,0,0,0,0 & ! element 134
|
||||||
|
/),(/FE_maxNips,FE_Nelemtypes/))
|
||||||
|
integer(pInt), dimension(FE_maxNnodes,FE_Nelemtypes), parameter :: FE_ipAtNode = &
|
||||||
|
reshape((/&
|
||||||
|
1,2,4,3,5,6,8,7, & ! element 7
|
||||||
|
1,1,1,1,0,0,0,0 & ! element 134
|
||||||
|
/),(/FE_maxNnodes,FE_Nelemtypes/))
|
||||||
|
integer(pInt), dimension(FE_maxNfaceNodes,FE_maxNfaces,FE_Nelemtypes), parameter :: FE_nodeOnFace = &
|
||||||
|
reshape((/&
|
||||||
|
1,2,3,4 , & ! element 7
|
||||||
|
2,1,5,6 , &
|
||||||
|
3,2,6,7 , &
|
||||||
|
3,4,8,7 , &
|
||||||
|
4,1,5,8 , &
|
||||||
|
8,7,6,5 , &
|
||||||
|
1,2,3,0 , & ! element 134
|
||||||
|
1,4,2,0 , &
|
||||||
|
2,3,4,0 , &
|
||||||
|
1,3,4,0 , &
|
||||||
|
0,0,0,0 , &
|
||||||
|
0,0,0,0 &
|
||||||
|
/),(/FE_maxNfaceNodes,FE_maxNfaces,FE_Nelemtypes/))
|
||||||
|
integer(pInt), dimension(FE_maxNneighbors,FE_maxNips,FE_Nelemtypes), parameter :: FE_ipNeighbor = &
|
||||||
|
reshape((/&
|
||||||
|
2,-5, 3,-2, 5,-1 , & ! element 7
|
||||||
|
-3, 1, 4,-2, 6,-1 , &
|
||||||
|
4,-5,-4, 1, 7,-1 , &
|
||||||
|
-3, 3,-4, 2, 8,-1 , &
|
||||||
|
6,-5, 7,-2,-6, 1 , &
|
||||||
|
-3, 5, 8,-2,-6, 2 , &
|
||||||
|
8,-5,-4, 5,-6, 3 , &
|
||||||
|
-3, 7,-4, 6,-6, 4 , &
|
||||||
|
-1,-2,-3,-4, 0, 0 , & ! element 134
|
||||||
|
0, 0, 0, 0, 0, 0 , &
|
||||||
|
0, 0, 0, 0, 0, 0 , &
|
||||||
|
0, 0, 0, 0, 0, 0 , &
|
||||||
|
0, 0, 0, 0, 0, 0 , &
|
||||||
|
0, 0, 0, 0, 0, 0 , &
|
||||||
|
0, 0, 0, 0, 0, 0 , &
|
||||||
|
0, 0, 0, 0, 0, 0 &
|
||||||
|
/),(/FE_maxNneighbors,FE_maxNips,FE_Nelemtypes/))
|
||||||
|
|
||||||
|
CONTAINS
|
||||||
|
! ---------------------------
|
||||||
|
! subroutine mesh_init()
|
||||||
|
! function mesh_FEtoCPelement(FEid)
|
||||||
|
! function mesh_build_ipNeighorhood()
|
||||||
|
! subroutine mesh_parse_inputFile()
|
||||||
|
! ---------------------------
|
||||||
|
|
||||||
|
|
||||||
|
!***********************************************************
|
||||||
|
! initialization
|
||||||
|
!***********************************************************
|
||||||
|
SUBROUTINE mesh_init ()
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO, only: IO_error,IO_open_InputFile
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt), parameter :: fileUnit = 222
|
||||||
|
|
||||||
|
mesh_Nelems = 0_pInt
|
||||||
|
mesh_NcpElems = 0_pInt
|
||||||
|
mesh_Nnodes = 0_pInt
|
||||||
|
mesh_maxNips = 0_pInt
|
||||||
|
mesh_maxNnodes = 0_pInt
|
||||||
|
mesh_maxNsharedElems = 0_pInt
|
||||||
|
|
||||||
|
FE_mapElemtype = 1 ! MISSING this should be zero...
|
||||||
|
FE_mapElemtype( 7) = 1
|
||||||
|
FE_mapElemtype(134) = 2
|
||||||
|
|
||||||
|
! call to various subrountes to parse the stuff from the input file...
|
||||||
|
if (IO_open_inputFile(fileUnit)) then
|
||||||
|
call mesh_get_meshDimensions(fileUnit)
|
||||||
|
call mesh_build_nodeMapping(fileUnit)
|
||||||
|
call mesh_build_elemMapping(fileUnit)
|
||||||
|
call mesh_get_nodeElemDimensions(fileUnit)
|
||||||
|
call mesh_build_nodes(fileUnit)
|
||||||
|
call mesh_build_elements(fileUnit)
|
||||||
|
call mesh_build_sharedElems(fileUnit)
|
||||||
|
call mesh_build_ipNeighborhood()
|
||||||
|
close (fileUnit)
|
||||||
|
else
|
||||||
|
call IO_error(100)
|
||||||
|
endif
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!***********************************************************
|
||||||
|
! FE to CP id mapping by binary search thru lookup array
|
||||||
|
!
|
||||||
|
! valid questions are 'elem', 'node'
|
||||||
|
!***********************************************************
|
||||||
|
FUNCTION mesh_FEasCP(what,id)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO, only: IO_lc
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character(len=*), intent(in) :: what
|
||||||
|
integer(pInt), intent(in) :: id
|
||||||
|
integer(pInt), dimension(:,:), pointer :: lookupMap
|
||||||
|
integer(pInt) mesh_FEasCP, lower,upper,center
|
||||||
|
|
||||||
|
mesh_FEasCP = 0_pInt
|
||||||
|
select case(IO_lc(what(1:4)))
|
||||||
|
case('elem')
|
||||||
|
lookupMap => mesh_mapFEtoCPelem
|
||||||
|
case('node')
|
||||||
|
lookupMap => mesh_mapFEtoCPnode
|
||||||
|
case default
|
||||||
|
return
|
||||||
|
end select
|
||||||
|
|
||||||
|
lower = 1_pInt
|
||||||
|
upper = size(lookupMap,2)
|
||||||
|
|
||||||
|
! check at bounds QUESTION is it valid to extend bounds by 1 and just do binary search w/o init check at bounds?
|
||||||
|
if (lookupMap(1,lower) == id) then
|
||||||
|
mesh_FEasCP = lookupMap(2,lower)
|
||||||
|
return
|
||||||
|
elseif (lookupMap(1,upper) == id) then
|
||||||
|
mesh_FEasCP = lookupMap(2,upper)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
! binary search in between bounds
|
||||||
|
do while (upper-lower > 1)
|
||||||
|
center = (lower+upper)/2
|
||||||
|
if (lookupMap(1,center) < id) then
|
||||||
|
lower = center
|
||||||
|
elseif (lookupMap(1,center) > id) then
|
||||||
|
upper = center
|
||||||
|
else
|
||||||
|
mesh_FEasCP = lookupMap(2,center)
|
||||||
|
exit
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!***********************************************************
|
||||||
|
! find face-matching element of same type
|
||||||
|
!!***********************************************************
|
||||||
|
FUNCTION mesh_faceMatch(face,elem)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt) face,elem
|
||||||
|
integer(pInt) mesh_faceMatch
|
||||||
|
integer(pInt), dimension(FE_NfaceNodes(face,FE_mapElemtype(mesh_element(2,elem)))) :: nodeMap
|
||||||
|
integer(pInt) minN,NsharedElems,lonelyNode,faceNode,i,n,t
|
||||||
|
|
||||||
|
minN = mesh_maxNsharedElems+1 ! init to worst case
|
||||||
|
mesh_faceMatch = 0_pInt ! intialize to "no match found"
|
||||||
|
t = FE_mapElemtype(mesh_element(2,elem)) ! figure elemType
|
||||||
|
|
||||||
|
do faceNode=1,FE_NfaceNodes(face,t) ! loop over nodes on face
|
||||||
|
nodeMap(faceNode) = mesh_FEasCP('node',mesh_element(4+FE_nodeOnFace(faceNode,face,t),elem)) ! CP id of face node
|
||||||
|
NsharedElems = mesh_sharedElem(1,nodeMap(faceNode)) ! figure # shared elements for this node
|
||||||
|
if (NsharedElems < minN) then
|
||||||
|
minN = NsharedElems ! remember min # shared elems
|
||||||
|
lonelyNode = faceNode ! remember most lonely node
|
||||||
|
endif
|
||||||
|
end do
|
||||||
|
candidate: do i=1,minN ! iterate over lonelyNode's shared elements
|
||||||
|
mesh_faceMatch = mesh_sharedElem(1+i,nodeMap(lonelyNode)) ! present candidate elem
|
||||||
|
if (mesh_faceMatch == elem) then ! my own element ?
|
||||||
|
mesh_faceMatch = 0_pInt ! disregard
|
||||||
|
cycle candidate
|
||||||
|
endif
|
||||||
|
do faceNode=1,FE_NfaceNodes(face,t) ! check remaining face nodes to match
|
||||||
|
if (faceNode == lonelyNode) cycle ! disregard lonely node (matches anyway)
|
||||||
|
n = nodeMap(faceNode)
|
||||||
|
if (all(mesh_sharedElem(2:1+mesh_sharedElem(1,n),n) /= mesh_faceMatch)) then ! no ref to candidate elem?
|
||||||
|
mesh_faceMatch = 0_pInt ! set to "no match" (so far)
|
||||||
|
cycle candidate ! next candidate elem
|
||||||
|
endif
|
||||||
|
end do
|
||||||
|
exit ! surviving candidate
|
||||||
|
end do candidate
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
END FUNCTION
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! get count of elements, nodes, and cp elements in mesh
|
||||||
|
! for subsequent array allocations
|
||||||
|
!
|
||||||
|
! assign globals:
|
||||||
|
! _Nelems, _Nnodes, _NcpElems
|
||||||
|
!********************************************************************
|
||||||
|
SUBROUTINE mesh_get_meshDimensions (unit)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt) unit,i,pos(41)
|
||||||
|
character*300 line
|
||||||
|
|
||||||
|
610 FORMAT(A300)
|
||||||
|
|
||||||
|
rewind(unit)
|
||||||
|
do
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,20)
|
||||||
|
|
||||||
|
select case ( IO_lc(IO_Stringvalue(line,pos,1)))
|
||||||
|
case('table')
|
||||||
|
if (pos(1) == 6) hypoelasticTableStyle = IO_IntValue (line,pos,5) ! only recognize header entry for "table"
|
||||||
|
case('sizing')
|
||||||
|
mesh_Nelems = IO_IntValue (line,pos,3)
|
||||||
|
mesh_Nnodes = IO_IntValue (line,pos,4)
|
||||||
|
case('hypoelastic')
|
||||||
|
do i=1,4+hypoelasticTableStyle
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
end do
|
||||||
|
pos = IO_stringPos(line,20)
|
||||||
|
if( IO_lc(IO_Stringvalue(line,pos,2)).eq.'to' )then
|
||||||
|
mesh_NcpElems = IO_IntValue(line,pos,3)-IO_IntValue(line,pos,1)+1
|
||||||
|
else
|
||||||
|
mesh_NcpElems = mesh_NcpElems + pos(1)
|
||||||
|
do while( IO_lc(IO_Stringvalue(line,pos,pos(1))).eq.'c' )
|
||||||
|
mesh_NcpElems = mesh_NcpElems - 1 ! Counted the c character from the line
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,20)
|
||||||
|
mesh_NcpElems = mesh_NcpElems + pos(1)
|
||||||
|
end do
|
||||||
|
end if
|
||||||
|
|
||||||
|
end select
|
||||||
|
|
||||||
|
end do
|
||||||
|
|
||||||
|
620 return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! get maximum count of nodes, IPs, IP neighbors, and shared elements
|
||||||
|
! for subsequent array allocations
|
||||||
|
!
|
||||||
|
! assign globals:
|
||||||
|
! _maxNnodes, _maxNips, _maxNipNeighbors, _maxNsharedElems
|
||||||
|
!********************************************************************
|
||||||
|
SUBROUTINE mesh_get_nodeElemDimensions (unit)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt), dimension (mesh_Nnodes) :: node_count
|
||||||
|
integer(pInt) unit,i,j,n,t,e
|
||||||
|
integer(pInt), dimension (133) :: pos
|
||||||
|
character*300 line
|
||||||
|
|
||||||
|
610 FORMAT(A300)
|
||||||
|
|
||||||
|
node_count = 0_pInt
|
||||||
|
|
||||||
|
rewind(unit)
|
||||||
|
do
|
||||||
|
read (unit,610,END=630) line
|
||||||
|
pos = IO_stringPos(line,1)
|
||||||
|
if( IO_lc(IO_stringValue(line,pos,1)) == 'connectivity' ) then
|
||||||
|
read (unit,610,END=630) line ! Garbage line
|
||||||
|
do i=1,mesh_Nelems ! read all elements
|
||||||
|
read (unit,610,END=630) line
|
||||||
|
pos = IO_stringPos(line,66) ! limit to 64 nodes max (plus ID, type)
|
||||||
|
e = mesh_FEasCP('elem',IO_intValue(line,pos,1))
|
||||||
|
if (e /= 0) then
|
||||||
|
t = FE_mapElemtype(IO_intValue(line,pos,2))
|
||||||
|
mesh_maxNnodes = max(mesh_maxNnodes,FE_Nnodes(t))
|
||||||
|
mesh_maxNips = max(mesh_maxNips,FE_Nips(t))
|
||||||
|
mesh_maxNipNeighbors = max(mesh_maxNipNeighbors,FE_NipNeighbors(t))
|
||||||
|
do j=1,FE_Nnodes(t)
|
||||||
|
n = mesh_FEasCP('node',IO_IntValue (line,pos,j+2))
|
||||||
|
node_count(n) = node_count(n)+1
|
||||||
|
end do
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
exit
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
|
||||||
|
630 mesh_maxNsharedElems = maxval(node_count)
|
||||||
|
|
||||||
|
return
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! Build node mapping from FEM to CP
|
||||||
|
!
|
||||||
|
! allocate globals:
|
||||||
|
! _mapFEtoCPnode
|
||||||
|
!********************************************************************
|
||||||
|
SUBROUTINE mesh_build_nodeMapping (unit)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
use math, only: qsort
|
||||||
|
use IO
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt), dimension (mesh_Nnodes) :: node_count
|
||||||
|
integer(pInt) unit,i
|
||||||
|
integer(pInt), dimension (133) :: pos
|
||||||
|
character*300 line
|
||||||
|
|
||||||
|
610 FORMAT(A300)
|
||||||
|
|
||||||
|
allocate (mesh_mapFEtoCPnode(2,mesh_Nnodes)) ; mesh_mapFEtoCPnode = 0_pInt
|
||||||
|
node_count(:) = 0_pInt
|
||||||
|
|
||||||
|
rewind(unit)
|
||||||
|
do
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,1)
|
||||||
|
if( IO_lc(IO_stringValue(line,pos,1)) == 'coordinates' ) then
|
||||||
|
read (unit,610,END=620) line ! skip crap line
|
||||||
|
do i=1,mesh_Nnodes
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
mesh_mapFEtoCPnode(1,i) = IO_fixedIntValue (line,(/0,10/),1)
|
||||||
|
mesh_mapFEtoCPnode(2,i) = i
|
||||||
|
end do
|
||||||
|
exit
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
|
||||||
|
620 call qsort(mesh_mapFEtoCPnode,1,size(mesh_mapFEtoCPnode,2))
|
||||||
|
|
||||||
|
return
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! Build element mapping from FEM to CP
|
||||||
|
!
|
||||||
|
! allocate globals:
|
||||||
|
! _mapFEtoCPelem
|
||||||
|
!********************************************************************
|
||||||
|
SUBROUTINE mesh_build_elemMapping (unit)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
use math, only: qsort
|
||||||
|
use IO
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer unit, i,CP_elem
|
||||||
|
character*300 line
|
||||||
|
integer(pInt), dimension (3) :: pos
|
||||||
|
integer(pInt), dimension (1+mesh_NcpElems) :: contInts
|
||||||
|
|
||||||
|
|
||||||
|
610 FORMAT(A300)
|
||||||
|
|
||||||
|
allocate (mesh_mapFEtoCPelem(2,mesh_NcpElems)) ; mesh_mapFEtoCPelem = 0_pInt
|
||||||
|
CP_elem = 0_pInt
|
||||||
|
|
||||||
|
rewind(unit)
|
||||||
|
do
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,1)
|
||||||
|
if( IO_lc(IO_stringValue(line,pos,1)) == 'hypoelastic' ) then
|
||||||
|
do i=1,3+hypoelasticTableStyle ! skip three (or four if new table style!) lines
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
end do
|
||||||
|
contInts = IO_continousIntValues(unit,mesh_NcpElems)
|
||||||
|
do i = 1,contInts(1)
|
||||||
|
CP_elem = CP_elem+1
|
||||||
|
mesh_mapFEtoCPelem(1,CP_elem) = contInts(1+i)
|
||||||
|
mesh_mapFEtoCPelem(2,CP_elem) = CP_elem
|
||||||
|
enddo
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
|
||||||
|
620 call qsort(mesh_mapFEtoCPelem,1,size(mesh_mapFEtoCPelem,2)) ! should be mesh_NcpElems
|
||||||
|
|
||||||
|
return
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! store x,y,z coordinates of all nodes in mesh
|
||||||
|
!
|
||||||
|
! allocate globals:
|
||||||
|
! _node
|
||||||
|
!********************************************************************
|
||||||
|
SUBROUTINE mesh_build_nodes (unit)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer unit,i,j,m
|
||||||
|
integer(pInt), dimension(3) :: pos
|
||||||
|
integer(pInt), dimension(5), parameter :: node_ends = (/0,10,30,50,70/)
|
||||||
|
character*300 line
|
||||||
|
|
||||||
|
allocate ( mesh_node (3,mesh_Nnodes) )
|
||||||
|
mesh_node(:,:) = 0_pInt
|
||||||
|
|
||||||
|
610 FORMAT(A300)
|
||||||
|
|
||||||
|
rewind(unit)
|
||||||
|
do
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,1)
|
||||||
|
if( IO_lc(IO_stringValue(line,pos,1)) == 'coordinates' ) then
|
||||||
|
read (unit,610,END=620) line ! skip crap line
|
||||||
|
do i=1,mesh_Nnodes
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
m = mesh_FEasCP('node',IO_fixedIntValue (line,node_ends,1))
|
||||||
|
do j=1,3
|
||||||
|
mesh_node(j,m) = IO_fixedNoEFloatValue (line,node_ends,j+1)
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
exit
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
|
||||||
|
620 return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! store FEid, type, mat, tex, and node list per element
|
||||||
|
!
|
||||||
|
! allocate globals:
|
||||||
|
! _element
|
||||||
|
!********************************************************************
|
||||||
|
SUBROUTINE mesh_build_elements (unit)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer unit,i,j,sv,val,CP_elem
|
||||||
|
integer(pInt), dimension(133) :: pos
|
||||||
|
integer(pInt), dimension(1+mesh_NcpElems) :: contInts
|
||||||
|
character*300 line
|
||||||
|
|
||||||
|
allocate (mesh_element (4+mesh_maxNnodes,mesh_NcpElems)) ; mesh_element = 0_pInt
|
||||||
|
|
||||||
|
610 FORMAT(A300)
|
||||||
|
|
||||||
|
|
||||||
|
rewind(unit)
|
||||||
|
do
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,2)
|
||||||
|
if( IO_lc(IO_stringValue(line,pos,1)) == 'connectivity' ) then
|
||||||
|
read (unit,610,END=620) line ! Garbage line
|
||||||
|
do i=1,mesh_Nelems
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,66) ! limit to 64 nodes max (plus ID, type)
|
||||||
|
CP_elem = mesh_FEasCP('elem',IO_intValue(line,pos,1))
|
||||||
|
if (CP_elem /= 0) then ! disregard non CP elems
|
||||||
|
mesh_element (1,CP_elem) = IO_IntValue (line,pos,1) ! FE id
|
||||||
|
mesh_element (2,CP_elem) = IO_IntValue (line,pos,2) ! elem type
|
||||||
|
do j=1,FE_Nnodes(FE_mapElemtype(mesh_element(2,CP_elem)))
|
||||||
|
mesh_element(j+4,CP_elem) = IO_IntValue (line,pos,j+2) ! copy FE ids of nodes
|
||||||
|
end do
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
exit
|
||||||
|
endif
|
||||||
|
enddo
|
||||||
|
|
||||||
|
rewind(unit) ! just in case "initial state" apears before "connectivity"
|
||||||
|
do ! fast forward to first "initial state" section
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,2)
|
||||||
|
if( (IO_lc(IO_stringValue(line,pos,1)) == 'initial').and. &
|
||||||
|
(IO_lc(IO_stringValue(line,pos,2)) == 'state') ) exit
|
||||||
|
enddo
|
||||||
|
|
||||||
|
do ! parse initial state section(s)
|
||||||
|
if( (IO_lc(IO_stringValue(line,pos,1)) == 'initial').and. &
|
||||||
|
(IO_lc(IO_stringValue(line,pos,2)) == 'state') ) then
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,1)
|
||||||
|
sv = IO_IntValue (line,pos,1) ! figure state variable index
|
||||||
|
if( (sv == 2).or.(sv == 3) ) then ! only state vars 2 and 3 of interest
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,1)
|
||||||
|
do while (scan(IO_stringValue(line,pos,1),'+-',back=.true.)>1)
|
||||||
|
val = NINT(IO_fixedNoEFloatValue (line,(/0,20/),1)) ! state var's value
|
||||||
|
contInts = IO_continousIntValues(unit,mesh_Nelems) ! get affected elements
|
||||||
|
do i = 1,contInts(1)
|
||||||
|
CP_elem = mesh_FEasCP('elem',contInts(1+i))
|
||||||
|
mesh_element(1+sv,CP_elem) = val
|
||||||
|
enddo
|
||||||
|
read (unit,610,END=620) line ! ignore IP range
|
||||||
|
pos = IO_stringPos(line,1)
|
||||||
|
enddo
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
read (unit,610,END=620) line ! read ahead (check in do loop)
|
||||||
|
pos = IO_stringPos(line,2)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
620 return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!********************************************************************
|
||||||
|
! build list of elements shared by each node in mesh
|
||||||
|
!
|
||||||
|
! allocate globals:
|
||||||
|
! _sharedElem
|
||||||
|
!********************************************************************
|
||||||
|
SUBROUTINE mesh_build_sharedElems (unit)
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
use IO
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer unit,i,j,CP_node,CP_elem
|
||||||
|
integer(pInt), dimension (133) :: pos
|
||||||
|
character*300 line
|
||||||
|
|
||||||
|
610 FORMAT(A300)
|
||||||
|
|
||||||
|
allocate ( mesh_sharedElem( 1+mesh_maxNsharedElems,mesh_Nnodes) )
|
||||||
|
mesh_sharedElem(:,:) = 0_pInt
|
||||||
|
|
||||||
|
rewind(unit)
|
||||||
|
do
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,1)
|
||||||
|
if( IO_lc(IO_stringValue(line,pos,1)) == 'connectivity' ) then
|
||||||
|
read (unit,610,END=620) line ! Garbage line
|
||||||
|
do i=1,mesh_Nelems
|
||||||
|
read (unit,610,END=620) line
|
||||||
|
pos = IO_stringPos(line,66) ! limit to 64 nodes max (plus ID, type)
|
||||||
|
CP_elem = mesh_FEasCP('elem',IO_IntValue(line,pos,1))
|
||||||
|
if (CP_elem /= 0) then ! disregard non CP elems
|
||||||
|
do j = 1,FE_Nnodes(FE_mapElemtype(IO_intValue(line,pos,2)))
|
||||||
|
CP_node = mesh_FEasCP('node',IO_IntValue (line,pos,j+2))
|
||||||
|
mesh_sharedElem(1,CP_node) = mesh_sharedElem(1,CP_node) + 1
|
||||||
|
mesh_sharedElem(1+mesh_sharedElem(1,CP_node),CP_node) = CP_elem
|
||||||
|
enddo
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
exit
|
||||||
|
end if
|
||||||
|
end do
|
||||||
|
|
||||||
|
620 return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
!***********************************************************
|
||||||
|
! build up of IP neighborhood
|
||||||
|
!
|
||||||
|
! allocate globals
|
||||||
|
! _ipNeighborhood
|
||||||
|
!***********************************************************
|
||||||
|
SUBROUTINE mesh_build_ipNeighborhood()
|
||||||
|
|
||||||
|
use prec, only: pInt
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer(pInt) e,t,i,j,k,n
|
||||||
|
integer(pInt) neighbor,neighboringElem,neighboringIP,matchingElem,faceNode,linkingNode
|
||||||
|
|
||||||
|
allocate(mesh_ipNeighborhood(2,mesh_maxNipNeighbors,mesh_maxNips,mesh_NcpElems)) ; mesh_ipNeighborhood = 0_pInt
|
||||||
|
|
||||||
|
do e = 1,mesh_NcpElems ! loop over cpElems
|
||||||
|
t = FE_mapElemtype(mesh_element(2,e)) ! get elemType
|
||||||
|
do i = 1,FE_Nips(t) ! loop over IPs of elem
|
||||||
|
do n = 1,FE_NipNeighbors(t) ! loop over neighbors of IP
|
||||||
|
neighbor = FE_ipNeighbor(n,i,t)
|
||||||
|
if (neighbor > 0) then ! intra-element IP
|
||||||
|
neighboringElem = e
|
||||||
|
neighboringIP = neighbor
|
||||||
|
else ! neighboring element's IP
|
||||||
|
neighboringElem = 0_pInt
|
||||||
|
neighboringIP = 0_pInt
|
||||||
|
matchingElem = mesh_faceMatch(-neighbor,e) ! get CP elem id of face match
|
||||||
|
if (matchingElem > 0 .and. &
|
||||||
|
FE_mapElemtype(mesh_element(2,matchingElem)) == t) then ! found match of same type?
|
||||||
|
matchFace: do j = 1,FE_NfaceNodes(-neighbor,t) ! count over nodes on matching face
|
||||||
|
faceNode = FE_nodeOnFace(j,-neighbor,t) ! get face node id
|
||||||
|
if (i == FE_ipAtNode(faceNode,t)) then ! ip linked to face node is me?
|
||||||
|
linkingNode = mesh_element(4+faceNode,e) ! FE id of this facial node
|
||||||
|
do k = 1,FE_Nnodes(t) ! loop over nodes in matching element
|
||||||
|
if (linkingNode == mesh_element(4+k,matchingElem)) then
|
||||||
|
neighboringElem = matchingElem
|
||||||
|
neighboringIP = FE_ipAtNode(k,t)
|
||||||
|
exit matchFace
|
||||||
|
endif
|
||||||
|
end do
|
||||||
|
endif
|
||||||
|
end do matchFace
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
mesh_ipNeighborhood(1,n,i,e) = neighboringElem
|
||||||
|
mesh_ipNeighborhood(2,n,i,e) = neighboringIP
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
end do
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
|
||||||
|
|
||||||
|
END MODULE mesh
|
||||||
|
|
|
@ -0,0 +1,275 @@
|
||||||
|
!********************************************************************
|
||||||
|
! Material subroutine for MSC.Marc Version 0.1
|
||||||
|
!
|
||||||
|
! written by F. Roters, P. Eisenlohr, L. Hantcherli, W.A. Counts
|
||||||
|
! MPI fuer Eisenforschung, Duesseldorf
|
||||||
|
!
|
||||||
|
! last modified: 28.03.2007
|
||||||
|
!********************************************************************
|
||||||
|
! Usage:
|
||||||
|
! - choose material as hypela2
|
||||||
|
! - set statevariable 2 to index of material
|
||||||
|
! - set statevariable 3 to index of texture
|
||||||
|
! - choose output of user variables if desired
|
||||||
|
! - make sure the file "mattex.mpie" exists in the working
|
||||||
|
! directory
|
||||||
|
! - use nonsymmetric option for solver (e.g. direct
|
||||||
|
! profile or multifrontal sparse, the latter seems
|
||||||
|
! to be faster!)
|
||||||
|
!********************************************************************
|
||||||
|
! Marc subroutines used:
|
||||||
|
! - hypela2
|
||||||
|
! - plotv
|
||||||
|
! - quit
|
||||||
|
!********************************************************************
|
||||||
|
! Marc common blocks included:
|
||||||
|
! - concom: lovl, ncycle, inc, incsub
|
||||||
|
! - creeps: timinc
|
||||||
|
!********************************************************************
|
||||||
|
!
|
||||||
|
include "prec.f90"
|
||||||
|
include "math.f90"
|
||||||
|
include "IO.f90"
|
||||||
|
include "mesh.f90"
|
||||||
|
include "crystal.f90"
|
||||||
|
include "constitutive.f90"
|
||||||
|
include "CPFEM.f90"
|
||||||
|
!
|
||||||
|
SUBROUTINE hypela2(d,g,e,de,s,t,dt,ngens,n,nn,kcus,matus,ndi,&
|
||||||
|
nshear,disp,dispt,coord,ffn,frotn,strechn,eigvn,ffn1,&
|
||||||
|
frotn1,strechn1,eigvn1,ncrd,itel,ndeg,ndm,&
|
||||||
|
nnode,jtype,lclass,ifr,ifu)
|
||||||
|
!********************************************************************
|
||||||
|
! This is the Marc material routine
|
||||||
|
!********************************************************************
|
||||||
|
!
|
||||||
|
! ************* user subroutine for defining material behavior **************
|
||||||
|
!
|
||||||
|
!
|
||||||
|
! CAUTION : Due to calculation of the Deformation gradients, Stretch Tensors and
|
||||||
|
! Rotation tensors at previous and current states, the analysis can be
|
||||||
|
! computationally expensive. Please use the user subroutine -> hypela
|
||||||
|
! if these kinematic quantities are not needed in the constitutive model
|
||||||
|
!
|
||||||
|
!
|
||||||
|
! IMPORTANT NOTES :
|
||||||
|
!
|
||||||
|
! (1) F,R,U are only available for continuum and membrane elements (not for
|
||||||
|
! shells and beams).
|
||||||
|
!
|
||||||
|
! (2) For total Lagrangian formulation use the -> 'Elasticity,1' card(=
|
||||||
|
! total Lagrange with large disp) in the parameter section of input deck.
|
||||||
|
! For updated Lagrangian formulation use the -> 'Plasticity,3' card(=
|
||||||
|
! update+finite+large disp+constant d) in the parameter section of
|
||||||
|
! input deck.
|
||||||
|
!
|
||||||
|
!
|
||||||
|
! d stress strain law to be formed
|
||||||
|
! g change in stress due to temperature effects
|
||||||
|
! e total elastic strain
|
||||||
|
! de increment of strain
|
||||||
|
! s stress - should be updated by user
|
||||||
|
! t state variables (comes in at t=n, must be updated
|
||||||
|
! to have state variables at t=n+1)
|
||||||
|
! dt increment of state variables
|
||||||
|
! ngens size of stress - strain law
|
||||||
|
! n element number
|
||||||
|
! nn integration point number
|
||||||
|
! kcus(1) layer number
|
||||||
|
! kcus(2) internal layer number
|
||||||
|
! matus(1) user material identification number
|
||||||
|
! matus(2) internal material identification number
|
||||||
|
! ndi number of direct components
|
||||||
|
! nshear number of shear components
|
||||||
|
! disp incremental displacements
|
||||||
|
! dispt displacements at t=n (at assembly, lovl=4) and
|
||||||
|
! displacements at t=n+1 (at stress recovery, lovl=6)
|
||||||
|
! coord coordinates
|
||||||
|
! ncrd number of coordinates
|
||||||
|
! ndeg number of degrees of freedom
|
||||||
|
! itel dimension of F and R, either 2 or 3
|
||||||
|
! nnode number of nodes per element
|
||||||
|
! jtype element type
|
||||||
|
! lclass element class
|
||||||
|
! ifr set to 1 if R has been calculated
|
||||||
|
! ifu set to 1 if strech has been calculated
|
||||||
|
!
|
||||||
|
! at t=n :
|
||||||
|
!
|
||||||
|
! ffn deformation gradient
|
||||||
|
! frotn rotation tensor
|
||||||
|
! strechn square of principal stretch ratios, lambda(i)
|
||||||
|
! eigvn(i,j) i principal direction components for j eigenvalues
|
||||||
|
!
|
||||||
|
! at t=n+1 :
|
||||||
|
!
|
||||||
|
! ffn1 deformation gradient
|
||||||
|
! frotn1 rotation tensor
|
||||||
|
! strechn1 square of principal stretch ratios, lambda(i)
|
||||||
|
! eigvn1(i,j) i principal direction components for j eigenvalues
|
||||||
|
!
|
||||||
|
! The following operation obtains U (stretch tensor) at t=n+1 :
|
||||||
|
!
|
||||||
|
! call scla(un1,0.d0,itel,itel,1)
|
||||||
|
! do 3 k=1,3
|
||||||
|
! do 2 i=1,3
|
||||||
|
! do 1 j=1,3
|
||||||
|
! un1(i,j)=un1(i,j)+dsqrt(strechn1(k))*eigvn1(i,k)*eigvn1(j,k)
|
||||||
|
!1 continue
|
||||||
|
!2 continue
|
||||||
|
!3 continue
|
||||||
|
!
|
||||||
|
!
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
use math, only: invnrmMandel, nrmMandel
|
||||||
|
use mesh, only: mesh_FEasCP
|
||||||
|
use CPFEM, only: CPFEM_general,CPFEM_stress_all, CPFEM_jaco_old
|
||||||
|
implicit real(pReal) (a-h,o-z)
|
||||||
|
!
|
||||||
|
! Marc common blocks are in fixed format so they have to be pasted in here
|
||||||
|
! Beware of changes in newer Marc versions -- these are from 2005r3
|
||||||
|
! concom is needed for inc, subinc, ncycle, lovl
|
||||||
|
! include 'concom'
|
||||||
|
common/concom/ &
|
||||||
|
iacous, iasmbl, iautth, ibear, icompl, iconj, icreep, ideva(50), idyn, idynt,&
|
||||||
|
ielas, ielcma, ielect, iform, ifour, iharm, ihcps, iheat, iheatt, ihresp,&
|
||||||
|
ijoule, ilem, ilnmom, iloren, inc, incext, incsub, ipass, iplres, ipois,&
|
||||||
|
ipoist, irpflo, ismall, ismalt, isoil, ispect, ispnow, istore, iswep, ithcrp,&
|
||||||
|
itherm, iupblg, iupdat, jacflg, jel, jparks, largst, lfond, loadup, loaduq,&
|
||||||
|
lodcor, lovl, lsub, magnet, ncycle, newtnt, newton, noshr, linear, ivscpl,&
|
||||||
|
icrpim, iradrt, ipshft, itshr, iangin, iupmdr, iconjf, jincfl, jpermg, jhour,&
|
||||||
|
isolvr, jritz, jtable, jshell, jdoubl, jform, jcentr, imini, kautth, iautof,&
|
||||||
|
ibukty, iassum, icnstd, icnstt, kmakmas, imethvp,iradrte,iradrtp, iupdate,iupdatp,&
|
||||||
|
ncycnt, marmen ,idynme, ihavca, ispf, kmini, imixed, largtt, kdoela, iautofg,&
|
||||||
|
ipshftp,idntrc, ipore, jtablm, jtablc, isnecma,itrnspo,imsdif, jtrnspo,mcnear,&
|
||||||
|
imech, imecht, ielcmat, ielectt,magnett, imsdift,noplas, jtabls, jactch, jtablth,&
|
||||||
|
kgmsto ,jpzo, ifricsh, iremkin,iremfor, ishearp,jspf, machining, jlshell,icompsol,&
|
||||||
|
iupblgfo,jcondir,nstcrp, nactive,ipassref, nstspnt,ibeart,icheckmpc, noline, icuring,&
|
||||||
|
ishrink,ioffsflg,isetoff, iharmt, inc_incdat, iautspc,ibrake
|
||||||
|
! creeps is needed for timinc (time increment)
|
||||||
|
! include 'creeps'
|
||||||
|
common/creeps/ &
|
||||||
|
cptim,timinc,timinc_p,timinc_s,timincm,timinc_a,timinc_b,creept(33),icptim,icfte,icfst,&
|
||||||
|
icfeq,icftm,icetem,mcreep,jcreep,icpa,icftmp,icfstr,icfqcp,icfcpm,icrppr,icrcha,icpb,iicpmt,iicpa
|
||||||
|
!
|
||||||
|
integer(pInt) cp_en, i
|
||||||
|
!
|
||||||
|
dimension e(*),de(*),t(*),dt(*),g(*),d(ngens,*),s(*), n(2),coord(ncrd,*),disp(ndeg,*),matus(2),dispt(ndeg,*),ffn(itel,*),&
|
||||||
|
frotn(itel,*),strechn(itel),eigvn(itel,*),ffn1(itel,*),frotn1(itel,*),strechn1(itel),eigvn1(itel,*),kcus(2)
|
||||||
|
!
|
||||||
|
! call general material routine only in cycle 0 and for lovl==6 (stress recovery)
|
||||||
|
|
||||||
|
! subroutine cpfem_general(mpie_ffn, mpie_ffn1, mpie_cn, mpie_tinc, mpie_enp, mpie_in)
|
||||||
|
!********************************************************************
|
||||||
|
! This routine calculates the material behaviour
|
||||||
|
!********************************************************************
|
||||||
|
! mpie_ffn deformation gradient for t=t0
|
||||||
|
! mpie_ffn1 deformation gradient for t=t1
|
||||||
|
! mpie_cn number of cycle
|
||||||
|
! mpie_tinc time increment
|
||||||
|
! mpie_en element number
|
||||||
|
! mpie_in intergration point number
|
||||||
|
!********************************************************************
|
||||||
|
if ((lovl==6).or.(ncycle==0)) then
|
||||||
|
call CPFEM_general(ffn, ffn1, t(1), inc, incsub, ncycle, timinc, n(1), nn)
|
||||||
|
endif
|
||||||
|
! return stress and jacobi
|
||||||
|
! Mandel: 11, 22, 33, 12, 23, 13
|
||||||
|
! Marc: 11, 22, 33, 12, 23, 13
|
||||||
|
cp_en = mesh_FEasCP('elem', n(1))
|
||||||
|
s(1:ngens)=invnrmMandel(1:ngens)*CPFEM_stress_all(1:ngens, nn, cp_en)
|
||||||
|
d(1:ngens,1:ngens)=CPFEM_jaco_old(1:ngens,1:ngens, nn, cp_en)
|
||||||
|
forall(i=1:ngens) d(1:ngens,i)=d(1:ngens,i)*invnrmMandel(1:ngens)
|
||||||
|
return
|
||||||
|
|
||||||
|
END SUBROUTINE
|
||||||
|
!
|
||||||
|
!
|
||||||
|
SUBROUTINE plotv(v,s,sp,etot,eplas,ecreep,t,m,nn,layer,ndi,nshear,jpltcd)
|
||||||
|
!********************************************************************
|
||||||
|
! This routine sets user defined output variables for Marc
|
||||||
|
!********************************************************************
|
||||||
|
!
|
||||||
|
! select a variable contour plotting (user subroutine).
|
||||||
|
!
|
||||||
|
! v variable
|
||||||
|
! s (idss) stress array
|
||||||
|
! sp stresses in preferred direction
|
||||||
|
! etot total strain (generalized)
|
||||||
|
! eplas total plastic strain
|
||||||
|
! ecreep total creep strain
|
||||||
|
! t current temperature
|
||||||
|
! m element number
|
||||||
|
! nn integration point number
|
||||||
|
! layer layer number
|
||||||
|
! ndi (3) number of direct stress components
|
||||||
|
! nshear (3) number of shear stress components
|
||||||
|
!
|
||||||
|
!********************************************************************
|
||||||
|
use prec, only: pReal,pInt
|
||||||
|
use CPFEM, only: CPFEM_results, CPFEM_Nresults
|
||||||
|
use constitutive, only: constitutive_maxNresults
|
||||||
|
use mesh, only: mesh_FEasCP
|
||||||
|
implicit none
|
||||||
|
!
|
||||||
|
real(pReal) s(*),etot(*),eplas(*),ecreep(*),sp(*)
|
||||||
|
real(pReal) v, t(*)
|
||||||
|
integer(pInt) m, nn, layer, ndi, nshear, jpltcd
|
||||||
|
!
|
||||||
|
! assign result variable
|
||||||
|
v=CPFEM_results(mod(jpltcd, CPFEM_Nresults+constitutive_maxNresults),&
|
||||||
|
int(jpltcd/(CPFEM_Nresults+constitutive_maxNresults)),&
|
||||||
|
nn, mesh_FEasCP('elem', m))
|
||||||
|
return
|
||||||
|
END SUBROUTINE
|
||||||
|
!
|
||||||
|
!
|
||||||
|
! subroutine utimestep(timestep,timestepold,icall,time,timeloadcase)
|
||||||
|
!********************************************************************
|
||||||
|
! This routine modifies the addaptive time step of Marc
|
||||||
|
!********************************************************************
|
||||||
|
! use prec, only: pReal,pInt
|
||||||
|
! use CPFEM, only : CPFEM_timefactor_max
|
||||||
|
! implicit none
|
||||||
|
!
|
||||||
|
! real(pReal) timestep, timestepold, time,timeloadcase
|
||||||
|
! integer(pInt) icall
|
||||||
|
!
|
||||||
|
! user subroutine for modifying the time step in auto step
|
||||||
|
!
|
||||||
|
! timestep : the current time step as suggested by marc
|
||||||
|
! to be modified in this routine
|
||||||
|
! timestepold : the current time step before it was modified by marc
|
||||||
|
! icall : =1 for setting the initial time step
|
||||||
|
! =2 if this routine is called during an increment
|
||||||
|
! =3 if this routine is called at the beginning
|
||||||
|
! of the increment
|
||||||
|
! time : time at the start of the current increment
|
||||||
|
! timeloadcase: time period of the current load case
|
||||||
|
!
|
||||||
|
! it is in general not recommended to increase the time step
|
||||||
|
! during the increment.
|
||||||
|
! this routine is called right after the time step has (possibly)
|
||||||
|
! been updated by marc.
|
||||||
|
!
|
||||||
|
! user coding
|
||||||
|
! reduce timestep during increment in case mpie_timefactor is too large
|
||||||
|
! if(icall==2_pInt) then
|
||||||
|
! if(mpie_timefactor_max>1.25_pReal) then
|
||||||
|
! timestep=min(timestep,timestepold*0.8_pReal)
|
||||||
|
! end if
|
||||||
|
! return
|
||||||
|
! modify timestep at beginning of new increment
|
||||||
|
! else if(icall==3_pInt) then
|
||||||
|
! if(mpie_timefactor_max<=0.8_pReal) then
|
||||||
|
! timestep=min(timestep,timestepold*1.25_pReal)
|
||||||
|
! else if (mpie_timefactor_max<=1.0_pReal) then
|
||||||
|
! timestep=min(timestep,timestepold/mpie_timefactor_max)
|
||||||
|
! else if (mpie_timefactor_max<=1.25_pReal) then
|
||||||
|
! timestep=min(timestep,timestepold*1.01_pReal)
|
||||||
|
! else
|
||||||
|
! timestep=min(timestep,timestepold*0.8_pReal)
|
||||||
|
! end if
|
||||||
|
! end if
|
||||||
|
! return
|
||||||
|
! end
|
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
!##############################################################
|
||||||
|
MODULE prec
|
||||||
|
!##############################################################
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
! *** Precision of real and integer variables ***
|
||||||
|
integer, parameter :: pReal = 8
|
||||||
|
integer, parameter :: pInt = 4
|
||||||
|
! *** Numerical parameters ***
|
||||||
|
! *** How frequently the jacobian is recalculated ***
|
||||||
|
integer (pInt), parameter :: ijaco = 5_pInt
|
||||||
|
! *** Maximum number of internal cutbacks in time step ***
|
||||||
|
integer(pInt), parameter :: nCutback = 7_pInt
|
||||||
|
! *** Maximum number of regularization attempts for Jacobi inversion ***
|
||||||
|
integer(pInt), parameter :: nReg = 1_pInt
|
||||||
|
! *** Perturbation of strain array for numerical calculation of FEM Jacobi matrix ***
|
||||||
|
real(pReal), parameter :: pert_e=1.0e-5_pReal
|
||||||
|
! *** Maximum number of iterations in outer (state variables) loop ***
|
||||||
|
integer(pInt), parameter :: nState = 50_pInt
|
||||||
|
! *** Convergence criteria for outer (state variables) loop ***
|
||||||
|
real(pReal), parameter :: tol_State = 1.0e-6_pReal
|
||||||
|
! *** Maximum number of iterations in inner (stress) loop ***
|
||||||
|
integer(pInt), parameter :: nStress = 500_pInt
|
||||||
|
! *** Convergence criteria for inner (stress) loop ***
|
||||||
|
real(pReal), parameter :: tol_Stress = 1.0e-6_pReal
|
||||||
|
! *** Factor for maximum stress correction in inner (stress) loop ***
|
||||||
|
! real(pReal), parameter :: crite = 0.1_pReal
|
||||||
|
|
||||||
|
|
||||||
|
END MODULE prec
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
!use prec
|
||||||
|
!use IO
|
||||||
|
!use constitutive
|
||||||
|
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
integer, dimension(4) :: array,m
|
||||||
|
|
||||||
|
real a,twopi
|
||||||
|
integer i
|
||||||
|
|
||||||
|
array = (/10,2,3,4/)
|
||||||
|
m = (/1,1,0,0/)
|
||||||
|
|
||||||
|
write(*,*) maxval(array,m /= 0)
|
||||||
|
|
||||||
|
twopi=2.0*3.1415926
|
||||||
|
a=1.234
|
||||||
|
|
||||||
|
do i=0,-3,-1
|
||||||
|
write(*,*) a+i*twopi,modulo(a+i*twopi,twopi)
|
||||||
|
enddo
|
||||||
|
|
||||||
|
|
||||||
|
!call constitutive_parse_MatTexDat('materials_textures.mpie')
|
||||||
|
|
||||||
|
!write(*,*) 'materials_maxN ', materials_maxN
|
||||||
|
!write(*,*) 'textures_maxN ', textures_maxN
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue