2013-03-01 17:18:29 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
|
!> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH
|
|
|
|
|
!> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH
|
|
|
|
|
!> @author Luc Hantcherli, Max-Planck-Institut für Eisenforschung GmbH
|
|
|
|
|
!> @author W.A. Counts
|
|
|
|
|
!> @author Denny Tjahjanto, Max-Planck-Institut für Eisenforschung GmbH
|
|
|
|
|
!> @author Christoph Kords, Max-Planck-Institut für Eisenforschung GmbH
|
2018-07-10 11:54:45 +05:30
|
|
|
|
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
|
|
|
|
|
!> @brief Interfaces DAMASK with MSC.Marc
|
2013-03-01 17:18:29 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2018-07-10 11:54:45 +05:30
|
|
|
|
#define QUOTE(x) #x
|
|
|
|
|
#define PASTE(x,y) x ## y
|
|
|
|
|
|
|
|
|
|
#include "prec.f90"
|
|
|
|
|
|
2012-03-09 01:55:28 +05:30
|
|
|
|
module DAMASK_interface
|
2020-01-25 13:42:09 +05:30
|
|
|
|
use prec
|
2019-06-07 11:15:54 +05:30
|
|
|
|
#if __INTEL_COMPILER >= 1800
|
2020-09-19 14:20:32 +05:30
|
|
|
|
use, intrinsic :: ISO_fortran_env, only: &
|
2020-01-25 13:42:09 +05:30
|
|
|
|
compiler_version, &
|
|
|
|
|
compiler_options
|
2019-06-07 09:48:42 +05:30
|
|
|
|
#endif
|
2020-01-25 13:42:09 +05:30
|
|
|
|
use ifport, only: &
|
|
|
|
|
CHDIR
|
2016-07-20 12:14:12 +05:30
|
|
|
|
|
2020-01-25 13:42:09 +05:30
|
|
|
|
implicit none
|
|
|
|
|
private
|
|
|
|
|
|
2020-03-10 18:19:11 +05:30
|
|
|
|
logical, protected, public :: symmetricSolver
|
2020-01-25 13:42:09 +05:30
|
|
|
|
character(len=*), parameter, public :: INPUTFILEEXTENSION = '.dat'
|
2020-09-12 19:36:33 +05:30
|
|
|
|
|
2020-01-25 13:42:09 +05:30
|
|
|
|
public :: &
|
|
|
|
|
DAMASK_interface_init, &
|
|
|
|
|
getSolverJobName
|
2009-10-12 21:31:49 +05:30
|
|
|
|
|
2012-03-09 01:55:28 +05:30
|
|
|
|
contains
|
2009-08-31 20:51:15 +05:30
|
|
|
|
|
2013-03-01 17:18:29 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2018-07-10 11:54:45 +05:30
|
|
|
|
!> @brief reports and sets working directory
|
2013-03-01 17:18:29 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2012-03-09 01:55:28 +05:30
|
|
|
|
subroutine DAMASK_interface_init
|
2010-11-03 20:09:18 +05:30
|
|
|
|
|
2020-01-26 16:54:35 +05:30
|
|
|
|
integer, dimension(8) :: dateAndTime
|
|
|
|
|
integer :: ierr
|
|
|
|
|
character(len=pPathLen) :: wd
|
2020-02-25 14:10:38 +05:30
|
|
|
|
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print'(/,a)', ' <<<+- DAMASK_marc init -+>>>'
|
2020-02-25 14:10:38 +05:30
|
|
|
|
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print*, 'Roters et al., Computational Materials Science 158:420–478, 2019'
|
|
|
|
|
print*, 'https://doi.org/10.1016/j.commatsci.2018.04.030'
|
2020-02-25 14:10:38 +05:30
|
|
|
|
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print'(/,a)', ' Version: '//DAMASKVERSION
|
2020-02-25 14:10:38 +05:30
|
|
|
|
|
2021-02-02 13:33:41 +05:30
|
|
|
|
print'(/,a)', ' Compiled with: '//compiler_version()
|
|
|
|
|
print'(a)', ' Compiler options: '//compiler_options()
|
2020-02-25 14:10:38 +05:30
|
|
|
|
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print'(/,a)', ' Compiled on: '//__DATE__//' at '//__TIME__
|
2020-02-25 14:10:38 +05:30
|
|
|
|
|
2020-01-25 13:42:09 +05:30
|
|
|
|
call date_and_time(values = dateAndTime)
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print'(/,a,2(i2.2,a),i4.4)', ' Date: ',dateAndTime(3),'/',dateAndTime(2),'/', dateAndTime(1)
|
|
|
|
|
print'(a,2(i2.2,a),i2.2)', ' Time: ',dateAndTime(5),':', dateAndTime(6),':', dateAndTime(7)
|
2020-02-25 14:10:38 +05:30
|
|
|
|
|
2020-01-25 13:42:09 +05:30
|
|
|
|
inquire(5, name=wd)
|
|
|
|
|
wd = wd(1:scan(wd,'/',back=.true.))
|
|
|
|
|
ierr = CHDIR(wd)
|
|
|
|
|
if (ierr /= 0) then
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print*, 'working directory "'//trim(wd)//'" does not exist'
|
2020-01-25 13:42:09 +05:30
|
|
|
|
call quit(1)
|
|
|
|
|
endif
|
|
|
|
|
symmetricSolver = solverIsSymmetric()
|
2012-03-09 01:55:28 +05:30
|
|
|
|
|
|
|
|
|
end subroutine DAMASK_interface_init
|
|
|
|
|
|
2009-08-31 20:39:15 +05:30
|
|
|
|
|
2013-03-01 17:18:29 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
|
!> @brief solver job name (no extension) as combination of geometry and load case name
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-01-25 13:26:39 +05:30
|
|
|
|
function getSolverJobName()
|
2010-05-10 20:32:59 +05:30
|
|
|
|
|
2020-01-25 13:42:09 +05:30
|
|
|
|
character(len=:), allocatable :: getSolverJobName
|
|
|
|
|
character(1024) :: inputName
|
|
|
|
|
character(len=*), parameter :: pathSep = achar(47)//achar(92) ! forward and backward slash
|
|
|
|
|
integer :: extPos
|
2010-05-10 20:32:59 +05:30
|
|
|
|
|
2020-01-25 13:42:09 +05:30
|
|
|
|
inquire(5, name=inputName) ! determine inputfile
|
|
|
|
|
extPos = len_trim(inputName)-4
|
|
|
|
|
getSolverJobName=inputName(scan(inputName,pathSep,back=.true.)+1:extPos)
|
2010-05-10 20:32:59 +05:30
|
|
|
|
|
2012-03-09 01:55:28 +05:30
|
|
|
|
end function getSolverJobName
|
|
|
|
|
|
2013-03-01 17:18:29 +05:30
|
|
|
|
|
2020-01-25 13:42:09 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
|
!> @brief determines whether a symmetric solver is used
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
|
logical function solverIsSymmetric()
|
|
|
|
|
|
|
|
|
|
character(len=pStringLen) :: line
|
|
|
|
|
integer :: myStat,fileUnit,s,e
|
|
|
|
|
|
|
|
|
|
open(newunit=fileUnit, file=getSolverJobName()//INPUTFILEEXTENSION, &
|
|
|
|
|
status='old', position='rewind', action='read',iostat=myStat)
|
|
|
|
|
do
|
|
|
|
|
read (fileUnit,'(A)',END=100) line
|
|
|
|
|
if(index(trim(lc(line)),'solver') == 1) then
|
|
|
|
|
read (fileUnit,'(A)',END=100) line ! next line
|
|
|
|
|
s = verify(line, ' ') ! start of first chunk
|
|
|
|
|
s = s + verify(line(s+1:),' ') ! start of second chunk
|
|
|
|
|
e = s + scan (line(s+1:),' ') ! end of second chunk
|
|
|
|
|
solverIsSymmetric = line(s:e) /= '1'
|
|
|
|
|
endif
|
|
|
|
|
enddo
|
|
|
|
|
100 close(fileUnit)
|
|
|
|
|
contains
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
|
!> @brief changes characters in string to lower case
|
|
|
|
|
!> @details copied from IO_lc
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
|
function lc(string)
|
|
|
|
|
|
|
|
|
|
character(len=*), intent(in) :: string !< string to convert
|
|
|
|
|
character(len=len(string)) :: lc
|
|
|
|
|
|
|
|
|
|
character(26), parameter :: LOWER = 'abcdefghijklmnopqrstuvwxyz'
|
|
|
|
|
character(26), parameter :: UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
|
|
|
|
|
|
|
|
integer :: i,n
|
|
|
|
|
|
|
|
|
|
do i=1,len(string)
|
|
|
|
|
lc(i:i) = string(i:i)
|
|
|
|
|
n = index(UPPER,lc(i:i))
|
|
|
|
|
if (n/=0) lc(i:i) = LOWER(n:n)
|
|
|
|
|
enddo
|
|
|
|
|
end function lc
|
|
|
|
|
|
|
|
|
|
end function solverIsSymmetric
|
|
|
|
|
|
2012-03-09 01:55:28 +05:30
|
|
|
|
end module DAMASK_interface
|
2009-08-31 20:51:15 +05:30
|
|
|
|
|
2018-07-10 11:54:45 +05:30
|
|
|
|
|
2014-12-08 22:06:22 +05:30
|
|
|
|
#include "commercialFEM_fileList.f90"
|
2009-03-04 17:18:54 +05:30
|
|
|
|
|
2013-03-01 17:18:29 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
|
!> @brief This is the MSC.Marc user subroutine for defining material behavior
|
|
|
|
|
!> @details (1) F,R,U are only available for continuum and membrane elements (not for
|
|
|
|
|
!> @details shells and beams).
|
|
|
|
|
!> @details
|
2013-04-09 15:38:00 +05:30
|
|
|
|
!> @details (2) Use the -> 'Plasticity,3' card(=update+finite+large disp+constant d)
|
|
|
|
|
!> @details in the parameter section of input deck (updated Lagrangian formulation).
|
2013-03-01 17:18:29 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2013-04-09 15:38:00 +05:30
|
|
|
|
subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,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)
|
2020-06-16 10:04:12 +05:30
|
|
|
|
use prec
|
|
|
|
|
use DAMASK_interface
|
2020-08-15 19:32:10 +05:30
|
|
|
|
use config
|
2020-06-19 04:35:44 +05:30
|
|
|
|
use YAML_types
|
2020-06-16 10:04:12 +05:30
|
|
|
|
use discretization_marc
|
|
|
|
|
use homogenization
|
|
|
|
|
use CPFEM
|
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
include "omp_lib.h" ! the openMP function library
|
|
|
|
|
integer, intent(in) :: & ! according to MSC.Marc 2012 Manual D
|
|
|
|
|
ngens, & !< size of stress-strain law
|
|
|
|
|
nn, & !< integration point number
|
|
|
|
|
ndi, & !< number of direct components
|
|
|
|
|
nshear, & !< number of shear components
|
|
|
|
|
ncrd, & !< number of coordinates
|
|
|
|
|
itel, & !< dimension of F and R, either 2 or 3
|
|
|
|
|
ndeg, & !< number of degrees of freedom
|
|
|
|
|
ndm, & !< not specified in MSC.Marc 2012 Manual D
|
|
|
|
|
nnode, & !< number of nodes per element
|
|
|
|
|
jtype, & !< element type
|
|
|
|
|
ifr, & !< set to 1 if R has been calculated
|
|
|
|
|
ifu !< set to 1 if stretch has been calculated
|
|
|
|
|
integer, dimension(2), intent(in) :: & ! according to MSC.Marc 2012 Manual D
|
|
|
|
|
m, & !< (1) user element number, (2) internal element number
|
|
|
|
|
matus, & !< (1) user material identification number, (2) internal material identification number
|
|
|
|
|
kcus, & !< (1) layer number, (2) internal layer number
|
|
|
|
|
lclass !< (1) element class, (2) 0: displacement, 1: low order Herrmann, 2: high order Herrmann
|
|
|
|
|
real(pReal), dimension(*), intent(in) :: & ! has dimension(1) according to MSC.Marc 2012 Manual D, but according to example hypela2.f dimension(*)
|
|
|
|
|
e, & !< total elastic strain
|
|
|
|
|
de, & !< increment of strain
|
|
|
|
|
dt !< increment of state variables
|
|
|
|
|
real(pReal), dimension(itel), intent(in) :: & ! according to MSC.Marc 2012 Manual D
|
|
|
|
|
strechn, & !< square of principal stretch ratios, lambda(i) at t=n
|
|
|
|
|
strechn1 !< square of principal stretch ratios, lambda(i) at t=n+1
|
|
|
|
|
real(pReal), dimension(3,3), intent(in) :: & ! has dimension(itel,*) according to MSC.Marc 2012 Manual D, but we alway assume dimension(3,3)
|
|
|
|
|
ffn, & !< deformation gradient at t=n
|
|
|
|
|
ffn1 !< deformation gradient at t=n+1
|
|
|
|
|
real(pReal), dimension(itel,*), intent(in) :: & ! according to MSC.Marc 2012 Manual D
|
|
|
|
|
frotn, & !< rotation tensor at t=n
|
|
|
|
|
eigvn, & !< i principal direction components for j eigenvalues at t=n
|
|
|
|
|
frotn1, & !< rotation tensor at t=n+1
|
|
|
|
|
eigvn1 !< i principal direction components for j eigenvalues at t=n+1
|
|
|
|
|
real(pReal), dimension(ndeg,*), intent(in) :: & ! according to MSC.Marc 2012 Manual D
|
|
|
|
|
disp, & !< incremental displacements
|
|
|
|
|
dispt !< displacements at t=n (at assembly, lovl=4) and displacements at t=n+1 (at stress recovery, lovl=6)
|
|
|
|
|
real(pReal), dimension(ncrd,*), intent(in) :: & ! according to MSC.Marc 2012 Manual D
|
|
|
|
|
coord !< coordinates
|
|
|
|
|
real(pReal), dimension(*), intent(inout) :: & ! according to MSC.Marc 2012 Manual D
|
|
|
|
|
t !< state variables (comes in at t=n, must be updated to have state variables at t=n+1)
|
|
|
|
|
real(pReal), dimension(ndi+nshear), intent(out) :: & ! has dimension(*) according to MSC.Marc 2012 Manual D, but we need to loop over it
|
|
|
|
|
s, & !< stress - should be updated by user
|
|
|
|
|
g !< change in stress due to temperature effects
|
|
|
|
|
real(pReal), dimension(ngens,ngens), intent(out) :: & ! according to MSC.Marc 2012 Manual D, but according to example hypela2.f dimension(ngens,*)
|
|
|
|
|
d !< stress-strain law to be formed
|
2008-03-15 03:02:57 +05:30
|
|
|
|
|
2013-04-09 15:38:00 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2009-03-04 17:18:54 +05:30
|
|
|
|
! Marc common blocks are in fixed format so they have to be reformated to free format (f90)
|
|
|
|
|
! Beware of changes in newer Marc versions
|
2013-04-22 20:11:33 +05:30
|
|
|
|
|
2021-03-26 16:10:24 +05:30
|
|
|
|
#include QUOTE(PASTE(./Marc/include/concom,Marc4DAMASK)) ! concom is needed for inc, lovl
|
|
|
|
|
#include QUOTE(PASTE(./Marc/include/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment)
|
2009-03-04 17:18:54 +05:30
|
|
|
|
|
2020-06-16 10:04:12 +05:30
|
|
|
|
logical :: cutBack
|
|
|
|
|
real(pReal), dimension(6) :: stress
|
|
|
|
|
real(pReal), dimension(6,6) :: ddsdde
|
|
|
|
|
integer :: computationMode, i, cp_en, node, CPnodeID
|
2021-02-02 13:33:41 +05:30
|
|
|
|
integer(pI32) :: defaultNumThreadsInt !< default value set by Marc
|
2020-06-16 10:32:29 +05:30
|
|
|
|
|
|
|
|
|
integer(pInt), save :: &
|
|
|
|
|
theInc = -1_pInt, & !< needs description
|
|
|
|
|
lastLovl = 0_pInt !< lovl in previous call to marc hypela2
|
|
|
|
|
real(pReal), save :: &
|
|
|
|
|
theTime = 0.0_pReal, & !< needs description
|
|
|
|
|
theDelta = 0.0_pReal
|
|
|
|
|
logical, save :: &
|
|
|
|
|
lastIncConverged = .false., & !< needs description
|
|
|
|
|
outdatedByNewInc = .false., & !< needs description
|
2021-02-02 13:33:41 +05:30
|
|
|
|
CPFEM_init_done = .false., & !< remember whether init has been done already
|
2020-07-03 20:15:11 +05:30
|
|
|
|
debug_basic = .true.
|
2020-06-19 04:35:44 +05:30
|
|
|
|
class(tNode), pointer :: &
|
2020-06-26 23:42:05 +05:30
|
|
|
|
debug_Marc ! pointer to Marc debug options
|
2020-06-18 23:01:08 +05:30
|
|
|
|
|
2020-07-03 20:15:11 +05:30
|
|
|
|
if(debug_basic) then
|
2021-02-02 13:33:41 +05:30
|
|
|
|
print'(a,/,i8,i8,i2)', ' MSC.Marc information on shape of element(2), IP:', m, nn
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print'(a,2(i1))', ' Jacobian: ', ngens,ngens
|
|
|
|
|
print'(a,i1)', ' Direct stress: ', ndi
|
|
|
|
|
print'(a,i1)', ' Shear stress: ', nshear
|
|
|
|
|
print'(a,i2)', ' DoF: ', ndeg
|
|
|
|
|
print'(a,i2)', ' Coordinates: ', ncrd
|
|
|
|
|
print'(a,i12)', ' Nodes: ', nnode
|
|
|
|
|
print'(a,i1)', ' Deformation gradient: ', itel
|
2020-06-16 10:04:12 +05:30
|
|
|
|
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') ' Deformation gradient at t=n:', &
|
|
|
|
|
transpose(ffn)
|
|
|
|
|
write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') ' Deformation gradient at t=n+1:', &
|
|
|
|
|
transpose(ffn1)
|
|
|
|
|
endif
|
|
|
|
|
|
2020-07-03 20:15:11 +05:30
|
|
|
|
defaultNumThreadsInt = omp_get_num_threads() ! remember number of threads set by Marc
|
2021-02-02 13:33:41 +05:30
|
|
|
|
call omp_set_num_threads(1_pI32) ! no openMP
|
2020-07-03 20:15:11 +05:30
|
|
|
|
|
|
|
|
|
if (.not. CPFEM_init_done) then
|
|
|
|
|
CPFEM_init_done = .true.
|
|
|
|
|
call CPFEM_initAll
|
2021-03-26 17:04:16 +05:30
|
|
|
|
debug_Marc => config_debug%get('Marc',defaultVal=emptyList)
|
2020-07-03 21:42:40 +05:30
|
|
|
|
debug_basic = debug_Marc%contains('basic')
|
2020-07-03 20:15:11 +05:30
|
|
|
|
endif
|
2020-06-16 10:04:12 +05:30
|
|
|
|
|
|
|
|
|
computationMode = 0 ! save initialization value, since it does not result in any calculation
|
|
|
|
|
if (lovl == 4 ) then ! jacobian requested by marc
|
|
|
|
|
if (timinc < theDelta .and. theInc == inc .and. lastLovl /= lovl) & ! first after cutback
|
|
|
|
|
computationMode = CPFEM_RESTOREJACOBIAN
|
|
|
|
|
elseif (lovl == 6) then ! stress requested by marc
|
2020-06-16 10:32:29 +05:30
|
|
|
|
computationMode = CPFEM_CALCRESULTS
|
2021-04-11 00:22:46 +05:30
|
|
|
|
cp_en = discretization_Marc_FEM2DAMASK_elem(m(1))
|
2020-06-16 10:04:12 +05:30
|
|
|
|
if (cptim > theTime .or. inc /= theInc) then ! reached "convergence"
|
|
|
|
|
terminallyIll = .false.
|
|
|
|
|
cycleCounter = -1 ! first calc step increments this to cycle = 0
|
|
|
|
|
if (inc == 0) then ! >> start of analysis <<
|
|
|
|
|
lastIncConverged = .false.
|
|
|
|
|
outdatedByNewInc = .false.
|
|
|
|
|
lastLovl = lovl ! pretend that this is NOT the first after a lovl change
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print'(a,i6,1x,i2)', '<< HYPELA2 >> start of analysis..! ',m(1),nn
|
2020-06-16 10:04:12 +05:30
|
|
|
|
else if (inc - theInc > 1) then ! >> restart of broken analysis <<
|
|
|
|
|
lastIncConverged = .false.
|
|
|
|
|
outdatedByNewInc = .false.
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print'(a,i6,1x,i2)', '<< HYPELA2 >> restart of analysis..! ',m(1),nn
|
2020-06-16 10:04:12 +05:30
|
|
|
|
else ! >> just the next inc <<
|
|
|
|
|
lastIncConverged = .true.
|
|
|
|
|
outdatedByNewInc = .true.
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print'(a,i6,1x,i2)', '<< HYPELA2 >> new increment..! ',m(1),nn
|
2020-06-16 10:04:12 +05:30
|
|
|
|
endif
|
|
|
|
|
else if ( timinc < theDelta ) then ! >> cutBack <<
|
|
|
|
|
lastIncConverged = .false.
|
|
|
|
|
outdatedByNewInc = .false.
|
|
|
|
|
terminallyIll = .false.
|
|
|
|
|
cycleCounter = -1 ! first calc step increments this to cycle = 0
|
2020-09-17 22:58:41 +05:30
|
|
|
|
print'(a,i6,1x,i2)', '<< HYPELA2 >> cutback detected..! ',m(1),nn
|
2020-06-16 10:04:12 +05:30
|
|
|
|
endif ! convergence treatment end
|
|
|
|
|
flush(6)
|
|
|
|
|
|
|
|
|
|
if (lastLovl /= lovl) then
|
|
|
|
|
cycleCounter = cycleCounter + 1
|
|
|
|
|
!mesh_cellnode = mesh_build_cellnodes() ! update cell node coordinates
|
|
|
|
|
!call mesh_build_ipCoordinates() ! update ip coordinates
|
|
|
|
|
endif
|
|
|
|
|
if (outdatedByNewInc) then
|
|
|
|
|
computationMode = ior(computationMode,CPFEM_AGERESULTS)
|
|
|
|
|
outdatedByNewInc = .false.
|
|
|
|
|
endif
|
|
|
|
|
if (lastIncConverged) then
|
|
|
|
|
computationMode = ior(computationMode,CPFEM_BACKUPJACOBIAN)
|
|
|
|
|
lastIncConverged = .false.
|
|
|
|
|
endif
|
|
|
|
|
|
|
|
|
|
theTime = cptim
|
|
|
|
|
theDelta = timinc
|
|
|
|
|
theInc = inc
|
|
|
|
|
|
|
|
|
|
endif
|
|
|
|
|
lastLovl = lovl
|
|
|
|
|
|
|
|
|
|
call CPFEM_general(computationMode,ffn,ffn1,t(1),timinc,m(1),nn,stress,ddsdde)
|
|
|
|
|
|
|
|
|
|
d = ddsdde(1:ngens,1:ngens)
|
|
|
|
|
s = stress(1:ndi+nshear)
|
|
|
|
|
g = 0.0_pReal
|
|
|
|
|
if(symmetricSolver) d = 0.5_pReal*(d+transpose(d))
|
|
|
|
|
|
|
|
|
|
call omp_set_num_threads(defaultNumThreadsInt) ! reset number of threads to stored default value
|
2010-11-19 23:15:27 +05:30
|
|
|
|
|
2012-03-09 01:55:28 +05:30
|
|
|
|
end subroutine hypela2
|
2009-05-07 21:57:36 +05:30
|
|
|
|
|
2008-04-07 20:24:29 +05:30
|
|
|
|
|
2016-05-03 20:36:55 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2017-02-08 14:32:56 +05:30
|
|
|
|
!> @brief calculate internal heat generated due to inelastic energy dissipation
|
2016-05-03 20:36:55 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
|
subroutine flux(f,ts,n,time)
|
2020-01-25 13:42:09 +05:30
|
|
|
|
use prec
|
2021-01-24 21:34:41 +05:30
|
|
|
|
use homogenization
|
2020-03-20 11:28:55 +05:30
|
|
|
|
use discretization_marc
|
2016-07-20 12:14:12 +05:30
|
|
|
|
|
2020-01-25 13:42:09 +05:30
|
|
|
|
implicit none
|
|
|
|
|
real(pReal), dimension(6), intent(in) :: &
|
|
|
|
|
ts
|
|
|
|
|
integer, dimension(10), intent(in) :: &
|
|
|
|
|
n
|
|
|
|
|
real(pReal), intent(in) :: &
|
|
|
|
|
time
|
|
|
|
|
real(pReal), dimension(2), intent(out) :: &
|
|
|
|
|
f
|
|
|
|
|
|
2021-04-11 00:46:57 +05:30
|
|
|
|
f(1) = homogenization_f_T(discretization_Marc_FEM2DAMASK_cell(n(3),n(1)))
|
2021-01-08 13:27:30 +05:30
|
|
|
|
f(2) = 0.0_pReal
|
2017-02-08 14:32:56 +05:30
|
|
|
|
|
|
|
|
|
end subroutine flux
|
2016-05-03 20:36:55 +05:30
|
|
|
|
|
|
|
|
|
|
2019-05-05 15:36:55 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2019-06-15 19:51:15 +05:30
|
|
|
|
!> @brief trigger writing of results
|
2020-01-12 05:25:00 +05:30
|
|
|
|
!> @details uedinc is called before each new increment, not at the end of a converged one.
|
|
|
|
|
!> Therefore, storing the last written inc with an 'save' variable is required to avoid writing the
|
|
|
|
|
! same increment multiple times.
|
2019-05-05 15:36:55 +05:30
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
|
subroutine uedinc(inc,incsub)
|
2019-05-15 02:14:38 +05:30
|
|
|
|
use prec
|
2019-06-07 09:48:42 +05:30
|
|
|
|
use CPFEM
|
2021-02-02 13:33:41 +05:30
|
|
|
|
use discretization_marc
|
2019-05-05 15:36:55 +05:30
|
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
|
integer, intent(in) :: inc, incsub
|
2021-02-02 13:33:41 +05:30
|
|
|
|
integer :: n, nqncomp, nqdatatype
|
2020-01-12 05:25:00 +05:30
|
|
|
|
integer, save :: inc_written
|
2021-02-02 13:33:41 +05:30
|
|
|
|
real(pReal), allocatable, dimension(:,:) :: d_n
|
2021-03-26 17:13:27 +05:30
|
|
|
|
#include QUOTE(PASTE(./Marc/include/creeps,Marc4DAMASK)) ! creeps is needed for timinc (time increment)
|
2019-05-05 15:36:55 +05:30
|
|
|
|
|
2021-02-02 13:33:41 +05:30
|
|
|
|
|
2020-01-12 05:25:00 +05:30
|
|
|
|
if (inc > inc_written) then
|
2021-04-11 00:22:46 +05:30
|
|
|
|
allocate(d_n(3,count(discretization_Marc_FEM2DAMASK_node /= -1)))
|
|
|
|
|
do n = lbound(discretization_Marc_FEM2DAMASK_node,1), ubound(discretization_Marc_FEM2DAMASK_node,1)
|
|
|
|
|
if (discretization_Marc_FEM2DAMASK_node(n) /= -1) then
|
|
|
|
|
call nodvar(1,n,d_n(1:3,discretization_Marc_FEM2DAMASK_node(n)),nqncomp,nqdatatype)
|
|
|
|
|
if(nqncomp == 2) d_n(3,discretization_Marc_FEM2DAMASK_node(n)) = 0.0_pReal
|
2021-02-02 13:33:41 +05:30
|
|
|
|
endif
|
|
|
|
|
enddo
|
|
|
|
|
|
|
|
|
|
call discretization_marc_UpdateNodeAndIpCoords(d_n)
|
2020-01-12 05:25:00 +05:30
|
|
|
|
call CPFEM_results(inc,cptim)
|
2021-02-02 13:33:41 +05:30
|
|
|
|
|
2020-01-12 05:25:00 +05:30
|
|
|
|
inc_written = inc
|
|
|
|
|
endif
|
2019-05-05 15:36:55 +05:30
|
|
|
|
|
|
|
|
|
end subroutine uedinc
|