This commit is contained in:
Luc Hantcherli 2007-10-15 12:03:52 +00:00
parent 532d3c2a16
commit 73694790f8
10 changed files with 5083 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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