# new interface for Abaqus
# IO has some additional functionality for Abaqus parsing # ping pong scheme in FE interface now similar (and more human understandable) in both versions # mesh has better splitting of different tasks, plus operation on database whenever possible # FEsolver as new global var to indicate FEM solver type # computation mode reshuffling: 6 is now Marc special case of recycling...
This commit is contained in:
parent
02602144d2
commit
21cad32137
|
@ -79,8 +79,6 @@ subroutine CPFEM_general(mode, ffn, ffn1, Temperature, dt, element, IP, cauchySt
|
|||
terminallyIll, &
|
||||
cycleCounter, &
|
||||
theInc, &
|
||||
theCycle, &
|
||||
theLovl, &
|
||||
theTime, &
|
||||
FEsolving_execElem, &
|
||||
FEsolving_execIP
|
||||
|
@ -120,8 +118,8 @@ subroutine CPFEM_general(mode, ffn, ffn1, Temperature, dt, element, IP, cauchySt
|
|||
materialpoint_Temperature, &
|
||||
materialpoint_stressAndItsTangent, &
|
||||
materialpoint_postResults
|
||||
use IO, only: IO_init
|
||||
use cpfem_interface
|
||||
use IO, only: IO_init
|
||||
use cpfem_interface
|
||||
|
||||
implicit none
|
||||
|
||||
|
@ -133,12 +131,12 @@ subroutine CPFEM_general(mode, ffn, ffn1, Temperature, dt, element, IP, cauchySt
|
|||
real(pReal), intent(in) :: dt ! time increment
|
||||
real(pReal), dimension (3,3), intent(in) :: ffn, & ! deformation gradient for t=t0
|
||||
ffn1 ! deformation gradient for t=t1
|
||||
integer(pInt), intent(in) :: mode ! computation mode 1: regular computation with aged results
|
||||
integer(pInt), intent(in) :: mode ! computation mode 1: regular computation plus aging of results
|
||||
! 2: regular computation
|
||||
! 3: collection of FEM data
|
||||
! 4: recycling of former results (MARC speciality)
|
||||
! 5: record tangent from former converged inc
|
||||
! 6: restore tangent from former converged inc
|
||||
! 4: backup tangent from former converged inc
|
||||
! 5: restore tangent from former converged inc
|
||||
! 6: recycling of former results (MARC speciality)
|
||||
|
||||
!*** output variables ***!
|
||||
real(pReal), dimension(ngens), intent(out) :: cauchyStress ! stress vector in Mandel notation
|
||||
|
@ -176,7 +174,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, Temperature, dt, element, IP, cauchySt
|
|||
call debug_init()
|
||||
call math_init()
|
||||
call FE_init()
|
||||
call mesh_init()
|
||||
call mesh_init(IP, element) ! pass on coordinates to alter calcMode of first ip
|
||||
call lattice_init()
|
||||
call material_init()
|
||||
call constitutive_init()
|
||||
|
@ -190,12 +188,14 @@ subroutine CPFEM_general(mode, ffn, ffn1, Temperature, dt, element, IP, cauchySt
|
|||
cp_en = mesh_FEasCP('elem',element)
|
||||
|
||||
if (cp_en == 1 .and. IP == 1) then
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,*)
|
||||
write(6,*) '#####################################'
|
||||
write(6,'(a10,1x,f8.4,1x,a10,1x,i4,1x,a10,1x,i3,1x,a10,1x,i2,x,a10,1x,i2)') &
|
||||
'theTime',theTime,'theInc',theInc,'theCycle',theCycle,'theLovl',theLovl,&
|
||||
'mode',mode
|
||||
write(6,'(a10,x,f8.4,x,a10,x,i4,x,a10,x,i3,x,a16,x,i2,x,a16,x,i2)') &
|
||||
'theTime',theTime,'theInc',theInc,'cycleCounter',cycleCounter,'computationMode',mode
|
||||
write(6,*) '#####################################'
|
||||
call flush (6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
endif
|
||||
|
||||
! according to our "mode" we decide what to do
|
||||
|
@ -213,7 +213,9 @@ subroutine CPFEM_general(mode, ffn, ffn1, Temperature, dt, element, IP, cauchySt
|
|||
j = 1:mesh_maxNips, &
|
||||
k = 1:mesh_NcpElems ) &
|
||||
constitutive_state0(i,j,k)%p = constitutive_state(i,j,k)%p ! microstructure of crystallites
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,'(a10,/,4(3(e20.8,x),/))') 'aged state',constitutive_state(1,1,1)%p
|
||||
!$OMP END CRITICAL (write2out)
|
||||
do k = 1,mesh_NcpElems
|
||||
do j = 1,mesh_maxNips
|
||||
if (homogenization_sizeState(j,k) > 0_pInt) &
|
||||
|
@ -225,7 +227,9 @@ subroutine CPFEM_general(mode, ffn, ffn1, Temperature, dt, element, IP, cauchySt
|
|||
! deformation gradient outdated or any actual deformation gradient differs more than relevantStrain from the stored one
|
||||
if (terminallyIll .or. outdatedFFN1 .or. any(abs(ffn1 - materialpoint_F(:,:,IP,cp_en)) > relevantStrain)) then
|
||||
if (.not. terminallyIll .and. .not. outdatedFFN1) then
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,'(a11,x,i5,x,i2,x,a10,/,3(3(f10.6,x),/))') 'outdated at',cp_en,IP,'FFN1 now:',ffn1(:,1),ffn1(:,2),ffn1(:,3)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
outdatedFFN1 = .true.
|
||||
endif
|
||||
CPFEM_cs(1:ngens,IP,cp_en) = CPFEM_odd_stress
|
||||
|
@ -234,7 +238,7 @@ subroutine CPFEM_general(mode, ffn, ffn1, Temperature, dt, element, IP, cauchySt
|
|||
! deformation gradient is not outdated
|
||||
else
|
||||
! set flag for Jacobian update
|
||||
updateJaco = (mod(cycleCounter-4,4_pInt*iJacoStiffness)==0)
|
||||
updateJaco = mod(cycleCounter,iJacoStiffness) == 0
|
||||
|
||||
! no parallel computation
|
||||
if (.not. parallelExecution) then
|
||||
|
@ -278,8 +282,13 @@ subroutine CPFEM_general(mode, ffn, ffn1, Temperature, dt, element, IP, cauchySt
|
|||
endif
|
||||
endif
|
||||
|
||||
! --+>> COLLECTION OF FEM DATA AND RETURN OF ODD STRESS AND JACOBIAN <<+--
|
||||
case (3)
|
||||
! --+>> COLLECTION OF FEM INPUT WITH RETURNING OF ODD STRESS AND JACOBIAN <<+--
|
||||
case (3,4,5)
|
||||
if (mode == 4) then
|
||||
CPFEM_dcsde_knownGood = CPFEM_dcsde ! --+>> BACKUP JACOBIAN FROM FORMER CONVERGED INC
|
||||
else if (mode == 5) then
|
||||
CPFEM_dcsde = CPFEM_dcsde_knownGood ! --+>> RESTORE CONSISTENT JACOBIAN FROM FORMER CONVERGED INC
|
||||
end if
|
||||
materialpoint_Temperature(IP,cp_en) = Temperature
|
||||
materialpoint_F0(:,:,IP,cp_en) = ffn
|
||||
materialpoint_F(:,:,IP,cp_en) = ffn1
|
||||
|
@ -288,29 +297,26 @@ subroutine CPFEM_general(mode, ffn, ffn1, Temperature, dt, element, IP, cauchySt
|
|||
CPFEM_calc_done = .false.
|
||||
|
||||
! --+>> RECYCLING OF FORMER RESULTS (MARC SPECIALTY) <<+--
|
||||
case (4)
|
||||
case (6)
|
||||
! do nothing
|
||||
|
||||
! --+>> RECORD JACOBIAN FROM FORMER CONVERGED INC <<+--
|
||||
case (5)
|
||||
CPFEM_dcsde_knownGood = CPFEM_dcsde
|
||||
|
||||
! --+>> RESTORE CONSISTENT JACOBIAN FROM FORMER CONVERGED INC <<+--
|
||||
case (6)
|
||||
CPFEM_dcsde = CPFEM_dcsde_knownGood
|
||||
|
||||
end select
|
||||
|
||||
! return the local stress and the jacobian from storage
|
||||
cauchyStress(1:ngens) = CPFEM_cs(1:ngens,IP,cp_en)
|
||||
jacobian(1:ngens,1:ngens) = CPFEM_dcsdE(1:ngens,1:ngens,IP,cp_en)
|
||||
if (IP == 1 .and. cp_en == 1) write(6,'(a,/,6(6(f10.3,x)/))') 'jacobian/GPa at ip 1 el 1',jacobian/1e9
|
||||
if (IP == 1 .and. cp_en == 1) then
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,'(a,/,6(6(f10.3,x)/))') 'jacobian/GPa at ip 1 el 1',jacobian/1e9
|
||||
call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
endif
|
||||
|
||||
! return temperature
|
||||
if (theInc > 0_pInt) Temperature = materialpoint_Temperature(IP,cp_en) ! homogenized result except for potentially non-isothermal starting condition.
|
||||
return
|
||||
|
||||
end subroutine
|
||||
|
||||
|
||||
END MODULE CPFEM
|
||||
|
||||
END MODULE CPFEM
|
||||
|
||||
|
|
|
@ -6,12 +6,13 @@
|
|||
use prec, only: pInt,pReal
|
||||
implicit none
|
||||
|
||||
integer(pInt) cycleCounter
|
||||
integer(pInt) theInc,theCycle,theLovl
|
||||
real(pReal) theTime
|
||||
integer(pInt) cycleCounter, theInc
|
||||
real(pReal) theTime, theDelta
|
||||
logical :: lastIncConverged = .false.,outdatedByNewInc = .false.,outdatedFFN1 = .false.,terminallyIll = .false.
|
||||
logical :: symmetricSolver = .false.
|
||||
logical :: parallelExecution = .true.
|
||||
logical :: lastMode = .true., cutBack = .false.
|
||||
logical, dimension(:,:), allocatable :: calcMode
|
||||
integer(pInt), dimension(:,:), allocatable :: FEsolving_execIP
|
||||
integer(pInt), dimension(2) :: FEsolving_execElem
|
||||
|
||||
|
|
249
code/IO.f90
249
code/IO.f90
|
@ -27,11 +27,16 @@
|
|||
!********************************************************************
|
||||
! output version number
|
||||
!********************************************************************
|
||||
subroutine IO_init
|
||||
write(6,*)
|
||||
write(6,*) '<<<+- IO init -+>>>'
|
||||
write(6,*) '$Id$'
|
||||
write(6,*)
|
||||
subroutine IO_init ()
|
||||
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,*)
|
||||
write(6,*) '<<<+- IO init -+>>>'
|
||||
write(6,*) '$Id$'
|
||||
write(6,*)
|
||||
call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
|
||||
return
|
||||
endsubroutine
|
||||
|
||||
|
@ -64,6 +69,7 @@ endsubroutine
|
|||
!********************************************************************
|
||||
logical function IO_open_inputFile(unit)
|
||||
|
||||
use cpfem_interface
|
||||
use prec, only: pReal, pInt
|
||||
implicit none
|
||||
|
||||
|
@ -74,11 +80,18 @@ endsubroutine
|
|||
|
||||
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
|
||||
endif
|
||||
! if(outName(extPos:extPos+2)=='out') then
|
||||
! ext='dat' ! MARC
|
||||
! else
|
||||
! ext='inp' ! ABAQUS
|
||||
! endif
|
||||
select case (FEsolver)
|
||||
case ('Marc')
|
||||
ext='dat'
|
||||
case ('Abaqus')
|
||||
ext='inp'
|
||||
end select
|
||||
|
||||
open(unit,status='old',err=100,file=outName(1:extPos-1)//ext)
|
||||
IO_open_inputFile = .true.
|
||||
return
|
||||
|
@ -461,7 +474,7 @@ endfunction
|
|||
implicit none
|
||||
|
||||
character(len=*), intent(in) :: line
|
||||
character(len=*), parameter :: sep=achar(32)//achar(9)//achar(10)//achar(13) ! whitespaces
|
||||
character(len=*), parameter :: sep=achar(44)//achar(32)//achar(9)//achar(10)//achar(13) ! comma and whitespaces
|
||||
integer(pInt), intent(in) :: N
|
||||
integer(pInt) part
|
||||
integer(pInt) IO_stringPos(1+N*2)
|
||||
|
@ -703,91 +716,211 @@ endfunction
|
|||
|
||||
endsubroutine
|
||||
|
||||
|
||||
!********************************************************************
|
||||
! extract value from key=value pair and check whether key matches
|
||||
!********************************************************************
|
||||
pure function IO_extractValue (line,key)
|
||||
|
||||
use prec, only: pReal,pInt
|
||||
implicit none
|
||||
|
||||
character(len=*), intent(in) :: line,key
|
||||
character(len=*), parameter :: sep = achar(61) ! '='
|
||||
integer(pInt) pos
|
||||
character(len=300) IO_extractValue
|
||||
|
||||
IO_extractValue = ''
|
||||
|
||||
pos = scan(line,sep)
|
||||
if (pos > 0 .and. line(:pos-1) == key(:pos-1)) & ! key matches expected key
|
||||
IO_extractValue = line(pos+1:) ! extract value
|
||||
|
||||
return
|
||||
|
||||
endfunction
|
||||
|
||||
|
||||
!********************************************************************
|
||||
! count items in consecutive lines of ints concatenated by "c"
|
||||
! as last char or range of values a "to" b
|
||||
! count lines containig data up to next *keyword
|
||||
!********************************************************************
|
||||
function IO_countContinousIntValues (unit)
|
||||
function IO_countDataLines (unit)
|
||||
|
||||
use prec, only: pReal,pInt
|
||||
implicit none
|
||||
|
||||
integer(pInt) IO_countContinousIntValues,unit
|
||||
integer(pInt), dimension(67) :: pos ! allow for 32 values excl "c"
|
||||
character(len=300) line
|
||||
integer(pInt) IO_countDataLines,unit
|
||||
integer(pInt), parameter :: maxNchunks = 64
|
||||
integer(pInt), dimension(1+2*maxNchunks) :: pos
|
||||
character(len=300) line,tmp
|
||||
|
||||
IO_countContinousIntValues = 0
|
||||
IO_countDataLines = 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
|
||||
IO_countContinousIntValues = IO_countContinousIntValues+1+IO_intValue(line,pos,3)-IO_intValue(line,pos,1)
|
||||
exit
|
||||
pos = IO_stringPos(line,maxNchunks)
|
||||
tmp = IO_lc(IO_stringValue(line,pos,1))
|
||||
if (tmp(1:1) == '*' ) then ! found keyword
|
||||
exit
|
||||
else
|
||||
IO_countContinousIntValues = IO_countContinousIntValues+pos(1)-1
|
||||
if ( IO_lc(IO_stringValue(line,pos,pos(1))) /= 'c' ) then ! line finished, read last value
|
||||
IO_countContinousIntValues = IO_countContinousIntValues+1
|
||||
exit
|
||||
endif
|
||||
IO_countDataLines = IO_countDataLines + 1_pInt
|
||||
endif
|
||||
enddo
|
||||
100 backspace(unit)
|
||||
return
|
||||
|
||||
endfunction
|
||||
|
||||
|
||||
!********************************************************************
|
||||
! count items in consecutive lines
|
||||
! Marc: ints concatenated by "c" as last char or range of values a "to" b
|
||||
! Abaqus: triplet of start,stop,inc
|
||||
!********************************************************************
|
||||
function IO_countContinousIntValues (unit)
|
||||
|
||||
use cpfem_interface
|
||||
use prec, only: pReal,pInt
|
||||
implicit none
|
||||
|
||||
integer(pInt) unit,i,j,l,count
|
||||
integer(pInt) IO_countContinousIntValues
|
||||
integer(pInt), parameter :: maxNchunks = 64
|
||||
integer(pInt), dimension(1+2*maxNchunks) :: pos
|
||||
character(len=300) line
|
||||
|
||||
IO_countContinousIntValues = 0_pInt
|
||||
|
||||
select case (FEsolver)
|
||||
case ('Marc')
|
||||
|
||||
do
|
||||
read(unit,'(A300)',end=100) line
|
||||
pos = IO_stringPos(line,maxNchunks)
|
||||
if (IO_lc(IO_stringValue(line,pos,2)) == 'to' ) then ! found range indicator
|
||||
IO_countContinousIntValues = 1 + IO_intValue(line,pos,3) - IO_intValue(line,pos,1)
|
||||
exit ! only one single range indicator allowed
|
||||
else
|
||||
IO_countContinousIntValues = IO_countContinousIntValues+pos(1)-1 ! add line's count when assuming 'c'
|
||||
if ( IO_lc(IO_stringValue(line,pos,pos(1))) /= 'c' ) then ! line finished, read last value
|
||||
IO_countContinousIntValues = IO_countContinousIntValues+1
|
||||
exit ! data ended
|
||||
endif
|
||||
endif
|
||||
enddo
|
||||
|
||||
case('Abaqus')
|
||||
|
||||
count = IO_countDataLines(unit)
|
||||
do l = 1,count
|
||||
backspace(unit)
|
||||
enddo
|
||||
|
||||
do l = 1,count
|
||||
read(unit,'(A300)',end=100) line
|
||||
pos = IO_stringPos(line,maxNchunks)
|
||||
IO_countContinousIntValues = IO_countContinousIntValues + 1 + & ! assuming range generation
|
||||
(IO_intValue(line,pos,2)-IO_intValue(line,pos,1))/max(1,IO_intValue(line,pos,3))
|
||||
enddo
|
||||
|
||||
endselect
|
||||
|
||||
100 return
|
||||
|
||||
endfunction
|
||||
|
||||
!*********************************************************************
|
||||
! read consecutive lines of ints concatenated by "c" as last char
|
||||
! or range of values a "to" b
|
||||
!*********************************************************************
|
||||
|
||||
!********************************************************************
|
||||
! return integer list corrsponding to items in consecutive lines
|
||||
! Marc: ints concatenated by "c" as last char, range of a "to" b, or named set
|
||||
! Abaqus: triplet of start,stop,inc or named set
|
||||
!********************************************************************
|
||||
function IO_continousIntValues (unit,maxN,lookupName,lookupMap,lookupMaxN)
|
||||
|
||||
use cpfem_interface
|
||||
use prec, only: pReal,pInt
|
||||
implicit none
|
||||
|
||||
integer(pInt) unit,maxN,i
|
||||
integer(pInt) unit,maxN,i,j,l,count,first,last
|
||||
integer(pInt), dimension(1+maxN) :: IO_continousIntValues
|
||||
integer(pInt), dimension(67) :: pos ! allow for 32 values excl "c"
|
||||
integer(pInt), parameter :: maxNchunks = 64
|
||||
integer(pInt), dimension(1+2*maxNchunks) :: pos
|
||||
character(len=64), dimension(:) :: lookupName
|
||||
integer(pInt) :: lookupMaxN
|
||||
integer(pInt), dimension(:,:) :: lookupMap
|
||||
character(len=300) line
|
||||
|
||||
IO_continousIntValues = 0_pInt
|
||||
do
|
||||
read(unit,'(A300)',end=100) line
|
||||
pos = IO_stringPos(line,33)
|
||||
if (verify(IO_stringValue(line,pos,1),"0123456789") > 0) then ! a non-int, i.e. set name
|
||||
do i = 1,lookupMaxN ! loop over known set names
|
||||
if (IO_stringValue(line,pos,1) == lookupName(i)) then ! found matching name
|
||||
IO_continousIntValues = lookupMap(:,i) ! return resp. entity list
|
||||
IO_continousIntValues = 0
|
||||
|
||||
select case (FEsolver)
|
||||
case ('Marc')
|
||||
|
||||
do
|
||||
read(unit,'(A300)',end=100) line
|
||||
pos = IO_stringPos(line,maxNchunks)
|
||||
if (verify(IO_stringValue(line,pos,1),"0123456789") > 0) then ! a non-int, i.e. set name
|
||||
do i = 1,lookupMaxN ! loop over known set names
|
||||
if (IO_stringValue(line,pos,1) == lookupName(i)) then ! found matching name
|
||||
IO_continousIntValues = lookupMap(:,i) ! return resp. entity list
|
||||
exit
|
||||
endif
|
||||
enddo
|
||||
exit
|
||||
else 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
|
||||
exit
|
||||
else 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
|
||||
|
||||
case('Abaqus')
|
||||
|
||||
count = IO_countDataLines(unit)
|
||||
do l = 1,count
|
||||
backspace(unit)
|
||||
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)
|
||||
|
||||
do l = 1,count
|
||||
read(unit,'(A300)',end=100) line
|
||||
pos = IO_stringPos(line,maxNchunks)
|
||||
if (verify(IO_stringValue(line,pos,1),"0123456789") > 0) then ! a non-int, i.e. set names follow on this line
|
||||
do i = 1,pos(1) ! loop over set names in line
|
||||
do j = 1,lookupMaxN ! look thru known set names
|
||||
if (IO_stringValue(line,pos,i) == lookupName(j)) then ! found matching name
|
||||
first = 2 + IO_continousIntValues(1) ! where to start appending data
|
||||
last = first + lookupMap(1,j) - 1 ! up to where to append data
|
||||
IO_continousIntValues(first:last) = lookupMap(2:1+lookupMap(1,j),j) ! add resp. entity list
|
||||
IO_continousIntValues(1) = IO_continousIntValues(1) + lookupMap(1,j) ! count them
|
||||
endif
|
||||
enddo
|
||||
enddo
|
||||
else ! assuming range generation
|
||||
do i = IO_intValue(line,pos,1),IO_intValue(line,pos,2),max(1,IO_intValue(line,pos,3))
|
||||
IO_continousIntValues(1) = IO_continousIntValues(1) + 1
|
||||
IO_continousIntValues(1+IO_continousIntValues(1)) = i
|
||||
enddo
|
||||
endif
|
||||
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
|
||||
|
||||
endselect
|
||||
|
||||
100 return
|
||||
|
||||
endfunction
|
||||
|
||||
|
||||
|
||||
!********************************************************************
|
||||
! write error statements to standard out
|
||||
! and terminate the Marc run with exit #9xxx
|
||||
|
|
File diff suppressed because it is too large
Load Diff
1347
code/mesh.f90
1347
code/mesh.f90
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,270 @@
|
|||
!* $Id$
|
||||
!********************************************************************
|
||||
! Material subroutine for Abaqus
|
||||
!
|
||||
! written by P. Eisenlohr,
|
||||
! F. Roters,
|
||||
! K. Janssens
|
||||
!
|
||||
! MPI fuer Eisenforschung, Duesseldorf
|
||||
! PSI, Switzerland
|
||||
!********************************************************************
|
||||
|
||||
MODULE cpfem_interface
|
||||
|
||||
character(len=64), parameter :: FEsolver = 'Abaqus'
|
||||
|
||||
CONTAINS
|
||||
|
||||
subroutine mpie_cpfem_init ()
|
||||
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,*)
|
||||
write(6,*) '<<<+- mpie_cpfem_abaqus init -+>>>'
|
||||
write(6,*)
|
||||
call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
return
|
||||
end subroutine
|
||||
|
||||
END MODULE
|
||||
|
||||
include "prec.f90" ! uses nothing else
|
||||
include "IO.f90" ! uses prec
|
||||
include "numerics.f90" ! uses prec, IO
|
||||
include "math.f90" ! uses prec, numerics
|
||||
include "debug.f90" ! uses prec, numerics
|
||||
include "FEsolving.f90" ! uses prec, IO
|
||||
include "mesh.f90" ! uses prec, math, IO, FEsolving
|
||||
include "material.f90" ! uses prec, math, IO, mesh
|
||||
include "lattice.f90" ! uses prec, math, IO, material
|
||||
include "constitutive_phenopowerlaw.f90" ! uses prec, math, IO, latt ice, material, debug
|
||||
include "constitutive_j2.f90" ! uses prec, math, IO, latt ice, material, debug
|
||||
include "constitutive_dislobased.f90" ! uses prec, math, IO, latt ice, material, debug
|
||||
include "constitutive_nonlocal.f90" ! uses prec, math, IO, latt ice, material, debug
|
||||
include "constitutive.f90" ! uses prec, IO, math, lattice, mesh, debug
|
||||
include "crystallite.f90" ! uses prec, math, IO, numerics
|
||||
include "homogenization_isostrain.f90" ! uses prec, math, IO,
|
||||
include "homogenization_RGC.f90" ! uses prec, math, IO, numerics, mesh: added <<<updated 31.07.2009>>>
|
||||
include "homogenization.f90" ! uses prec, math, IO, numerics
|
||||
include "CPFEM.f90" ! uses prec, math, IO, numerics, debug, FEsolving, mesh, lattice, constitutive, crystallite
|
||||
|
||||
subroutine UMAT(STRESS,STATEV,DDSDDE,SSE,SPD,SCD,&
|
||||
RPL,DDSDDT,DRPLDE,DRPLDT,STRAN,DSTRAN,&
|
||||
TIME,DTIME,TEMP,DTEMP,PREDEF,DPRED,CMNAME,NDI,NSHR,NTENS,&
|
||||
NSTATV,PROPS,NPROPS,COORDS,DROT,PNEWDT,CELENT,&
|
||||
DFGRD0,DFGRD1,NOEL,NPT,KSLAY,KSPT,KSTEP,KINC)
|
||||
|
||||
use prec, only: pReal, &
|
||||
pInt
|
||||
use FEsolving, only: cycleCounter, &
|
||||
theInc, &
|
||||
cutBack, &
|
||||
calcMode, &
|
||||
lastMode, &
|
||||
theTime, &
|
||||
theDelta, &
|
||||
lastIncConverged, &
|
||||
outdatedByNewInc, &
|
||||
outdatedFFN1, &
|
||||
terminallyIll, &
|
||||
symmetricSolver
|
||||
use math, only: invnrmMandel
|
||||
use debug, only: debug_info, &
|
||||
debug_reset
|
||||
use mesh, only: mesh_FEasCP
|
||||
use CPFEM, only: CPFEM_general,CPFEM_init_done
|
||||
use homogenization, only: materialpoint_sizeResults, materialpoint_results
|
||||
|
||||
|
||||
implicit none
|
||||
|
||||
CHARACTER*80 CMNAME
|
||||
integer(pInt) ndi, nshr, ntens, nstatv, nprops, noel, npt,&
|
||||
kslay, kspt, kstep, kinc
|
||||
real(pReal) STRESS(NTENS),STATEV(NSTATV),&
|
||||
DDSDDE(NTENS,NTENS),DDSDDT(NTENS),DRPLDE(NTENS),&
|
||||
STRAN(NTENS),DSTRAN(NTENS),TIME(2),PREDEF(1),DPRED(1),&
|
||||
PROPS(NPROPS),COORDS(3),DROT(3,3),&
|
||||
DFGRD0(3,3),DFGRD1(3,3)
|
||||
real(pReal) SSE, SPD, SCD, RPL, DRPLDT, DTIME, TEMP,&
|
||||
DTEMP, PNEWDT, CELENT
|
||||
|
||||
! local variables
|
||||
real(pReal), dimension(6) :: stress_h
|
||||
real(pReal), dimension(6,6) :: ddsdde_h
|
||||
integer(pInt) computationMode, i, cp_en
|
||||
|
||||
if (noel == 1 .and. npt == 1) then
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,*) 'el',noel,'ip',npt
|
||||
write(6,*) 'got kinc as',kinc
|
||||
write(6,*) 'got dStran',dstran
|
||||
call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
endif
|
||||
|
||||
if ( .not. CPFEM_init_done ) then
|
||||
|
||||
computationMode = 2 ! calc + init
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,'(i6,x,i2,x,a)') noel,npt,'first call special case..!'; call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
|
||||
else
|
||||
cp_en = mesh_FEasCP('elem',noel)
|
||||
if (theTime < time(2) .or. theInc /= kinc) then ! reached convergence
|
||||
lastIncConverged = .true.
|
||||
outdatedByNewInc = .true.
|
||||
terminallyIll = .false.
|
||||
cycleCounter = 0
|
||||
!$OMP CRITICAL (write2out)
|
||||
write (6,'(i6,x,i2,x,a)') noel,npt,'lastIncConverged + outdated'; call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
endif
|
||||
|
||||
if ( dtime < theDelta ) then ! cutBack
|
||||
calcMode = .true. ! pretend last step was calculation
|
||||
cutBack = .true.
|
||||
terminallyIll = .false.
|
||||
cycleCounter = 0
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,'(i6,x,i2,x,a)') noel,npt,'cutback detected..!'; call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
endif
|
||||
|
||||
calcMode(npt,cp_en) = .not. calcMode(npt,cp_en) ! ping pong (calc <--> collect)
|
||||
|
||||
if ( calcMode(npt,cp_en) ) then ! now calc
|
||||
if ( lastMode .ne. calcMode(npt,cp_en) ) then ! first after ping pong
|
||||
call debug_reset() ! resets debugging
|
||||
outdatedFFN1 = .false.
|
||||
cycleCounter = cycleCounter + 1
|
||||
endif
|
||||
if ( outdatedByNewInc ) then
|
||||
outdatedByNewInc = .false.
|
||||
computationMode = 1 ! calc and age results
|
||||
else
|
||||
computationMode = 2 ! plain calc
|
||||
endif
|
||||
else ! now collect
|
||||
if ( lastMode .ne. calcMode(npt,cp_en) ) call debug_info() ! first after ping pong reports debugging
|
||||
if ( lastIncConverged ) then
|
||||
lastIncConverged = .false.
|
||||
computationMode = 4 ! collect and backup Jacobian after convergence
|
||||
elseif ( cutBack ) then
|
||||
cutBack = .false.
|
||||
computationMode = 5 ! collect and restore Jacobian after cutback
|
||||
else
|
||||
computationMode = 3 ! plain collect
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
theTime = time(2) ! record current starting time
|
||||
theDelta = dtime ! record current time increment
|
||||
theInc = kinc ! record current increment number
|
||||
if (CPFEM_init_done) lastMode = calcMode(npt,cp_en) ! record calculationMode
|
||||
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,'(a16,x,i2,x,a,i5,a,i5,x,i5,a)') 'computationMode',computationMode,'(',cp_en,':',noel,npt,')'; call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
|
||||
call CPFEM_general(computationMode,dfgrd0,dfgrd1,temp,dtime,noel,npt,stress,ddsdde,ntens)
|
||||
|
||||
! Mandel: 11, 22, 33, SQRT(2)*12, SQRT(2)*23, SQRT(2)*13
|
||||
! straight: 11, 22, 33, 12, 23, 13
|
||||
forall(i=1:ntens) ddsdde(1:ntens,i) = invnrmMandel(i)*ddsdde(1:ntens,i)*invnrmMandel(1:ntens)
|
||||
stress(1:ntens) = stress(1:ntens)*invnrmMandel(1:ntens)
|
||||
if(symmetricSolver) ddsdde(1:ntens,1:ntens) = 0.5_pReal*(ddsdde(1:ntens,1:ntens) + transpose(ddsdde(1:ntens,1:ntens)))
|
||||
! ABAQUS: 11, 22, 33, 12, 13, 23
|
||||
if(ntens == 6) then
|
||||
stress_h=stress
|
||||
stress(5)=stress_h(6)
|
||||
stress(6)=stress_h(5)
|
||||
ddsdde_h=ddsdde
|
||||
ddsdde(:,5)=ddsdde_h(:,6)
|
||||
ddsdde(:,6)=ddsdde_h(:,5)
|
||||
ddsdde_h=ddsdde
|
||||
ddsdde(5,:)=ddsdde_h(6,:)
|
||||
ddsdde(6,:)=ddsdde_h(5,:)
|
||||
end if
|
||||
|
||||
statev = materialpoint_results(1:min(nstatv,materialpoint_sizeResults),npt,mesh_FEasCP('elem', noel))
|
||||
|
||||
if ( terminallyIll ) pnewdt = 0.5_pReal ! force cutback directly ?
|
||||
|
||||
return
|
||||
end subroutine
|
||||
|
||||
!********************************************************************
|
||||
! This subroutine replaces the corresponding Marc subroutine
|
||||
!********************************************************************
|
||||
subroutine quit(mpie_error)
|
||||
|
||||
use prec, only: pReal, &
|
||||
pInt
|
||||
implicit none
|
||||
integer(pInt) mpie_error
|
||||
|
||||
call xit
|
||||
end subroutine
|
||||
|
||||
!############################################################################
|
||||
!
|
||||
|
||||
! include "KJ_Disp.f"
|
||||
subroutine disp(u,kstep,kinc,time,node,noel,jdof,coords)
|
||||
|
||||
! hardwired aba_param.inc
|
||||
implicit real*8(a-h,o-z)
|
||||
parameter (nprecd=2)
|
||||
!
|
||||
dimension u(3),time(2), coords(3)
|
||||
|
||||
real ktime,ktcl,ktmax,ktmin,ktdeltaup,ktdeltadown
|
||||
real klmin,klmax,kldelta,klbegincycle
|
||||
real kdeltau, kru, kret
|
||||
! When using stdb_abqerr for debugging
|
||||
! dimension intv(2),realv(4)
|
||||
! character*8 charv(1)
|
||||
|
||||
! ratchet displacement per cycle
|
||||
kru = 0.1
|
||||
! ratcheting ends at time kret
|
||||
kret = 400.
|
||||
! displacement amplitude
|
||||
kdeltau = 0.5
|
||||
! time cycle length:
|
||||
ktcl = 4.
|
||||
ktmax = ktcl/4
|
||||
ktmin = 3.*ktmax
|
||||
ktdeltadown = ktmin - ktmax
|
||||
ktdeltaup = ktcl - ktdeltadown
|
||||
! load minimum & maximum:
|
||||
klmin = -kdeltau
|
||||
klmax = kdeltau
|
||||
kldelta = klmax - klmin
|
||||
klbegincycle = klmin + kldelta * (ktcl-ktmin) / ktdeltaup
|
||||
! load as a function of (total time); trianglar loading cycle
|
||||
ktime = time(2)
|
||||
kru = kru * MIN(kret, ktime) / ktcl
|
||||
if ( ktime .lt. ktmax ) then
|
||||
! special case for path to first maximum
|
||||
u(1) = kru + (ktime/ktmax) * klmax
|
||||
else
|
||||
do while ( ktime .ge. ktcl )
|
||||
ktime = ktime - ktcl
|
||||
end do
|
||||
if ( ktime .le. ktmax ) then
|
||||
u(1) = kru + klbegincycle + ktime * (klmax-klbegincycle) / ktmax
|
||||
else if ( ktime .lt. ktmin ) then
|
||||
u(1) = kru + klmax - (ktime-ktmax) * kldelta / (ktmin-ktmax)
|
||||
else
|
||||
u(1) = kru + klmin + (ktime-ktmin) * (klbegincycle-klmin)/(ktcl-ktmin)
|
||||
end if
|
||||
endif
|
||||
return
|
||||
end
|
||||
!
|
|
@ -38,6 +38,8 @@
|
|||
!
|
||||
MODULE cpfem_interface
|
||||
|
||||
character(len=64), parameter :: FEsolver = 'Marc'
|
||||
|
||||
CONTAINS
|
||||
|
||||
subroutine mpie_cpfem_init
|
||||
|
@ -61,7 +63,7 @@ END MODULE
|
|||
include "lattice.f90" ! uses prec, math, IO, material
|
||||
include "constitutive_phenopowerlaw.f90" ! uses prec, math, IO, lattice, material, debug
|
||||
include "constitutive_j2.f90" ! uses prec, math, IO, lattice, material, debug
|
||||
include "constitutive_dislotwin.f90" ! uses prec, math, IO, lattice, material, debug
|
||||
include "constitutive_dislobased.f90" ! uses prec, math, IO, lattice, material, debug
|
||||
include "constitutive_nonlocal.f90" ! uses prec, math, IO, lattice, material, debug
|
||||
include "constitutive.f90" ! uses prec, IO, math, lattice, mesh, debug
|
||||
include "crystallite.f90" ! uses prec, math, IO, numerics
|
||||
|
@ -148,18 +150,22 @@ subroutine hypela2(&
|
|||
pInt
|
||||
use FEsolving, only: cycleCounter, &
|
||||
theInc, &
|
||||
theCycle, &
|
||||
theLovl, &
|
||||
cutBack, &
|
||||
calcMode, &
|
||||
lastMode, &
|
||||
theTime, &
|
||||
theDelta, &
|
||||
lastIncConverged, &
|
||||
outdatedByNewInc, &
|
||||
outdatedFFN1, &
|
||||
terminallyIll, &
|
||||
symmetricSolver
|
||||
use CPFEM, only: CPFEM_general
|
||||
use math, only: invnrmMandel
|
||||
use debug, only: debug_info, &
|
||||
debug_reset
|
||||
use mesh, only: mesh_FEasCP
|
||||
use CPFEM, only: CPFEM_general,CPFEM_init_done
|
||||
use homogenization, only: materialpoint_sizeResults, materialpoint_results
|
||||
implicit none
|
||||
|
||||
! ** Start of generated type statements **
|
||||
|
@ -179,47 +185,74 @@ subroutine hypela2(&
|
|||
include "concom%%MARCVERSION%%" ! concom is needed for inc, subinc, ncycle, lovl
|
||||
include "creeps%%MARCVERSION%%" ! creeps is needed for timinc (time increment)
|
||||
|
||||
integer(pInt) computationMode, i
|
||||
integer(pInt) computationMode, i, cp_en
|
||||
|
||||
if (inc == 0) then
|
||||
cycleCounter = 4
|
||||
if ( .not. CPFEM_init_done ) then
|
||||
|
||||
computationMode = 2 ! calc + init
|
||||
!$OMP CRITICAL (write2out)
|
||||
write (6,'(i6,x,i2,x,a)') n(1),nn,'first call special case..!'; call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
|
||||
else if (lovl == 4) then ! Marc requires stiffness in separate call
|
||||
computationMode = 6 ! --> just return known value
|
||||
else
|
||||
if (theCycle > ncycle .or. theInc /= inc) then
|
||||
cycleCounter = 0 ! reset counter for each cutback or new inc
|
||||
cp_en = mesh_FEasCP('elem',n(1))
|
||||
if (theTime < cptim .or. theInc /= inc) then ! reached convergence
|
||||
lastIncConverged = .true.
|
||||
outdatedByNewInc = .true.
|
||||
terminallyIll = .false.
|
||||
cycleCounter = 0
|
||||
!$OMP CRITICAL (write2out)
|
||||
write (6,'(i6,x,i2,x,a)') n(1),nn,'lastIncConverged + outdated'; call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
endif
|
||||
if (theCycle /= ncycle .or. theLovl /= lovl) then
|
||||
cycleCounter = cycleCounter+1 ! ping pong
|
||||
outdatedFFN1 = .false.
|
||||
write (6,*) n(1),nn,'cycleCounter',cycleCounter
|
||||
call debug_info() ! output of debugging/performance statistics of former
|
||||
call debug_reset()
|
||||
|
||||
if ( timinc < theDelta ) then ! cutBack
|
||||
calcMode = .true. ! pretend last step was calculation
|
||||
cutBack = .true.
|
||||
terminallyIll = .false.
|
||||
cycleCounter = 0
|
||||
!$OMP CRITICAL (write2out)
|
||||
write(6,'(i6,x,i2,x,a)') n(1),nn,'cutback detected..!'; call flush(6)
|
||||
!$OMP END CRITICAL (write2out)
|
||||
endif
|
||||
endif
|
||||
if (cptim > theTime .or. theInc /= inc) then ! reached convergence
|
||||
lastIncConverged = .true.
|
||||
outdatedByNewInc = .true.
|
||||
write (6,*) n(1),nn,'lastIncConverged + outdated'
|
||||
|
||||
calcMode(nn,cp_en) = .not. calcMode(nn,cp_en) ! ping pong (calc <--> collect)
|
||||
|
||||
if ( calcMode(nn,cp_en) ) then ! now calc
|
||||
if ( lastMode .ne. calcMode(nn,cp_en) ) then ! first after ping pong
|
||||
call debug_reset() ! resets debugging
|
||||
outdatedFFN1 = .false.
|
||||
cycleCounter = cycleCounter + 1
|
||||
endif
|
||||
if ( outdatedByNewInc ) then
|
||||
outdatedByNewInc = .false.
|
||||
computationMode = 1 ! calc and age results
|
||||
else
|
||||
computationMode = 2 ! plain calc
|
||||
endif
|
||||
else ! now collect
|
||||
if ( lastMode .ne. calcMode(nn,cp_en) ) call debug_info() ! first after ping pong reports debugging
|
||||
if ( lastIncConverged ) then
|
||||
lastIncConverged = .false.
|
||||
computationMode = 4 ! collect and backup Jacobian after convergence
|
||||
elseif ( cutBack ) then
|
||||
cutBack = .false.
|
||||
computationMode = 5 ! collect and restore Jacobian after cutback
|
||||
else
|
||||
computationMode = 3 ! plain collect
|
||||
endif
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
if (mod(cycleCounter,2) /= 0) computationMode = 4 ! recycle in odd cycles
|
||||
if (mod(cycleCounter,4) == 2) computationMode = 3 ! collect in 2,6,10,...
|
||||
if (mod(cycleCounter,4) == 0) computationMode = 2 ! compute in 0,4,8,...
|
||||
if (computationMode == 4 .and. ncycle == 0 .and. .not. lastIncConverged) &
|
||||
computationMode = 6 ! recycle but restore known good consistent tangent
|
||||
if (computationMode == 4 .and. lastIncConverged) then
|
||||
computationMode = 5 ! recycle and record former consistent tangent
|
||||
lastIncConverged = .false.
|
||||
if (lovl /= 4) then ! pass-by for Marc recycle
|
||||
theTime = cptim ! record current starting time
|
||||
theDelta = timinc ! record current time increment
|
||||
theInc = inc ! record current increment number
|
||||
if (CPFEM_init_done) lastMode = calcMode(nn,cp_en) ! record calculationMode
|
||||
endif
|
||||
if (computationMode == 2 .and. outdatedByNewInc) then
|
||||
computationMode = 1 ! compute and age former results
|
||||
outdatedByNewInc = .false.
|
||||
endif
|
||||
|
||||
theTime = cptim ! record current starting time
|
||||
theInc = inc ! record current increment number
|
||||
theCycle = ncycle ! record current cycle count
|
||||
theLovl = lovl ! record current lovl
|
||||
|
||||
call CPFEM_general(computationMode,ffn,ffn1,t(1),timinc,n(1),nn,s,d,ngens)
|
||||
|
||||
|
@ -269,55 +302,3 @@ subroutine plotv(&
|
|||
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
|
Loading…
Reference in New Issue