DAMASK with MSC.Marc FEM solver  Revision: v2.0.3-2204-gdb1f2151
The Düsseldorf Advanced Material Simulation Kit with MSC.Marc
DAMASK_marc.f90
Go to the documentation of this file.
1 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/DAMASK_marc.f90"
2 # 1 "<built-in>"
3 # 1 "<command-line>"
4 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/DAMASK_marc.f90"
5 !--------------------------------------------------------------------------------------------------
28 !--------------------------------------------------------------------------------------------------
29 
30 
31 
32 
33 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/prec.f90" 1
34 !--------------------------------------------------------------------------------------------------
41 !--------------------------------------------------------------------------------------------------
42 module prec
43  use, intrinsic :: ieee_arithmetic
44 
45  implicit none
46  public
47 
48  ! https://software.intel.com/en-us/blogs/2017/03/27/doctor-fortran-in-it-takes-all-kinds
49  integer, parameter :: preal = ieee_selected_real_kind(15,307)
50 
51  integer, parameter :: pint = selected_int_kind(18)
52 
53 
54 
55  integer, parameter :: plongint = selected_int_kind(18)
56  integer, parameter :: pstringlen = 256
57  integer, parameter :: ppathlen = 4096
58 
59  real(preal), parameter :: tol_math_check = 1.0e-8_preal
60 
61 
62  type :: group_float
63  real(preal), dimension(:), pointer :: p
64  end type group_float
65 
66  type :: group_int
67  integer, dimension(:), pointer :: p
68  end type group_int
69 
70  ! http://stackoverflow.com/questions/3948210/can-i-have-a-pointer-to-an-item-in-an-allocatable-array
71  type :: tstate
72  integer :: &
73  sizestate = 0, & !< size of state
74  sizedotstate = 0, &
75  offsetdeltastate = 0, &
76  sizedeltastate = 0
77  real(preal), pointer, dimension(:), contiguous :: &
78  atol
79  real(preal), pointer, dimension(:,:), contiguous :: & ! a pointer is needed here because we might point to state/doState. However, they will never point to something, but are rather allocated and, hence, contiguous
80  state0, &
81  state, & !< state
82  dotstate, & !< rate of state change
83  deltastate
84  real(preal), allocatable, dimension(:,:) :: &
85  partionedstate0, &
86  substate0, &
87  previousdotstate, &
88  previousdotstate2
89  real(preal), allocatable, dimension(:,:,:) :: &
90  rk4dotstate, &
91  rkck45dotstate
92  end type
93 
94  type, extends(tstate) :: tplasticstate
95  logical :: &
96  nonlocal = .false.
97  real(preal), pointer, dimension(:,:) :: &
98  sliprate, & !< slip rate
99  accumulatedslip
100  end type
101 
102  type :: tsourcestate
103  type(tstate), dimension(:), allocatable :: p
104  end type
105 
107  integer, pointer, dimension(:,:) :: p
108  end type
109 
110  real(preal), private, parameter :: preal_epsilon = epsilon(0.0_preal)
111  real(preal), private, parameter :: preal_min = tiny(0.0_preal)
112 
113  integer, dimension(0), parameter :: &
114  emptyintarray = [integer::]
115  real(preal), dimension(0), parameter :: &
116  emptyrealarray = [real(preal)::]
117  character(len=pStringLen), dimension(0), parameter :: &
118  emptystringarray = [character(len=pstringlen)::]
119 
120  private :: &
121  unittest
122 
123 contains
124 
125 
126 !--------------------------------------------------------------------------------------------------
128 !--------------------------------------------------------------------------------------------------
129 subroutine prec_init
130 
131  write(6,'(/,a)') ' <<<+- prec init -+>>>'
132 
133  write(6,'(a,i3)') ' Size of integer in bit: ',bit_size(0)
134  write(6,'(a,i19)') ' Maximum value: ',huge(0)
135  write(6,'(/,a,i3)') ' Size of float in bit: ',storage_size(0.0_preal)
136  write(6,'(a,e10.3)') ' Maximum value: ',huge(0.0_preal)
137  write(6,'(a,e10.3)') ' Minimum value: ',tiny(0.0_preal)
138  write(6,'(a,i3)') ' Decimal precision: ',precision(0.0_preal)
139 
140  call unittest
141 
142 end subroutine prec_init
143 
144 
145 !--------------------------------------------------------------------------------------------------
147 ! replaces "==" but for certain (relative) tolerance. Counterpart to dNeq
148 ! https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
149 ! AlmostEqualRelative
150 !--------------------------------------------------------------------------------------------------
151 logical elemental pure function dEq(a,b,tol)
152 
153  real(preal), intent(in) :: a,b
154  real(preal), intent(in), optional :: tol
155  real(preal) :: eps
156 
157  if (present(tol)) then
158  eps = tol
159  else
160  eps = preal_epsilon * maxval(abs([a,b]))
161  endif
162 
163  deq = merge(.true.,.false.,abs(a-b) <= eps)
164 
165 end function deq
166 
167 
168 !--------------------------------------------------------------------------------------------------
170 ! replaces "!=" but for certain (relative) tolerance. Counterpart to dEq
171 ! https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
172 ! AlmostEqualRelative NOT
173 !--------------------------------------------------------------------------------------------------
174 logical elemental pure function dneq(a,b,tol)
175 
176  real(preal), intent(in) :: a,b
177  real(preal), intent(in), optional :: tol
178 
179  if (present(tol)) then
180  dneq = .not. deq(a,b,tol)
181  else
182  dneq = .not. deq(a,b)
183  endif
184 
185 end function dneq
186 
187 
188 !--------------------------------------------------------------------------------------------------
190 ! replaces "==0" but everything not representable as a normal number is treated as 0. Counterpart to dNeq0
191 ! https://de.mathworks.com/help/matlab/ref/realmin.html
192 ! https://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html
193 !--------------------------------------------------------------------------------------------------
194 logical elemental pure function deq0(a,tol)
195 
196  real(preal), intent(in) :: a
197  real(preal), intent(in), optional :: tol
198  real(preal) :: eps
199 
200  if (present(tol)) then
201  eps = tol
202  else
203  eps = preal_min * 10.0_preal
204  endif
205 
206  deq0 = merge(.true.,.false.,abs(a) <= eps)
207 
208 end function deq0
209 
210 
211 !--------------------------------------------------------------------------------------------------
213 ! replaces "!=0" but everything not representable as a normal number is treated as 0. Counterpart to dEq0
214 ! https://de.mathworks.com/help/matlab/ref/realmin.html
215 ! https://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html
216 !--------------------------------------------------------------------------------------------------
217 logical elemental pure function dneq0(a,tol)
218 
219  real(preal), intent(in) :: a
220  real(preal), intent(in), optional :: tol
221 
222  if (present(tol)) then
223  dneq0 = .not. deq0(a,tol)
224  else
225  dneq0 = .not. deq0(a)
226  endif
227 
228 end function dneq0
229 
230 
231 !--------------------------------------------------------------------------------------------------
233 ! replaces "==" but for certain (relative) tolerance. Counterpart to cNeq
234 ! https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
235 ! probably a component wise comparison would be more accurate than the comparsion of the absolute
236 ! value
237 !--------------------------------------------------------------------------------------------------
238 logical elemental pure function ceq(a,b,tol)
239 
240  complex(pReal), intent(in) :: a,b
241  real(preal), intent(in), optional :: tol
242  real(preal) :: eps
243 
244  if (present(tol)) then
245  eps = tol
246  else
247  eps = preal_epsilon * maxval(abs([a,b]))
248  endif
249 
250  ceq = merge(.true.,.false.,abs(a-b) <= eps)
251 
252 end function ceq
253 
254 
255 !--------------------------------------------------------------------------------------------------
257 ! replaces "!=" but for certain (relative) tolerance. Counterpart to cEq
258 ! https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
259 ! probably a component wise comparison would be more accurate than the comparsion of the absolute
260 ! value
261 !--------------------------------------------------------------------------------------------------
262 logical elemental pure function cneq(a,b,tol)
263 
264  complex(pReal), intent(in) :: a,b
265  real(preal), intent(in), optional :: tol
266 
267  if (present(tol)) then
268  cneq = .not. ceq(a,b,tol)
269  else
270  cneq = .not. ceq(a,b)
271  endif
272 
273 end function cneq
274 
275 
276 !--------------------------------------------------------------------------------------------------
278 !--------------------------------------------------------------------------------------------------
279 subroutine unittest
280 
281  integer, allocatable, dimension(:) :: realloc_lhs_test
282  real(preal), dimension(2) :: r
283  external :: &
284  quit
285 
286  call random_number(r)
287  r = r/minval(r)
288  if(.not. all(deq(r,r+preal_epsilon))) call quit(9000)
289  if(deq(r(1),r(2)) .and. dneq(r(1),r(2))) call quit(9000)
290  if(.not. all(deq0(r-(r+preal_min)))) call quit(9000)
291 
292  realloc_lhs_test = [1,2]
293  if (any(realloc_lhs_test/=[1,2])) call quit(9000)
294 
295 end subroutine unittest
296 
297 end module prec
298 # 29 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/DAMASK_marc.f90" 2
299 
301  use prec
302 
303 
304 
305 
306 
307  use ifport, only: &
308  chdir
309 
310  implicit none
311  private
312 
313  logical, protected, public :: symmetricsolver
314  character(len=*), parameter, public :: inputfileextension = '.dat'
315 
316  public :: &
319 
320 contains
321 
322 !--------------------------------------------------------------------------------------------------
324 !--------------------------------------------------------------------------------------------------
325 subroutine damask_interface_init
326 
327  integer, dimension(8) :: dateandtime
328  integer :: ierr
329  character(len=pPathLen) :: wd
330 
331  write(6,'(/,a)') ' <<<+- DAMASK_marc init -+>>>'
332 
333  write(6,'(/,a)') ' Roters et al., Computational Materials Science 158:420–478, 2019'
334  write(6,'(a)') ' https://doi.org/10.1016/j.commatsci.2018.04.030'
335 
336  write(6,'(/,a)') ' Version: '//damaskversion
337 
338  ! https://github.com/jeffhammond/HPCInfo/blob/master/docs/Preprocessor-Macros.md
339 
340 
341 
342 
343  write(6,'(/,a,i4.4,a,i8.8)') ' Compiled with Intel fortran version :', __intel_compiler,&
344  ', build date :', __intel_compiler_build_date
345 
346 
347  write(6,'(/,a)') ' Compiled on: '//"Apr 1 2020"//' at '//"18:44:55"
348 
349  call date_and_time(values = dateandtime)
350  write(6,'(/,a,2(i2.2,a),i4.4)') ' Date: ',dateandtime(3),'/',dateandtime(2),'/', dateandtime(1)
351  write(6,'(a,2(i2.2,a),i2.2)') ' Time: ',dateandtime(5),':', dateandtime(6),':', dateandtime(7)
352 
353  inquire(5, name=wd)
354  wd = wd(1:scan(wd,'/',back=.true.))
355  ierr = chdir(wd)
356  if (ierr /= 0) then
357  write(6,'(a20,a,a16)') ' working directory "',trim(wd),'" does not exist'
358  call quit(1)
359  endif
361 
362 end subroutine damask_interface_init
363 
364 
365 !--------------------------------------------------------------------------------------------------
367 !--------------------------------------------------------------------------------------------------
368 function getsolverjobname()
369 
370  character(len=:), allocatable :: getsolverjobname
371  character(1024) :: inputname
372  character(len=*), parameter :: pathsep = achar(47)//achar(92) ! forward and backward slash
373  integer :: extpos
374 
375  inputname=''
376  inquire(5, name=inputname) ! determine inputfile
377  extpos = len_trim(inputname)-4
378  getsolverjobname=inputname(scan(inputname,pathsep,back=.true.)+1:extpos)
379 
380 end function getsolverjobname
381 
382 
383 !--------------------------------------------------------------------------------------------------
385 !--------------------------------------------------------------------------------------------------
386 logical function solverissymmetric()
387 
388  character(len=pStringLen) :: line
389  integer :: mystat,fileunit,s,e
390 
391  open(newunit=fileunit, file=getsolverjobname()//inputfileextension, &
392  status='old', position='rewind', action='read',iostat=mystat)
393  do
394  read (fileunit,'(A)',END=100) line
395  if(index(trim(lc(line)),'solver') == 1) then
396  read (fileunit,'(A)',END=100) line ! next line
397  s = verify(line, ' ') ! start of first chunk
398  s = s + verify(line(s+1:),' ') ! start of second chunk
399  e = s + scan(line(s+1:),' ') ! end of second chunk
400  solverissymmetric = line(s:e) /= '1'
401  endif
402  enddo
403 100 close(fileunit)
404  contains
405 
406  !--------------------------------------------------------------------------------------------------
409  !--------------------------------------------------------------------------------------------------
410  function lc(string)
411 
412  character(len=*), intent(in) :: string
413  character(len=len(string)) :: lc
414 
415  character(26), parameter :: lower = 'abcdefghijklmnopqrstuvwxyz'
416  character(26), parameter :: upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
417 
418  integer :: i,n
419 
420  do i=1,len(string)
421  lc(i:i) = string(i:i)
422  n = index(upper,lc(i:i))
423  if (n/=0) lc(i:i) = lower(n:n)
424  enddo
425  end function lc
426 
427 end function solverissymmetric
428 
429 end module damask_interface
430 
431 
432 
433 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 1
434 !--------------------------------------------------------------------------------------------------
438 !--------------------------------------------------------------------------------------------------
439 
440 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/IO.f90" 1
441 !--------------------------------------------------------------------------------------------------
447 !--------------------------------------------------------------------------------------------------
448 module io
449  use prec
450 
451  implicit none
452  private
453  character(len=*), parameter, public :: &
454  io_eof = '#EOF#', & !< end of file string
455  io_whitespace = achar(44)//achar(32)//achar(9)//achar(10)//achar(13)
456  character, parameter, public :: &
457  io_eol = new_line('DAMASK'), &
458  io_comment = '#'
459  character(len=*), parameter, private :: &
460  io_divider = '───────────────────'//&
461  '───────────────────'//&
462  '───────────────────'//&
463  '────────────'
464  public :: &
465  io_init, &
466  io_read_ascii, &
467  io_open_binary, &
468  io_isblank, &
469  io_gettag, &
470  io_stringpos, &
471  io_stringvalue, &
472  io_floatvalue, &
473  io_intvalue, &
474  io_lc, &
475  io_error, &
476  io_warning
477 
478 contains
479 
480 
481 !--------------------------------------------------------------------------------------------------
483 !--------------------------------------------------------------------------------------------------
484 subroutine io_init
485 
486  write(6,'(/,a)') ' <<<+- IO init -+>>>'; flush(6)
487 
488  call unittest
489 
490 end subroutine io_init
491 
492 
493 !--------------------------------------------------------------------------------------------------
495 !--------------------------------------------------------------------------------------------------
496 function io_read_ascii(fileName) result(fileContent)
497 
498  character(len=*), intent(in) :: filename
499 
500  character(len=pStringLen), dimension(:), allocatable :: filecontent
501  character(len=pStringLen) :: line
502  character(len=:), allocatable :: rawdata
503  integer :: &
504  filelength, &
505  fileunit, &
506  startpos, endpos, &
507  mytotallines, & !< # lines read from file
508  l, &
509  mystat
510  logical :: warned
511 
512 !--------------------------------------------------------------------------------------------------
513 ! read data as stream
514  inquire(file = filename, size=filelength)
515  if (filelength == 0) then
516  allocate(filecontent(0))
517  return
518  endif
519  open(newunit=fileunit, file=filename, access='stream',&
520  status='old', position='rewind', action='read',iostat=mystat)
521  if(mystat /= 0) call io_error(100,ext_msg=trim(filename))
522  allocate(character(len=fileLength)::rawdata)
523  read(fileunit) rawdata
524  close(fileunit)
525 
526 !--------------------------------------------------------------------------------------------------
527 ! count lines to allocate string array
528  mytotallines = 1
529  do l=1, len(rawdata)
530  if (rawdata(l:l) == io_eol) mytotallines = mytotallines+1
531  enddo
532  allocate(filecontent(mytotallines))
533 
534 !--------------------------------------------------------------------------------------------------
535 ! split raw data at end of line
536  warned = .false.
537  startpos = 1
538  l = 1
539  do while (l <= mytotallines)
540  endpos = merge(startpos + scan(rawdata(startpos:),io_eol) - 2,len(rawdata),l /= mytotallines)
541  if (endpos - startpos > pstringlen-1) then
542  line = rawdata(startpos:startpos+pstringlen-1)
543  if (.not. warned) then
544  call io_warning(207,ext_msg=trim(filename),el=l)
545  warned = .true.
546  endif
547  else
548  line = rawdata(startpos:endpos)
549  endif
550  startpos = endpos + 2 ! jump to next line start
551 
552  filecontent(l) = line
553  l = l + 1
554  enddo
555 
556 end function io_read_ascii
557 
558 
559 !--------------------------------------------------------------------------------------------------
562 !--------------------------------------------------------------------------------------------------
563 integer function io_open_binary(fileName,mode)
564 
565  character(len=*), intent(in) :: filename
566  character, intent(in), optional :: mode
567 
568  character :: m
569  integer :: ierr
570 
571  if (present(mode)) then
572  m = mode
573  else
574  m = 'r'
575  endif
576 
577  if (m == 'w') then
578  open(newunit=io_open_binary, file=trim(filename),&
579  status='replace',access='stream',action='write',iostat=ierr)
580  if (ierr /= 0) call io_error(100,ext_msg='could not open file (w): '//trim(filename))
581  elseif(m == 'r') then
582  open(newunit=io_open_binary, file=trim(filename),&
583  status='old', access='stream',action='read', iostat=ierr)
584  if (ierr /= 0) call io_error(100,ext_msg='could not open file (r): '//trim(filename))
585  else
586  call io_error(100,ext_msg='unknown access mode: '//m)
587  endif
588 
589 end function io_open_binary
590 
591 
592 !--------------------------------------------------------------------------------------------------
594 !--------------------------------------------------------------------------------------------------
595 logical pure function io_isblank(string)
596 
597  character(len=*), intent(in) :: string
598 
599  integer :: posnonblank
600 
601  posnonblank = verify(string,io_whitespace)
602  io_isblank = posnonblank == 0 .or. posnonblank == scan(string,io_comment)
603 
604 end function io_isblank
605 
606 
607 !--------------------------------------------------------------------------------------------------
609 !--------------------------------------------------------------------------------------------------
610 pure function io_gettag(string,openChar,closeChar)
611 
612  character(len=*), intent(in) :: string
613  character, intent(in) :: openchar, & !< indicates beginning of tag
614  closechar
615  character(len=:), allocatable :: io_gettag
616 
617  integer :: left,right
618 
619  left = scan(string,openchar)
620  right = merge(scan(string,closechar), &
621  left + merge(scan(string(left+1:),openchar),0,len(string) > left), &
622  openchar /= closechar)
623 
624  foundtag: if (left == verify(string,io_whitespace) .and. right > left) then
625  io_gettag = string(left+1:right-1)
626  else foundtag
627  io_gettag = ''
628  endif foundtag
629 
630 end function io_gettag
631 
632 
633 !--------------------------------------------------------------------------------------------------
638 !--------------------------------------------------------------------------------------------------
639 pure function io_stringpos(string)
640 
641  character(len=*), intent(in) :: string
642  integer, dimension(:), allocatable :: io_stringpos
643 
644  integer :: left, right
645 
646  allocate(io_stringpos(1), source=0)
647  right = 0
648 
649  do while (verify(string(right+1:),io_whitespace)>0)
650  left = right + verify(string(right+1:),io_whitespace)
651  right = left + scan(string(left:),io_whitespace) - 2
652  if ( string(left:left) == io_comment) exit
653  io_stringpos = [io_stringpos,left,right]
654  io_stringpos(1) = io_stringpos(1)+1
655  endofstring: if (right < left) then
656  io_stringpos(io_stringpos(1)*2+1) = len_trim(string)
657  exit
658  endif endofstring
659  enddo
660 
661 end function io_stringpos
662 
663 
664 !--------------------------------------------------------------------------------------------------
666 !--------------------------------------------------------------------------------------------------
667 function io_stringvalue(string,chunkPos,myChunk)
668 
669  character(len=*), intent(in) :: string
670  integer, dimension(:), intent(in) :: chunkpos
671  integer, intent(in) :: mychunk
672  character(len=:), allocatable :: io_stringvalue
673 
674  validchunk: if (mychunk > chunkpos(1) .or. mychunk < 1) then
675  io_stringvalue = ''
676  call io_error(110,el=mychunk,ext_msg='IO_stringValue: "'//trim(string)//'"')
677  else validchunk
678  io_stringvalue = string(chunkpos(mychunk*2):chunkpos(mychunk*2+1))
679  endif validchunk
680 
681 end function io_stringvalue
682 
683 
684 !--------------------------------------------------------------------------------------------------
686 !--------------------------------------------------------------------------------------------------
687 integer function io_intvalue(string,chunkPos,myChunk)
688 
689  character(len=*), intent(in) :: string
690  integer, dimension(:), intent(in) :: chunkpos
691  integer, intent(in) :: mychunk
692 
693  io_intvalue = verifyintvalue(io_stringvalue(string,chunkpos,mychunk))
694 
695 end function io_intvalue
696 
697 
698 !--------------------------------------------------------------------------------------------------
700 !--------------------------------------------------------------------------------------------------
701 real(pReal) function io_floatvalue(string,chunkPos,myChunk)
702 
703  character(len=*), intent(in) :: string
704  integer, dimension(:), intent(in) :: chunkpos
705  integer, intent(in) :: mychunk
706 
707  io_floatvalue = verifyfloatvalue(io_stringvalue(string,chunkpos,mychunk))
708 
709 end function io_floatvalue
710 
711 
712 !--------------------------------------------------------------------------------------------------
714 !--------------------------------------------------------------------------------------------------
715 pure function io_lc(string)
716 
717  character(len=*), intent(in) :: string
718  character(len=len(string)) :: io_lc
719 
720  character(len=*), parameter :: lower = 'abcdefghijklmnopqrstuvwxyz'
721  character(len=len(LOWER)), parameter :: upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
722 
723  integer :: i,n
724 
725  do i=1,len(string)
726  n = index(upper,string(i:i))
727  if(n/=0) then
728  io_lc(i:i) = lower(n:n)
729  else
730  io_lc(i:i) = string(i:i)
731  endif
732  enddo
733 
734 end function io_lc
735 
736 
737 !--------------------------------------------------------------------------------------------------
739 !--------------------------------------------------------------------------------------------------
740 subroutine io_error(error_ID,el,ip,g,instance,ext_msg)
741 
742  integer, intent(in) :: error_id
743  integer, optional, intent(in) :: el,ip,g,instance
744  character(len=*), optional, intent(in) :: ext_msg
745 
746  external :: quit
747  character(len=pStringLen) :: msg
748  character(len=pStringLen) :: formatstring
749 
750  select case (error_id)
751 
752 !--------------------------------------------------------------------------------------------------
753 ! internal errors
754  case (0)
755  msg = 'internal check failed:'
756 
757 !--------------------------------------------------------------------------------------------------
758 ! file handling errors
759  case (100)
760  msg = 'could not open file:'
761  case (101)
762  msg = 'write error for file:'
763  case (102)
764  msg = 'could not read file:'
765  case (103)
766  msg = 'could not assemble input files'
767  case (106)
768  msg = 'working directory does not exist:'
769 
770 !--------------------------------------------------------------------------------------------------
771 ! file parsing errors
772  case (110)
773  msg = 'invalid chunk selected'
774  case (111)
775  msg = 'invalid character for int:'
776  case (112)
777  msg = 'invalid character for float:'
778 
779 !--------------------------------------------------------------------------------------------------
780 ! lattice error messages
781  case (130)
782  msg = 'unknown lattice structure encountered'
783  case (131)
784  msg = 'hex lattice structure with invalid c/a ratio'
785  case (132)
786  msg = 'trans_lattice_structure not possible'
787  case (133)
788  msg = 'transformed hex lattice structure with invalid c/a ratio'
789  case (134)
790  msg = 'negative lattice parameter'
791  case (135)
792  msg = 'zero entry on stiffness diagonal'
793  case (136)
794  msg = 'zero entry on stiffness diagonal for transformed phase'
795  case (137)
796  msg = 'not defined for lattice structure'
797  case (138)
798  msg = 'not enough interaction parameters given'
799 
800 !--------------------------------------------------------------------------------------------------
801 ! errors related to the parsing of material.config
802  case (140)
803  msg = 'key not found'
804  case (141)
805  msg = 'number of chunks in string differs'
806  case (142)
807  msg = 'empty list'
808  case (143)
809  msg = 'no value found for key'
810  case (144)
811  msg = 'negative number systems requested'
812  case (145)
813  msg = 'too many systems requested'
814  case (146)
815  msg = 'number of values does not match'
816  case (147)
817  msg = 'not supported anymore'
818  case (148)
819  msg = 'Nconstituents mismatch between homogenization and microstructure'
820 
821 !--------------------------------------------------------------------------------------------------
822 ! material error messages and related messages in mesh
823  case (150)
824  msg = 'index out of bounds'
825  case (151)
826  msg = 'microstructure has no constituents'
827  case (153)
828  msg = 'sum of phase fractions differs from 1'
829  case (154)
830  msg = 'homogenization index out of bounds'
831  case (155)
832  msg = 'microstructure index out of bounds'
833  case (157)
834  msg = 'invalid texture transformation specified'
835  case (160)
836  msg = 'no entries in config part'
837  case (161)
838  msg = 'config part found twice'
839  case (165)
840  msg = 'homogenization configuration'
841  case (170)
842  msg = 'no homogenization specified via State Variable 2'
843  case (180)
844  msg = 'no microstructure specified via State Variable 3'
845  case (190)
846  msg = 'unknown element type:'
847  case (191)
848  msg = 'mesh consists of more than one element type'
849 
850 !--------------------------------------------------------------------------------------------------
851 ! plasticity error messages
852  case (200)
853  msg = 'unknown elasticity specified:'
854  case (201)
855  msg = 'unknown plasticity specified:'
856 
857  case (210)
858  msg = 'unknown material parameter:'
859  case (211)
860  msg = 'material parameter out of bounds:'
861 
862 !--------------------------------------------------------------------------------------------------
863 ! numerics error messages
864  case (300)
865  msg = 'unknown numerics parameter:'
866  case (301)
867  msg = 'numerics parameter out of bounds:'
868 
869 !--------------------------------------------------------------------------------------------------
870 ! math errors
871  case (400)
872  msg = 'matrix inversion error'
873  case (401)
874  msg = 'error in Eigenvalue calculation'
875  case (402)
876  msg = 'invalid orientation specified'
877 
878 !-------------------------------------------------------------------------------------------------
879 ! homogenization errors
880  case (500)
881  msg = 'unknown homogenization specified'
882 
883 !--------------------------------------------------------------------------------------------------
884 ! user errors
885  case (600)
886  msg = 'Ping-Pong not possible when using non-DAMASK elements'
887  case (601)
888  msg = 'Ping-Pong needed when using non-local plasticity'
889  case (602)
890  msg = 'invalid selection for debug'
891 
892 !-------------------------------------------------------------------------------------------------
893 ! errors related to the grid solver
894  case (809)
895  msg = 'initializing FFTW'
896  case (810)
897  msg = 'FFTW plan creation'
898  case (831)
899  msg = 'mask consistency violated in grid load case'
900  case (832)
901  msg = 'ill-defined L (line partly defined) in grid load case'
902  case (834)
903  msg = 'negative time increment in grid load case'
904  case (835)
905  msg = 'non-positive increments in grid load case'
906  case (836)
907  msg = 'non-positive result frequency in grid load case'
908  case (837)
909  msg = 'incomplete loadcase'
910  case (838)
911  msg = 'mixed boundary conditions allow rotation'
912  case (839)
913  msg = 'non-positive restart frequency in grid load case'
914  case (841)
915  msg = 'missing header length info in grid mesh'
916  case (842)
917  msg = 'incomplete information in grid mesh header'
918  case (843)
919  msg = 'microstructure count mismatch'
920  case (846)
921  msg = 'rotation for load case rotation ill-defined (R:RT != I)'
922  case (891)
923  msg = 'unknown solver type selected'
924  case (892)
925  msg = 'unknown filter type selected'
926  case (894)
927  msg = 'MPI error'
928 
929 
930 !-------------------------------------------------------------------------------------------------
931 ! general error messages
932  case default
933  msg = 'unknown error number...'
934 
935  end select
936 
937  !$OMP CRITICAL (write2out)
938  write(0,'(/,a)') ' ┌'//io_divider//'┐'
939  write(0,'(a,24x,a,40x,a)') ' │','error', '│'
940  write(0,'(a,24x,i3,42x,a)') ' │',error_id, '│'
941  write(0,'(a)') ' ├'//io_divider//'┤'
942  write(formatstring,'(a,i6.6,a,i6.6,a)') '(1x,a4,a',max(1,len_trim(msg)),',',&
943  max(1,72-len_trim(msg)-4),'x,a)'
944  write(0,formatstring) '│ ',trim(msg), '│'
945  if (present(ext_msg)) then
946  write(formatstring,'(a,i6.6,a,i6.6,a)') '(1x,a4,a',max(1,len_trim(ext_msg)),',',&
947  max(1,72-len_trim(ext_msg)-4),'x,a)'
948  write(0,formatstring) '│ ',trim(ext_msg), '│'
949  endif
950  if (present(el)) &
951  write(0,'(a19,1x,i9,44x,a3)') ' │ at element ',el, '│'
952  if (present(ip)) &
953  write(0,'(a19,1x,i9,44x,a3)') ' │ at IP ',ip, '│'
954  if (present(g)) &
955  write(0,'(a19,1x,i9,44x,a3)') ' │ at constituent',g, '│'
956  if (present(instance)) &
957  write(0,'(a19,1x,i9,44x,a3)') ' │ at instance ',instance, '│'
958  write(0,'(a,69x,a)') ' │', '│'
959  write(0,'(a)') ' └'//io_divider//'┘'
960  flush(0)
961  call quit(9000+error_id)
962  !$OMP END CRITICAL (write2out)
963 
964 end subroutine io_error
965 
966 
967 !--------------------------------------------------------------------------------------------------
969 !--------------------------------------------------------------------------------------------------
970 subroutine io_warning(warning_ID,el,ip,g,ext_msg)
971 
972  integer, intent(in) :: warning_id
973  integer, optional, intent(in) :: el,ip,g
974  character(len=*), optional, intent(in) :: ext_msg
975 
976  character(len=pStringLen) :: msg
977  character(len=pStringLen) :: formatstring
978 
979  select case (warning_id)
980  case (1)
981  msg = 'unknown key'
982  case (34)
983  msg = 'invalid restart increment given'
984  case (35)
985  msg = 'could not get $DAMASK_NUM_THREADS'
986  case (40)
987  msg = 'found spectral solver parameter'
988  case (42)
989  msg = 'parameter has no effect'
990  case (43)
991  msg = 'main diagonal of C66 close to zero'
992  case (47)
993  msg = 'no valid parameter for FFTW, using FFTW_PATIENT'
994  case (50)
995  msg = 'not all available slip system families are defined'
996  case (51)
997  msg = 'not all available twin system families are defined'
998  case (52)
999  msg = 'not all available parameters are defined'
1000  case (53)
1001  msg = 'not all available transformation system families are defined'
1002  case (101)
1003  msg = 'crystallite debugging off'
1004  case (201)
1005  msg = 'position not found when parsing line'
1006  case (207)
1007  msg = 'line truncated'
1008  case (600)
1009  msg = 'crystallite responds elastically'
1010  case (601)
1011  msg = 'stiffness close to zero'
1012  case (650)
1013  msg = 'polar decomposition failed'
1014  case (700)
1015  msg = 'unknown crystal symmetry'
1016  case (850)
1017  msg = 'max number of cut back exceeded, terminating'
1018  case default
1019  msg = 'unknown warning number'
1020  end select
1021 
1022  !$OMP CRITICAL (write2out)
1023  write(6,'(/,a)') ' ┌'//io_divider//'┐'
1024  write(6,'(a,24x,a,38x,a)') ' │','warning', '│'
1025  write(6,'(a,24x,i3,42x,a)') ' │',warning_id, '│'
1026  write(6,'(a)') ' ├'//io_divider//'┤'
1027  write(formatstring,'(a,i6.6,a,i6.6,a)') '(1x,a4,a',max(1,len_trim(msg)),',',&
1028  max(1,72-len_trim(msg)-4),'x,a)'
1029  write(6,formatstring) '│ ',trim(msg), '│'
1030  if (present(ext_msg)) then
1031  write(formatstring,'(a,i6.6,a,i6.6,a)') '(1x,a4,a',max(1,len_trim(ext_msg)),',',&
1032  max(1,72-len_trim(ext_msg)-4),'x,a)'
1033  write(6,formatstring) '│ ',trim(ext_msg), '│'
1034  endif
1035  if (present(el)) &
1036  write(6,'(a19,1x,i9,44x,a3)') ' │ at element ',el, '│'
1037  if (present(ip)) &
1038  write(6,'(a19,1x,i9,44x,a3)') ' │ at IP ',ip, '│'
1039  if (present(g)) &
1040  write(6,'(a19,1x,i9,44x,a3)') ' │ at constituent',g, '│'
1041  write(6,'(a,69x,a)') ' │', '│'
1042  write(6,'(a)') ' └'//io_divider//'┘'
1043  flush(6)
1044  !$OMP END CRITICAL (write2out)
1045 
1046 end subroutine io_warning
1047 
1048 
1049 !--------------------------------------------------------------------------------------------------
1050 ! internal helper functions
1051 
1052 !--------------------------------------------------------------------------------------------------
1054 !--------------------------------------------------------------------------------------------------
1055 integer function verifyintvalue(string)
1057  character(len=*), intent(in) :: string
1058 
1059  integer :: readstatus
1060  character(len=*), parameter :: validchars = '0123456789+- '
1061 
1062  valid: if (verify(string,validchars) == 0) then
1063  read(string,*,iostat=readstatus) verifyintvalue
1064  if (readstatus /= 0) call io_error(111,ext_msg=string)
1065  else valid
1066  verifyintvalue = 0
1067  call io_error(111,ext_msg=string)
1068  endif valid
1069 
1070 end function verifyintvalue
1071 
1072 
1073 !--------------------------------------------------------------------------------------------------
1075 !--------------------------------------------------------------------------------------------------
1076 real(pReal) function verifyfloatvalue(string)
1078  character(len=*), intent(in) :: string
1079 
1080  integer :: readstatus
1081  character(len=*), parameter :: validchars = '0123456789eE.+- '
1082 
1083  valid: if (verify(string,validchars) == 0) then
1084  read(string,*,iostat=readstatus) verifyfloatvalue
1085  if (readstatus /= 0) call io_error(112,ext_msg=string)
1086  else valid
1087  verifyfloatvalue = 0.0_preal
1088  call io_error(112,ext_msg=string)
1089  endif valid
1090 
1091 end function verifyfloatvalue
1092 
1093 
1094 !--------------------------------------------------------------------------------------------------
1096 !--------------------------------------------------------------------------------------------------
1097 subroutine unittest
1099  integer, dimension(:), allocatable :: chunkPos
1100  character(len=:), allocatable :: str
1101 
1102  if(dneq(1.0_preal, verifyfloatvalue('1.0'))) call io_error(0,ext_msg='verifyFloatValue')
1103  if(dneq(1.0_preal, verifyfloatvalue('1e0'))) call io_error(0,ext_msg='verifyFloatValue')
1104  if(dneq(0.1_preal, verifyfloatvalue('1e-1'))) call io_error(0,ext_msg='verifyFloatValue')
1105 
1106  if(3112019 /= verifyintvalue( '3112019')) call io_error(0,ext_msg='verifyIntValue')
1107  if(3112019 /= verifyintvalue(' 3112019')) call io_error(0,ext_msg='verifyIntValue')
1108  if(-3112019 /= verifyintvalue('-3112019')) call io_error(0,ext_msg='verifyIntValue')
1109  if(3112019 /= verifyintvalue('+3112019 ')) call io_error(0,ext_msg='verifyIntValue')
1110 
1111  if(any([1,1,1] /= io_stringpos('a'))) call io_error(0,ext_msg='IO_stringPos')
1112  if(any([2,2,3,5,5] /= io_stringpos(' aa b'))) call io_error(0,ext_msg='IO_stringPos')
1113 
1114  str=' 1.0 xxx'
1115  chunkpos = io_stringpos(str)
1116  if(dneq(1.0_preal,io_floatvalue(str,chunkpos,1))) call io_error(0,ext_msg='IO_floatValue')
1117 
1118  str='M 3112019 F'
1119  chunkpos = io_stringpos(str)
1120  if(3112019 /= io_intvalue(str,chunkpos,2)) call io_error(0,ext_msg='IO_intValue')
1121 
1122  if(.not. io_isblank(' ')) call io_error(0,ext_msg='IO_isBlank/1')
1123  if(.not. io_isblank(' #isBlank')) call io_error(0,ext_msg='IO_isBlank/2')
1124  if( io_isblank(' i#s')) call io_error(0,ext_msg='IO_isBlank/3')
1125 
1126 end subroutine unittest
1127 
1128 end module io
1129 # 7 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
1130 
1131 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/numerics.f90" 1
1132 !--------------------------------------------------------------------------------------------------
1136 !--------------------------------------------------------------------------------------------------
1137 module numerics
1138  use prec
1139  use io
1140 
1141 
1142 
1143 
1144 
1145 !$ use OMP_LIB
1146 
1147  implicit none
1148  private
1149 
1150  integer, protected, public :: &
1151  ijacostiffness = 1, & !< frequency of stiffness update
1152  randomseed = 0, &
1153  worldrank = 0, &
1154  worldsize = 1, &
1155  numerics_integrator = 1
1156  integer(4), protected, public :: &
1158  real(preal), protected, public :: &
1159  defgradtolerance = 1.0e-7_preal, &
1160  numerics_unitlength = 1.0_preal, &
1161  charlength = 1.0_preal, &
1162  residualstiffness = 1.0e-6_preal
1163  logical, protected, public :: &
1164  usepingpong = .true.
1165 
1166 !--------------------------------------------------------------------------------------------------
1167 ! field parameters:
1168  real(preal), protected, public :: &
1169  err_struct_tolabs = 1.0e-10_preal, &
1170  err_struct_tolrel = 1.0e-4_preal, &
1171  err_thermal_tolabs = 1.0e-2_preal, &
1172  err_thermal_tolrel = 1.0e-6_preal, &
1173  err_damage_tolabs = 1.0e-2_preal, &
1174  err_damage_tolrel = 1.0e-6_preal
1175  integer, protected, public :: &
1176  itmax = 250, & !< maximum number of iterations
1177  itmin = 1, &
1178  stagitmax = 10, &
1179  maxcutback = 3
1180 
1181 !--------------------------------------------------------------------------------------------------
1182 ! spectral parameters:
1183 # 65 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/numerics.f90"
1184 
1185 !--------------------------------------------------------------------------------------------------
1186 ! FEM parameters:
1187 # 77 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/numerics.f90"
1188 
1189  public :: numerics_init
1190 
1191 contains
1192 
1193 
1194 !--------------------------------------------------------------------------------------------------
1196 ! a sanity check
1197 !--------------------------------------------------------------------------------------------------
1198 subroutine numerics_init
1199 !$ integer :: gotDAMASK_NUM_THREADS = 1
1200  integer :: i,j, ierr
1201  integer, allocatable, dimension(:) :: chunkpos
1202  character(len=pStringLen), dimension(:), allocatable :: filecontent
1203  character(len=pStringLen) :: &
1204  tag ,&
1205  line
1206  logical :: fexist
1207 !$ character(len=6) DAMASK_NumThreadsString ! environment variable DAMASK_NUM_THREADS
1208 
1209 
1210 
1211 
1212 
1213  write(6,'(/,a)') ' <<<+- numerics init -+>>>'
1214 
1215 !$ call GET_ENVIRONMENT_VARIABLE(NAME='DAMASK_NUM_THREADS',VALUE=DAMASK_NumThreadsString,STATUS=gotDAMASK_NUM_THREADS) ! get environment variable DAMASK_NUM_THREADS...
1216 !$ if(gotDAMASK_NUM_THREADS /= 0) then ! could not get number of threads, set it to 1
1217 !$ call IO_warning(35,ext_msg='BEGIN:'//DAMASK_NumThreadsString//':END')
1218 !$ DAMASK_NumThreadsInt = 1_4
1219 !$ else
1220 !$ read(DAMASK_NumThreadsString,'(i6)') DAMASK_NumThreadsInt ! read as integer
1221 !$ if (DAMASK_NumThreadsInt < 1_4) DAMASK_NumThreadsInt = 1_4 ! in case of string conversion fails, set it to one
1222 !$ endif
1223 !$ call omp_set_num_threads(DAMASK_NumThreadsInt) ! set number of threads for parallel execution
1224 
1225  inquire(file='numerics.config', exist=fexist)
1226 
1227  fileexists: if (fexist) then
1228  write(6,'(a,/)') ' using values from config file'
1229  flush(6)
1230  filecontent = io_read_ascii('numerics.config')
1231  do j=1, size(filecontent)
1232 
1233 !--------------------------------------------------------------------------------------------------
1234 ! read variables from config file and overwrite default parameters if keyword is present
1235  line = filecontent(j)
1236  do i=1,len(line)
1237  if(line(i:i) == '=') line(i:i) = ' ' ! also allow keyword = value version
1238  enddo
1239  if (io_isblank(line)) cycle ! skip empty lines
1240  chunkpos = io_stringpos(line)
1241  tag = io_lc(io_stringvalue(line,chunkpos,1)) ! extract key
1242 
1243  select case(tag)
1244  case ('defgradtolerance')
1245  defgradtolerance = io_floatvalue(line,chunkpos,2)
1246  case ('ijacostiffness')
1247  ijacostiffness = io_intvalue(line,chunkpos,2)
1248  case ('integrator')
1249  numerics_integrator = io_intvalue(line,chunkpos,2)
1250  case ('usepingpong')
1251  usepingpong = io_intvalue(line,chunkpos,2) > 0
1252  case ('unitlength')
1253  numerics_unitlength = io_floatvalue(line,chunkpos,2)
1254 
1255 !--------------------------------------------------------------------------------------------------
1256 ! random seeding parameter
1257  case ('random_seed','fixed_seed')
1258  randomseed = io_intvalue(line,chunkpos,2)
1259 
1260 !--------------------------------------------------------------------------------------------------
1261 ! gradient parameter
1262  case ('charlength')
1263  charlength = io_floatvalue(line,chunkpos,2)
1264  case ('residualstiffness')
1265  residualstiffness = io_floatvalue(line,chunkpos,2)
1266 
1267 !--------------------------------------------------------------------------------------------------
1268 ! field parameters
1269  case ('err_struct_tolabs')
1270  err_struct_tolabs = io_floatvalue(line,chunkpos,2)
1271  case ('err_struct_tolrel')
1272  err_struct_tolrel = io_floatvalue(line,chunkpos,2)
1273  case ('err_thermal_tolabs')
1274  err_thermal_tolabs = io_floatvalue(line,chunkpos,2)
1275  case ('err_thermal_tolrel')
1276  err_thermal_tolrel = io_floatvalue(line,chunkpos,2)
1277  case ('err_damage_tolabs')
1278  err_damage_tolabs = io_floatvalue(line,chunkpos,2)
1279  case ('err_damage_tolrel')
1280  err_damage_tolrel = io_floatvalue(line,chunkpos,2)
1281  case ('itmax')
1282  itmax = io_intvalue(line,chunkpos,2)
1283  case ('itmin')
1284  itmin = io_intvalue(line,chunkpos,2)
1285  case ('maxcutback')
1286  maxcutback = io_intvalue(line,chunkpos,2)
1287  case ('maxstaggerediter')
1288  stagitmax = io_intvalue(line,chunkpos,2)
1289 
1290 !--------------------------------------------------------------------------------------------------
1291 ! spectral parameters
1292 # 201 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/numerics.f90"
1293 
1294 !--------------------------------------------------------------------------------------------------
1295 ! FEM parameters
1296 # 214 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/numerics.f90"
1297  end select
1298  enddo
1299  else fileexists
1300  write(6,'(a,/)') ' using standard values'
1301  flush(6)
1302  endif fileexists
1303 
1304 
1305 !--------------------------------------------------------------------------------------------------
1306 ! writing parameters to output
1307  write(6,'(a24,1x,es8.1)') ' defgradTolerance: ',defgradtolerance
1308  write(6,'(a24,1x,i8)') ' iJacoStiffness: ',ijacostiffness
1309  write(6,'(a24,1x,i8)') ' integrator: ',numerics_integrator
1310  write(6,'(a24,1x,L8)') ' use ping pong scheme: ',usepingpong
1311  write(6,'(a24,1x,es8.1,/)')' unitlength: ',numerics_unitlength
1312 
1313 !--------------------------------------------------------------------------------------------------
1314 ! Random seeding parameter
1315  write(6,'(a16,1x,i16,/)') ' random_seed: ',randomseed
1316  if (randomseed <= 0) &
1317  write(6,'(a,/)') ' random seed will be generated!'
1318 
1319 !--------------------------------------------------------------------------------------------------
1320 ! gradient parameter
1321  write(6,'(a24,1x,es8.1)') ' charLength: ',charlength
1322  write(6,'(a24,1x,es8.1)') ' residualStiffness: ',residualstiffness
1323 
1324 !--------------------------------------------------------------------------------------------------
1325 ! openMP parameter
1326  !$ write(6,'(a24,1x,i8,/)') ' number of threads: ',DAMASK_NumThreadsInt
1327 
1328 !--------------------------------------------------------------------------------------------------
1329 ! field parameters
1330  write(6,'(a24,1x,i8)') ' itmax: ',itmax
1331  write(6,'(a24,1x,i8)') ' itmin: ',itmin
1332  write(6,'(a24,1x,i8)') ' maxCutBack: ',maxcutback
1333  write(6,'(a24,1x,i8)') ' maxStaggeredIter: ',stagitmax
1334  write(6,'(a24,1x,es8.1)') ' err_struct_tolAbs: ',err_struct_tolabs
1335  write(6,'(a24,1x,es8.1)') ' err_struct_tolRel: ',err_struct_tolrel
1336  write(6,'(a24,1x,es8.1)') ' err_thermal_tolabs: ',err_thermal_tolabs
1337  write(6,'(a24,1x,es8.1)') ' err_thermal_tolrel: ',err_thermal_tolrel
1338  write(6,'(a24,1x,es8.1)') ' err_damage_tolabs: ',err_damage_tolabs
1339  write(6,'(a24,1x,es8.1)') ' err_damage_tolrel: ',err_damage_tolrel
1340 
1341 !--------------------------------------------------------------------------------------------------
1342 ! spectral parameters
1343 # 271 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/numerics.f90"
1344 
1345 !--------------------------------------------------------------------------------------------------
1346 ! spectral parameters
1347 
1348 
1349 
1350 
1351 
1352 
1353 
1354 !--------------------------------------------------------------------------------------------------
1355 ! sanity checks
1356  if (defgradtolerance <= 0.0_preal) call io_error(301,ext_msg='defgradTolerance')
1357  if (ijacostiffness < 1) call io_error(301,ext_msg='iJacoStiffness')
1358  if (numerics_integrator <= 0 .or. numerics_integrator >= 6) &
1359  call io_error(301,ext_msg='integrator')
1360  if (numerics_unitlength <= 0.0_preal) call io_error(301,ext_msg='unitlength')
1361  if (residualstiffness < 0.0_preal) call io_error(301,ext_msg='residualStiffness')
1362  if (itmax <= 1) call io_error(301,ext_msg='itmax')
1363  if (itmin > itmax .or. itmin < 1) call io_error(301,ext_msg='itmin')
1364  if (maxcutback < 0) call io_error(301,ext_msg='maxCutBack')
1365  if (stagitmax < 0) call io_error(301,ext_msg='maxStaggeredIter')
1366  if (err_struct_tolrel <= 0.0_preal) call io_error(301,ext_msg='err_struct_tolRel')
1367  if (err_struct_tolabs <= 0.0_preal) call io_error(301,ext_msg='err_struct_tolAbs')
1368  if (err_thermal_tolabs <= 0.0_preal) call io_error(301,ext_msg='err_thermal_tolabs')
1369  if (err_thermal_tolrel <= 0.0_preal) call io_error(301,ext_msg='err_thermal_tolrel')
1370  if (err_damage_tolabs <= 0.0_preal) call io_error(301,ext_msg='err_damage_tolabs')
1371  if (err_damage_tolrel <= 0.0_preal) call io_error(301,ext_msg='err_damage_tolrel')
1372 # 311 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/numerics.f90"
1373 
1374 end subroutine numerics_init
1375 
1376 end module numerics
1377 # 8 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
1378 
1379 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/debug.f90" 1
1380 !--------------------------------------------------------------------------------------------------
1386 !--------------------------------------------------------------------------------------------------
1387 module debug
1388  use prec
1389  use io
1390 
1391  implicit none
1392  private
1393 
1394  integer, parameter, public :: &
1395  debug_levelselective = 2**0, &
1396  debug_levelbasic = 2**1, &
1397  debug_levelextensive = 2**2
1398  integer, parameter, private :: &
1399  debug_maxgeneral = debug_levelextensive ! must be set to the last bitcode used by (potentially) all debug types
1400  integer, parameter, public :: &
1406 
1407  integer, parameter, public :: &
1408  debug_debug = 1, &
1409  debug_math = 2, &
1410  debug_fesolving = 3, &
1411  debug_mesh = 4, &
1412  debug_material = 5, &
1413  debug_lattice = 6, &
1414  debug_constitutive = 7, &
1415  debug_crystallite = 8, &
1416  debug_homogenization = 9, &
1417  debug_cpfem = 10, &
1418  debug_spectral = 11, &
1419  debug_marc = 12
1420  integer, parameter, private :: &
1422 
1423  integer,protected, dimension(debug_maxNtype+2), public :: & ! specific ones, and 2 for "all" and "other"
1424  debug_level = 0
1425 
1426  integer, protected, public :: &
1427  debug_e = 1, &
1428  debug_i = 1, &
1429  debug_g = 1
1430 
1431  integer, dimension(2), public :: &
1436 
1437 
1438  real(preal), public :: &
1439  debug_stressmax = -huge(1.0_preal), &
1440  debug_stressmin = huge(1.0_preal), &
1441  debug_jacobianmax = -huge(1.0_preal), &
1442  debug_jacobianmin = huge(1.0_preal)
1443 
1444 
1445 
1446 
1447 
1448  public :: debug_init, &
1449  debug_reset, &
1450  debug_info
1451 
1452 contains
1453 
1454 
1455 !--------------------------------------------------------------------------------------------------
1457 !--------------------------------------------------------------------------------------------------
1458 subroutine debug_init
1460  character(len=pStringLen), dimension(:), allocatable :: filecontent
1461 
1462  integer :: i, what, j
1463  integer, allocatable, dimension(:) :: chunkpos
1464  character(len=pStringLen) :: tag, line
1465  logical :: fexist
1466 
1467  write(6,'(/,a)') ' <<<+- debug init -+>>>'
1468 
1469 
1470 
1471 
1472 
1473  inquire(file='debug.config', exist=fexist)
1474 
1475  fileexists: if (fexist) then
1476  filecontent = io_read_ascii('debug.config')
1477  do j=1, size(filecontent)
1478  line = filecontent(j)
1479  if (io_isblank(line)) cycle ! skip empty lines
1480  chunkpos = io_stringpos(line)
1481  tag = io_lc(io_stringvalue(line,chunkpos,1)) ! extract key
1482  select case(tag)
1483  case ('element','e','el')
1484  debug_e = io_intvalue(line,chunkpos,2)
1485  case ('integrationpoint','i','ip')
1486  debug_i = io_intvalue(line,chunkpos,2)
1487  case ('grain','g','gr')
1488  debug_g = io_intvalue(line,chunkpos,2)
1489  end select
1490 
1491  what = 0
1492  select case(tag)
1493  case ('debug')
1494  what = debug_debug
1495  case ('math')
1496  what = debug_math
1497  case ('fesolving', 'fe')
1498  what = debug_fesolving
1499  case ('mesh')
1500  what = debug_mesh
1501  case ('material')
1502  what = debug_material
1503  case ('lattice')
1504  what = debug_lattice
1505  case ('constitutive')
1506  what = debug_constitutive
1507  case ('crystallite')
1508  what = debug_crystallite
1509  case ('homogenization')
1510  what = debug_homogenization
1511  case ('cpfem')
1512  what = debug_cpfem
1513  case ('spectral')
1514  what = debug_spectral
1515  case ('marc')
1516  what = debug_marc
1517  case ('all')
1518  what = debug_maxntype + 1
1519  case ('other')
1520  what = debug_maxntype + 2
1521  end select
1522  if (what /= 0) then
1523  do i = 2, chunkpos(1)
1524  select case(io_lc(io_stringvalue(line,chunkpos,i)))
1525  case('basic')
1526  debug_level(what) = ior(debug_level(what), debug_levelbasic)
1527  case('extensive')
1528  debug_level(what) = ior(debug_level(what), debug_levelextensive)
1529  case('selective')
1530  debug_level(what) = ior(debug_level(what), debug_levelselective)
1531  case('restart')
1532  debug_level(what) = ior(debug_level(what), debug_spectralrestart)
1533  case('fft','fftw')
1534  debug_level(what) = ior(debug_level(what), debug_spectralfftw)
1535  case('divergence')
1537  case('rotation')
1538  debug_level(what) = ior(debug_level(what), debug_spectralrotation)
1539  case('petsc')
1540  debug_level(what) = ior(debug_level(what), debug_spectralpetsc)
1541  end select
1542  enddo
1543  endif
1544  enddo
1545 
1546  do i = 1, debug_maxntype
1547  if (debug_level(i) == 0) &
1548  debug_level(i) = ior(debug_level(i), debug_level(debug_maxntype + 2)) ! fill undefined debug types with levels specified by "other"
1549 
1550  debug_level(i) = ior(debug_level(i), debug_level(debug_maxntype + 1)) ! fill all debug types with levels specified by "all"
1551  enddo
1552 
1553  if (iand(debug_level(debug_debug),debug_levelbasic) /= 0) &
1554  write(6,'(a,/)') ' using values from config file'
1555  else fileexists
1556  if (iand(debug_level(debug_debug),debug_levelbasic) /= 0) &
1557  write(6,'(a,/)') ' using standard values'
1558  endif fileexists
1559 
1560 !--------------------------------------------------------------------------------------------------
1561 ! output switched on (debug level for debug must be extensive)
1562  if (iand(debug_level(debug_debug),debug_levelextensive) /= 0) then
1563  do i = 1, debug_maxntype
1564  select case(i)
1565  case (debug_debug)
1566  tag = ' Debug'
1567  case (debug_math)
1568  tag = ' Math'
1569  case (debug_fesolving)
1570  tag = ' FEsolving'
1571  case (debug_mesh)
1572  tag = ' Mesh'
1573  case (debug_material)
1574  tag = ' Material'
1575  case (debug_lattice)
1576  tag = ' Lattice'
1577  case (debug_constitutive)
1578  tag = ' Constitutive'
1579  case (debug_crystallite)
1580  tag = ' Crystallite'
1581  case (debug_homogenization)
1582  tag = ' Homogenizaiton'
1583  case (debug_cpfem)
1584  tag = ' CPFEM'
1585  case (debug_spectral)
1586  tag = ' Spectral solver'
1587  case (debug_marc)
1588  tag = ' MSC.MARC FEM solver'
1589  end select
1590 
1591  if(debug_level(i) /= 0) then
1592  write(6,'(3a)') ' debug level for ', trim(tag), ':'
1593  if(iand(debug_level(i),debug_levelbasic) /= 0) write(6,'(a)') ' basic'
1594  if(iand(debug_level(i),debug_levelextensive) /= 0) write(6,'(a)') ' extensive'
1595  if(iand(debug_level(i),debug_levelselective) /= 0) then
1596  write(6,'(a)') ' selective on:'
1597  write(6,'(a24,1x,i8)') ' element: ',debug_e
1598  write(6,'(a24,1x,i8)') ' ip: ',debug_i
1599  write(6,'(a24,1x,i8)') ' grain: ',debug_g
1600  endif
1601  if(iand(debug_level(i),debug_spectralrestart) /= 0) write(6,'(a)') ' restart'
1602  if(iand(debug_level(i),debug_spectralfftw) /= 0) write(6,'(a)') ' FFTW'
1603  if(iand(debug_level(i),debug_spectraldivergence)/= 0) write(6,'(a)') ' divergence'
1604  if(iand(debug_level(i),debug_spectralrotation) /= 0) write(6,'(a)') ' rotation'
1605  if(iand(debug_level(i),debug_spectralpetsc) /= 0) write(6,'(a)') ' PETSc'
1606  endif
1607  enddo
1608  endif
1609 
1610 end subroutine debug_init
1611 
1612 
1613 !--------------------------------------------------------------------------------------------------
1615 !--------------------------------------------------------------------------------------------------
1616 subroutine debug_reset
1622  debug_stressmax = -huge(1.0_preal)
1623  debug_stressmin = huge(1.0_preal)
1624  debug_jacobianmax = -huge(1.0_preal)
1625  debug_jacobianmin = huge(1.0_preal)
1626 
1627 end subroutine debug_reset
1628 
1629 
1630 !--------------------------------------------------------------------------------------------------
1632 !--------------------------------------------------------------------------------------------------
1633 subroutine debug_info
1635  !$OMP CRITICAL (write2out)
1636  debugoutputcpfem: if (iand(debug_level(debug_cpfem),debug_levelbasic) /= 0 &
1637  .and. any(debug_stressminlocation /= 0) &
1638  .and. any(debug_stressmaxlocation /= 0) ) then
1639  write(6,'(2/,a,/)') ' Extreme values of returned stress and Jacobian'
1640  write(6,'(a39)') ' value el ip'
1641  write(6,'(a14,1x,e12.3,1x,i8,1x,i4)') ' stress min :', debug_stressmin, debug_stressminlocation
1642  write(6,'(a14,1x,e12.3,1x,i8,1x,i4)') ' max :', debug_stressmax, debug_stressmaxlocation
1643  write(6,'(a14,1x,e12.3,1x,i8,1x,i4)') ' Jacobian min :', debug_jacobianmin, debug_jacobianminlocation
1644  write(6,'(a14,1x,e12.3,1x,i8,1x,i4,/)') ' max :', debug_jacobianmax, debug_jacobianmaxlocation
1645  endif debugoutputcpfem
1646  !$OMP END CRITICAL (write2out)
1647 
1648 end subroutine debug_info
1649 
1650 end module debug
1651 # 9 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
1652 
1653 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/list.f90" 1
1654 !-------------------------------------------------------------------------------------------------
1657 !--------------------------------------------------------------------------------------------------
1658 module list
1659  use prec
1660  use io
1661 
1662  implicit none
1663  private
1664  type, private :: tpartitionedstring
1665  character(len=:), allocatable :: val
1666  integer, dimension(:), allocatable :: pos
1667  end type tpartitionedstring
1668 
1669  type, public :: tpartitionedstringlist
1670  type(tpartitionedstring) :: string
1671  type(tpartitionedstringlist), pointer :: next => null()
1672  contains
1673  procedure :: add => add
1674  procedure :: show => show
1675  procedure :: free => free
1676 
1677  ! currently, a finalize is needed for all shapes of tPartitionedStringList.
1678  ! with Fortran 2015, we can define one recursive elemental function
1679  ! https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/543326
1680  final :: finalize, &
1681  finalizearray
1682 
1683  procedure :: keyexists => keyexists
1684  procedure :: countkeys => countkeys
1685 
1686  procedure :: getfloat => getfloat
1687  procedure :: getint => getint
1688  procedure :: getstring => getstring
1689 
1690  procedure :: getfloats => getfloats
1691  procedure :: getints => getints
1692  procedure :: getstrings => getstrings
1693 
1694  end type tpartitionedstringlist
1695 
1696 contains
1697 
1698 !--------------------------------------------------------------------------------------------------
1703 !--------------------------------------------------------------------------------------------------
1704 subroutine add(this,string)
1706  class(tpartitionedstringlist), target, intent(in) :: this
1707  character(len=*), intent(in) :: string
1708  type(tpartitionedstringlist), pointer :: new, temp
1709 
1710  if (io_isblank(string)) return
1711 
1712  allocate(new)
1713  temp => this
1714  do while (associated(temp%next))
1715  temp => temp%next
1716  enddo
1717  temp%string%val = io_lc(trim(string))
1718  temp%string%pos = io_stringpos(trim(string))
1719  temp%next => new
1720 
1721 end subroutine add
1722 
1723 
1724 !--------------------------------------------------------------------------------------------------
1727 !--------------------------------------------------------------------------------------------------
1728 subroutine show(this)
1730  class(tpartitionedstringlist), target, intent(in) :: this
1731  type(tpartitionedstringlist), pointer :: item
1732 
1733  item => this
1734  do while (associated(item%next))
1735  write(6,'(a)') ' '//trim(item%string%val)
1736  item => item%next
1737  enddo
1738 
1739 end subroutine show
1740 
1741 
1742 !--------------------------------------------------------------------------------------------------
1745 !--------------------------------------------------------------------------------------------------
1746 subroutine free(this)
1748  class(tpartitionedstringlist), intent(inout) :: this
1749 
1750  if(associated(this%next)) deallocate(this%next)
1751 
1752 end subroutine free
1753 
1754 
1755 !--------------------------------------------------------------------------------------------------
1758 !--------------------------------------------------------------------------------------------------
1759 recursive subroutine finalize(this)
1761  type(tpartitionedstringlist), intent(inout) :: this
1762 
1763  if(associated(this%next)) deallocate(this%next)
1764 
1765 end subroutine finalize
1766 
1767 
1768 !--------------------------------------------------------------------------------------------------
1771 !--------------------------------------------------------------------------------------------------
1772 subroutine finalizearray(this)
1774  integer :: i
1775  type(tpartitionedstringlist), intent(inout), dimension(:) :: this
1776  type(tpartitionedstringlist), pointer :: temp ! bug in Gfortran?
1777 
1778  do i=1, size(this)
1779  if (associated(this(i)%next)) then
1780  temp => this(i)%next
1781  !deallocate(this(i)) !internal compiler error: in gfc_build_final_call, at fortran/trans.c:975
1782  deallocate(temp)
1783  endif
1784  enddo
1785 
1786 end subroutine finalizearray
1787 
1788 
1789 !--------------------------------------------------------------------------------------------------
1791 !--------------------------------------------------------------------------------------------------
1792 logical function keyexists(this,key)
1794  class(tpartitionedstringlist), target, intent(in) :: this
1795  character(len=*), intent(in) :: key
1796  type(tpartitionedstringlist), pointer :: item
1797 
1798  keyexists = .false.
1799 
1800  item => this
1801  do while (associated(item%next) .and. .not. keyexists)
1802  keyexists = trim(io_stringvalue(item%string%val,item%string%pos,1)) == trim(key)
1803  item => item%next
1804  enddo
1805 
1806 end function keyexists
1807 
1808 
1809 !--------------------------------------------------------------------------------------------------
1812 !--------------------------------------------------------------------------------------------------
1813 integer function countkeys(this,key)
1815  class(tpartitionedstringlist), target, intent(in) :: this
1816  character(len=*), intent(in) :: key
1817  type(tpartitionedstringlist), pointer :: item
1818 
1819  countkeys = 0
1820 
1821  item => this
1822  do while (associated(item%next))
1823  if (trim(io_stringvalue(item%string%val,item%string%pos,1)) == trim(key)) &
1824  countkeys = countkeys + 1
1825  item => item%next
1826  enddo
1827 
1828 end function countkeys
1829 
1830 
1831 !--------------------------------------------------------------------------------------------------
1835 !--------------------------------------------------------------------------------------------------
1836 real(pReal) function getfloat(this,key,defaultVal)
1838  class(tpartitionedstringlist), target, intent(in) :: this
1839  character(len=*), intent(in) :: key
1840  real(preal), intent(in), optional :: defaultval
1841  type(tpartitionedstringlist), pointer :: item
1842  logical :: found
1843 
1844  getfloat = huge(1.0) ! suppress warning about unitialized value
1845  found = present(defaultval)
1846  if (found) getfloat = defaultval
1847 
1848  item => this
1849  do while (associated(item%next))
1850  if (trim(io_stringvalue(item%string%val,item%string%pos,1)) == trim(key)) then
1851  found = .true.
1852  if (item%string%pos(1) < 2) call io_error(143,ext_msg=key)
1853  getfloat = io_floatvalue(item%string%val,item%string%pos,2)
1854  endif
1855  item => item%next
1856  enddo
1857 
1858  if (.not. found) call io_error(140,ext_msg=key)
1859 
1860 end function getfloat
1861 
1862 
1863 !--------------------------------------------------------------------------------------------------
1867 !--------------------------------------------------------------------------------------------------
1868 integer function getint(this,key,defaultVal)
1870  class(tpartitionedstringlist), target, intent(in) :: this
1871  character(len=*), intent(in) :: key
1872  integer, intent(in), optional :: defaultval
1873  type(tpartitionedstringlist), pointer :: item
1874  logical :: found
1875 
1876  getint = huge(1) ! suppress warning about unitialized value
1877  found = present(defaultval)
1878  if (found) getint = defaultval
1879 
1880  item => this
1881  do while (associated(item%next))
1882  if (trim(io_stringvalue(item%string%val,item%string%pos,1)) == trim(key)) then
1883  found = .true.
1884  if (item%string%pos(1) < 2) call io_error(143,ext_msg=key)
1885  getint = io_intvalue(item%string%val,item%string%pos,2)
1886  endif
1887  item => item%next
1888  enddo
1889 
1890  if (.not. found) call io_error(140,ext_msg=key)
1891 
1892 end function getint
1893 
1894 
1895 !--------------------------------------------------------------------------------------------------
1900 !--------------------------------------------------------------------------------------------------
1901 character(len=pStringLen) function getstring(this,key,defaultVal,raw)
1903  class(tpartitionedstringlist), target, intent(in) :: this
1904  character(len=*), intent(in) :: key
1905  character(len=*), intent(in), optional :: defaultval
1906  logical, intent(in), optional :: raw
1907  type(tpartitionedstringlist), pointer :: item
1908  logical :: found, &
1909  whole
1910  if (present(raw)) then
1911  whole = raw
1912  else
1913  whole = .false.
1914  endif
1915 
1916  found = present(defaultval)
1917  if (found) then
1918  if (len_trim(defaultval) > len(getstring)) call io_error(0,ext_msg='getString')
1919  getstring = trim(defaultval)
1920  endif
1921 
1922  item => this
1923  do while (associated(item%next))
1924  if (trim(io_stringvalue(item%string%val,item%string%pos,1)) == trim(key)) then
1925  found = .true.
1926  if (item%string%pos(1) < 2) call io_error(143,ext_msg=key)
1927 
1928  if (whole) then
1929  getstring = trim(item%string%val(item%string%pos(4):)) ! raw string starting a second chunk
1930  else
1931  getstring = io_stringvalue(item%string%val,item%string%pos,2)
1932  endif
1933  endif
1934  item => item%next
1935  enddo
1936 
1937  if (.not. found) call io_error(140,ext_msg=key)
1938 
1939 end function getstring
1940 
1941 
1942 !--------------------------------------------------------------------------------------------------
1946 !--------------------------------------------------------------------------------------------------
1947 function getfloats(this,key,defaultVal,requiredSize)
1949  real(preal), dimension(:), allocatable :: getfloats
1950  class(tpartitionedstringlist), target, intent(in) :: this
1951  character(len=*), intent(in) :: key
1952  real(preal), dimension(:), intent(in), optional :: defaultval
1953  integer, intent(in), optional :: requiredsize
1954  type(tpartitionedstringlist), pointer :: item
1955  integer :: i
1956  logical :: found, &
1957  cumulative
1958 
1959  cumulative = (key(1:1) == '(' .and. key(len_trim(key):len_trim(key)) == ')')
1960  found = .false.
1961 
1962  allocate(getfloats(0))
1963 
1964  item => this
1965  do while (associated(item%next))
1966  if (trim(io_stringvalue(item%string%val,item%string%pos,1)) == trim(key)) then
1967  found = .true.
1968  if (.not. cumulative) getfloats = [real(preal)::]
1969  if (item%string%pos(1) < 2) call io_error(143,ext_msg=key)
1970  do i = 2, item%string%pos(1)
1971  getfloats = [getfloats,io_floatvalue(item%string%val,item%string%pos,i)]
1972  enddo
1973  endif
1974  item => item%next
1975  enddo
1976 
1977  if (.not. found) then
1978  if (present(defaultval)) then; getfloats = defaultval; else; call io_error(140,ext_msg=key); endif
1979  endif
1980  if (present(requiredsize)) then
1981  if(requiredsize /= size(getfloats)) call io_error(146,ext_msg=key)
1982  endif
1983 
1984 end function getfloats
1985 
1986 
1987 !--------------------------------------------------------------------------------------------------
1991 !--------------------------------------------------------------------------------------------------
1992 function getints(this,key,defaultVal,requiredSize)
1994  integer, dimension(:), allocatable :: getints
1995  class(tpartitionedstringlist), target, intent(in) :: this
1996  character(len=*), intent(in) :: key
1997  integer, dimension(:), intent(in), optional :: defaultval
1998  integer, intent(in), optional :: requiredsize
1999  type(tpartitionedstringlist), pointer :: item
2000  integer :: i
2001  logical :: found, &
2002  cumulative
2003 
2004  cumulative = (key(1:1) == '(' .and. key(len_trim(key):len_trim(key)) == ')')
2005  found = .false.
2006 
2007  allocate(getints(0))
2008 
2009  item => this
2010  do while (associated(item%next))
2011  if (trim(io_stringvalue(item%string%val,item%string%pos,1)) == trim(key)) then
2012  found = .true.
2013  if (.not. cumulative) getints = [integer::]
2014  if (item%string%pos(1) < 2) call io_error(143,ext_msg=key)
2015  do i = 2, item%string%pos(1)
2016  getints = [getints,io_intvalue(item%string%val,item%string%pos,i)]
2017  enddo
2018  endif
2019  item => item%next
2020  enddo
2021 
2022  if (.not. found) then
2023  if (present(defaultval)) then; getints = defaultval; else; call io_error(140,ext_msg=key); endif
2024  endif
2025  if (present(requiredsize)) then
2026  if(requiredsize /= size(getints)) call io_error(146,ext_msg=key)
2027  endif
2028 
2029 end function getints
2030 
2031 
2032 !--------------------------------------------------------------------------------------------------
2037 !--------------------------------------------------------------------------------------------------
2038 function getstrings(this,key,defaultVal,raw)
2040  character(len=pStringLen),dimension(:), allocatable :: getstrings
2041  class(tpartitionedstringlist),target, intent(in) :: this
2042  character(len=*), intent(in) :: key
2043  character(len=*), dimension(:), intent(in), optional :: defaultval
2044  logical, intent(in), optional :: raw
2045  type(tpartitionedstringlist), pointer :: item
2046  character(len=pStringLen) :: str
2047  integer :: i
2048  logical :: found, &
2049  whole, &
2050  cumulative
2051 
2052  cumulative = (key(1:1) == '(' .and. key(len_trim(key):len_trim(key)) == ')')
2053  if (present(raw)) then
2054  whole = raw
2055  else
2056  whole = .false.
2057  endif
2058  found = .false.
2059 
2060  item => this
2061  do while (associated(item%next))
2062  if (trim(io_stringvalue(item%string%val,item%string%pos,1)) == trim(key)) then
2063  found = .true.
2064  if (allocated(getstrings) .and. .not. cumulative) deallocate(getstrings)
2065  if (item%string%pos(1) < 2) call io_error(143,ext_msg=key)
2066 
2067  notallocated: if (.not. allocated(getstrings)) then
2068  if (whole) then
2069  str = item%string%val(item%string%pos(4):)
2070  getstrings = [str]
2071  else
2072  str = io_stringvalue(item%string%val,item%string%pos,2)
2073  allocate(getstrings(1),source=str)
2074  do i=3,item%string%pos(1)
2075  str = io_stringvalue(item%string%val,item%string%pos,i)
2076  getstrings = [getstrings,str]
2077  enddo
2078  endif
2079  else notallocated
2080  if (whole) then
2081  str = item%string%val(item%string%pos(4):)
2082  getstrings = [getstrings,str]
2083  else
2084  do i=2,item%string%pos(1)
2085  str = io_stringvalue(item%string%val,item%string%pos,i)
2086  getstrings = [getstrings,str]
2087  enddo
2088  endif
2089  endif notallocated
2090  endif
2091  item => item%next
2092  enddo
2093 
2094  if (.not. found) then
2095  if (present(defaultval)) then
2096  if (len(defaultval) > len(getstrings)) call io_error(0,ext_msg='getStrings')
2097  getstrings = defaultval
2098  else
2099  call io_error(140,ext_msg=key)
2100  endif
2101  endif
2102 
2103 end function getstrings
2104 
2105 
2106 end module list
2107 # 10 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
2108 
2109 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/future.f90" 1
2110 !--------------------------------------------------------------------------------------------------
2113 !--------------------------------------------------------------------------------------------------
2114 module future
2115  use prec
2116 
2117  implicit none
2118  public
2119 
2120 contains
2121 
2122 
2123 !--------------------------------------------------------------------------------------------------
2125 !--------------------------------------------------------------------------------------------------
2126 function findloc(a,v)
2128  integer, intent(in), dimension(:) :: a
2129  integer, intent(in) :: v
2130  integer :: i,j
2131  integer, allocatable, dimension(:) :: findloc
2132 
2133  allocate(findloc(count(a==v)))
2134  j = 1
2135  do i = 1, size(a)
2136  if (a(i)==v) then
2137  findloc(j) = i
2138  j = j + 1
2139  endif
2140  enddo
2141 end function findloc
2142 
2143 
2144 end module future
2145 # 11 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
2146 
2147 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/config.f90" 1
2148 !--------------------------------------------------------------------------------------------------
2155 !--------------------------------------------------------------------------------------------------
2156 module config
2157  use prec
2158  use damask_interface
2159  use io
2160  use debug
2161  use list
2162 
2163  implicit none
2164  private
2165 
2166  type(tpartitionedstringlist), public, protected, allocatable, dimension(:) :: &
2167  config_phase, &
2170  config_texture, &
2172 
2173  type(tpartitionedstringlist), public, protected :: &
2174  config_numerics, &
2175  config_debug
2176 
2177  character(len=pStringLen), public, protected, allocatable, dimension(:) :: &
2178  config_name_phase, & !< name of each phase
2179  config_name_homogenization, & !< name of each homogenization
2180  config_name_crystallite, & !< name of each crystallite setting
2181  config_name_microstructure, & !< name of each microstructure
2183 
2184  public :: &
2185  config_init, &
2187 
2188 contains
2189 
2190 !--------------------------------------------------------------------------------------------------
2192 !--------------------------------------------------------------------------------------------------
2193 subroutine config_init
2195  integer :: i
2196  logical :: verbose
2197 
2198  character(len=pStringLen) :: &
2199  line, &
2200  part
2201  character(len=pStringLen), dimension(:), allocatable :: filecontent
2202  logical :: fileexists
2203 
2204  write(6,'(/,a)') ' <<<+- config init -+>>>'; flush(6)
2205 
2206  verbose = iand(debug_level(debug_material),debug_levelbasic) /= 0
2207 
2208  inquire(file=trim(getsolverjobname())//'.materialConfig',exist=fileexists)
2209  if(fileexists) then
2210  write(6,'(/,a)') ' reading '//trim(getsolverjobname())//'.materialConfig'; flush(6)
2211  filecontent = read_materialconfig(trim(getsolverjobname())//'.materialConfig')
2212  else
2213  inquire(file='material.config',exist=fileexists)
2214  if(.not. fileexists) call io_error(100,ext_msg='material.config')
2215  write(6,'(/,a)') ' reading material.config'; flush(6)
2216  filecontent = read_materialconfig('material.config')
2217  endif
2218 
2219  do i = 1, size(filecontent)
2220  line = trim(filecontent(i))
2221  part = io_lc(io_gettag(line,'<','>'))
2222  select case (trim(part))
2223 
2224  case (trim('phase'))
2225  call parse_materialconfig(config_name_phase,config_phase,line,filecontent(i+1:))
2226  if (verbose) write(6,'(a)') ' Phase parsed'; flush(6)
2227 
2228  case (trim('microstructure'))
2230  if (verbose) write(6,'(a)') ' Microstructure parsed'; flush(6)
2231 
2232  case (trim('crystallite'))
2234  if (verbose) write(6,'(a)') ' Crystallite parsed'; flush(6)
2235  deallocate(config_crystallite)
2236 
2237  case (trim('homogenization'))
2239  if (verbose) write(6,'(a)') ' Homogenization parsed'; flush(6)
2240 
2241  case (trim('texture'))
2242  call parse_materialconfig(config_name_texture,config_texture,line,filecontent(i+1:))
2243  if (verbose) write(6,'(a)') ' Texture parsed'; flush(6)
2244 
2245  end select
2246 
2247  enddo
2248 
2249  if (.not. allocated(config_homogenization) .or. size(config_homogenization) < 1) &
2250  call io_error(160,ext_msg='<homogenization>')
2251  if (.not. allocated(config_microstructure) .or. size(config_microstructure) < 1) &
2252  call io_error(160,ext_msg='<microstructure>')
2253  if (.not. allocated(config_phase) .or. size(config_phase) < 1) &
2254  call io_error(160,ext_msg='<phase>')
2255  if (.not. allocated(config_texture) .or. size(config_texture) < 1) &
2256  call io_error(160,ext_msg='<texture>')
2257 
2258 
2259  inquire(file='numerics.config', exist=fileexists)
2260  if (fileexists) then
2261  write(6,'(/,a)') ' reading numerics.config'; flush(6)
2262  filecontent = io_read_ascii('numerics.config')
2264  endif
2265 
2266  inquire(file='debug.config', exist=fileexists)
2267  if (fileexists) then
2268  write(6,'(/,a)') ' reading debug.config'; flush(6)
2269  filecontent = io_read_ascii('debug.config')
2270  call parse_debugandnumericsconfig(config_debug,filecontent)
2271  endif
2272 
2273 contains
2274 
2275 
2276 !--------------------------------------------------------------------------------------------------
2279 !--------------------------------------------------------------------------------------------------
2280 recursive function read_materialconfig(fileName,cnt) result(fileContent)
2282  character(len=*), intent(in) :: filename
2283  integer, intent(in), optional :: cnt
2284  character(len=pStringLen), dimension(:), allocatable :: filecontent
2285  character(len=pStringLen), dimension(:), allocatable :: includedcontent
2286  character(len=pStringLen) :: line
2287  character(len=pStringLen), parameter :: dummy = 'https://damask2.mpie.de'
2288  character(len=:), allocatable :: rawdata
2289  integer :: &
2290  filelength, &
2291  fileunit, &
2292  startpos, endpos, &
2293  mytotallines, & !< # lines read from file without include statements
2294  l,i, &
2295  mystat
2296  logical :: warned
2297 
2298  if (present(cnt)) then
2299  if (cnt>10) call io_error(106,ext_msg=trim(filename))
2300  endif
2301 
2302 !--------------------------------------------------------------------------------------------------
2303 ! read data as stream
2304  inquire(file = filename, size=filelength)
2305  if (filelength == 0) then
2306  allocate(filecontent(0))
2307  return
2308  endif
2309  open(newunit=fileunit, file=filename, access='stream',&
2310  status='old', position='rewind', action='read',iostat=mystat)
2311  if(mystat /= 0) call io_error(100,ext_msg=trim(filename))
2312  allocate(character(len=fileLength)::rawdata)
2313  read(fileunit) rawdata
2314  close(fileunit)
2315 
2316 !--------------------------------------------------------------------------------------------------
2317 ! count lines to allocate string array
2318  mytotallines = 1
2319  do l=1, len(rawdata)
2320  if (rawdata(l:l) == io_eol) mytotallines = mytotallines+1
2321  enddo
2322  allocate(filecontent(mytotallines))
2323 
2324 !--------------------------------------------------------------------------------------------------
2325 ! split raw data at end of line and handle includes
2326  warned = .false.
2327  startpos = 1
2328  l = 1
2329  do while (l <= mytotallines)
2330  endpos = merge(startpos + scan(rawdata(startpos:),io_eol) - 2,len(rawdata),l /= mytotallines)
2331  if (endpos - startpos > pstringlen -1) then
2332  line = rawdata(startpos:startpos+pstringlen-1)
2333  if (.not. warned) then
2334  call io_warning(207,ext_msg=trim(filename),el=l)
2335  warned = .true.
2336  endif
2337  else
2338  line = rawdata(startpos:endpos)
2339  endif
2340  startpos = endpos + 2 ! jump to next line start
2341 
2342  recursion: if (scan(trim(adjustl(line)),'{') == 1 .and. scan(trim(line),'}') > 2) then
2343  includedcontent = read_materialconfig(trim(line(scan(line,'{')+1:scan(line,'}')-1)), &
2344  merge(cnt,1,present(cnt))) ! to track recursion depth
2345  filecontent = [ filecontent(1:l-1), includedcontent, [(dummy,i=1,mytotallines-l)] ] ! add content and grow array
2346  mytotallines = mytotallines - 1 + size(includedcontent)
2347  l = l - 1 + size(includedcontent)
2348  else recursion
2349  filecontent(l) = line
2350  l = l + 1
2351  endif recursion
2352 
2353  enddo
2354 
2355 end function read_materialconfig
2356 
2357 
2358 !--------------------------------------------------------------------------------------------------
2360 !--------------------------------------------------------------------------------------------------
2361 subroutine parse_materialconfig(sectionNames,part,line, &
2362  fileContent)
2364  character(len=pStringLen), allocatable, dimension(:), intent(out) :: sectionNames
2365  type(tpartitionedstringlist), allocatable, dimension(:), intent(inout) :: part
2366  character(len=pStringLen), intent(inout) :: line
2367  character(len=pStringLen), dimension(:), intent(in) :: fileContent
2368 
2369  integer, allocatable, dimension(:) :: partPosition
2370  integer :: i, j
2371  logical :: echo
2372  character(len=pStringLen) :: sectionName
2373 
2374  echo = .false.
2375 
2376  if (allocated(part)) call io_error(161,ext_msg=trim(line))
2377  allocate(partposition(0))
2378 
2379  do i = 1, size(filecontent)
2380  line = trim(filecontent(i))
2381  if (io_gettag(line,'<','>') /= '') exit
2382  nextsection: if (io_gettag(line,'[',']') /= '') then
2383  partposition = [partposition, i]
2384  cycle
2385  endif nextsection
2386  if (size(partposition) < 1) &
2387  echo = (trim(io_gettag(line,'/','/')) == 'echo') .or. echo
2388  enddo
2389 
2390  allocate(sectionnames(size(partposition)))
2391  allocate(part(size(partposition)))
2392 
2393  partposition = [partposition, i] ! needed when actually storing content
2394 
2395  do i = 1, size(partposition) -1
2396  write(sectionname,'(i0,a,a)') i,'_',trim(io_gettag(filecontent(partposition(i)),'[',']'))
2397  sectionnames(i) = sectionname
2398  do j = partposition(i) + 1, partposition(i+1) -1
2399  call part(i)%add(trim(adjustl(filecontent(j))))
2400  enddo
2401  if (echo) then
2402  write(6,*) 'section',i, '"'//trim(sectionnames(i))//'"'
2403  call part(i)%show()
2404  endif
2405  enddo
2406 
2407 end subroutine parse_materialconfig
2408 
2409 
2410 !--------------------------------------------------------------------------------------------------
2412 !--------------------------------------------------------------------------------------------------
2413 subroutine parse_debugandnumericsconfig(config_list, &
2414  fileContent)
2416  type(tpartitionedstringlist), intent(out) :: config_list
2417  character(len=pStringLen), dimension(:), intent(in) :: fileContent
2418  integer :: i
2419 
2420  do i = 1, size(filecontent)
2421  call config_list%add(trim(adjustl(filecontent(i))))
2422  enddo
2423 
2424 end subroutine parse_debugandnumericsconfig
2425 
2426 end subroutine config_init
2427 
2428 
2429 !--------------------------------------------------------------------------------------------------
2431 !--------------------------------------------------------------------------------------------------
2432 subroutine config_deallocate(what)
2434  character(len=*), intent(in) :: what
2435 
2436  select case(trim(what))
2437 
2438  case('material.config/phase')
2439  deallocate(config_phase)
2440 
2441  case('material.config/microstructure')
2442  deallocate(config_microstructure)
2443 
2444  case('material.config/homogenization')
2445  deallocate(config_homogenization)
2446 
2447  case('material.config/texture')
2448  deallocate(config_texture)
2449 
2450  case('debug.config')
2451  call config_debug%free
2452 
2453  case('numerics.config')
2454  call config_numerics%free
2455 
2456  case default
2457  call io_error(0,ext_msg='config_deallocate')
2458 
2459  end select
2460 
2461 end subroutine config_deallocate
2462 
2463 end module config
2464 # 12 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
2465 
2466 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/math.f90" 1
2467 !--------------------------------------------------------------------------------------------------
2473 !--------------------------------------------------------------------------------------------------
2474 module math
2475  use prec
2476  use io
2477  use numerics
2478 
2479  implicit none
2480  public
2481 
2482 
2483 
2484 
2485 
2486 
2487 
2488 
2489  real(preal), parameter :: pi = acos(-1.0_preal)
2490  real(preal), parameter :: indeg = 180.0_preal/pi
2491  real(preal), parameter :: inrad = pi/180.0_preal
2492  complex(pReal), parameter :: twopiimg = cmplx(0.0_preal,2.0_preal*pi)
2493 
2494  real(preal), dimension(3,3), parameter :: &
2495  math_i3 = reshape([&
2496  1.0_preal,0.0_preal,0.0_preal, &
2497  0.0_preal,1.0_preal,0.0_preal, &
2498  0.0_preal,0.0_preal,1.0_preal &
2499  ],[3,3])
2500 
2501  real(preal), dimension(6), parameter, private :: &
2502  nrmmandel = [&
2503  1.0_preal, 1.0_preal, 1.0_preal, &
2504  sqrt(2.0_preal), sqrt(2.0_preal), sqrt(2.0_preal) ]
2505 
2506  real(preal), dimension(6), parameter, private :: &
2507  invnrmmandel = 1.0_preal/nrmmandel
2508 
2509  integer, dimension (2,6), parameter, private :: &
2510  mapnye = reshape([&
2511  1,1, &
2512  2,2, &
2513  3,3, &
2514  1,2, &
2515  2,3, &
2516  1,3 &
2517  ],[2,6])
2518 
2519  integer, dimension (2,6), parameter, private :: &
2520  mapvoigt = reshape([&
2521  1,1, &
2522  2,2, &
2523  3,3, &
2524  2,3, &
2525  1,3, &
2526  1,2 &
2527  ],[2,6])
2528 
2529  integer, dimension (2,9), parameter, private :: &
2530  mapplain = reshape([&
2531  1,1, &
2532  1,2, &
2533  1,3, &
2534  2,1, &
2535  2,2, &
2536  2,3, &
2537  3,1, &
2538  3,2, &
2539  3,3 &
2540  ],[2,9])
2541 
2542  interface math_eye
2543  module procedure math_identity2nd
2544  end interface math_eye
2545 
2546 
2547 !---------------------------------------------------------------------------------------------------
2548  private :: &
2549  unittest
2550 
2551 contains
2552 
2553 !--------------------------------------------------------------------------------------------------
2555 !--------------------------------------------------------------------------------------------------
2556 subroutine math_init
2558  real(pReal), dimension(4) :: randTest
2559  integer :: randSize
2560  integer, dimension(:), allocatable :: randInit
2561 
2562  write(6,'(/,a)') ' <<<+- math init -+>>>'; flush(6)
2563 
2564  call random_seed(size=randsize)
2565  allocate(randinit(randsize))
2566  if (randomseed > 0) then
2567  randinit = randomseed
2568  else
2569  call random_seed()
2570  call random_seed(get = randinit)
2571  randinit(2:randsize) = randinit(1)
2572  endif
2573 
2574  call random_seed(put = randinit)
2575  call random_number(randtest)
2576 
2577  write(6,'(a,i2)') ' size of random seed: ', randsize
2578  write(6,'(a,i0)') ' value of random seed: ', randinit(1)
2579  write(6,'(a,4(/,26x,f17.14),/)') ' start of random sequence: ', randtest
2580 
2581  call random_seed(put = randinit)
2582 
2583  call unittest
2584 
2585 end subroutine math_init
2586 
2587 
2588 !--------------------------------------------------------------------------------------------------
2590 ! Sorting is done with respect to array(sort,:) and keeps array(/=sort,:) linked to it.
2591 ! default: sort=1
2592 !--------------------------------------------------------------------------------------------------
2593 recursive subroutine math_sort(a, istart, iend, sortDim)
2595  integer, dimension(:,:), intent(inout) :: a
2596  integer, intent(in),optional :: istart,iend, sortdim
2597  integer :: ipivot,s,e,d
2598 
2599  if(present(istart)) then
2600  s = istart
2601  else
2602  s = lbound(a,2)
2603  endif
2604 
2605  if(present(iend)) then
2606  e = iend
2607  else
2608  e = ubound(a,2)
2609  endif
2610 
2611  if(present(sortdim)) then
2612  d = sortdim
2613  else
2614  d = 1
2615  endif
2616 
2617  if (s < e) then
2618  ipivot = qsort_partition(a,s, e, d)
2619  call math_sort(a, s, ipivot-1, d)
2620  call math_sort(a, ipivot+1, e, d)
2621  endif
2622 
2623 
2624  contains
2625 
2626  !-------------------------------------------------------------------------------------------------
2628  !-------------------------------------------------------------------------------------------------
2629  integer function qsort_partition(a, istart, iend, sort)
2631  integer, dimension(:,:), intent(inout) :: a
2632  integer, intent(in) :: istart,iend,sort
2633  integer, dimension(size(a,1)) :: tmp
2634  integer :: i,j
2635 
2636  do
2637  ! find the first element on the right side less than or equal to the pivot point
2638  do j = iend, istart, -1
2639  if (a(sort,j) <= a(sort,istart)) exit
2640  enddo
2641  ! find the first element on the left side greater than the pivot point
2642  do i = istart, iend
2643  if (a(sort,i) > a(sort,istart)) exit
2644  enddo
2645  cross: if (i >= j) then ! exchange left value with pivot and return with the partition index
2646  tmp = a(:,istart)
2647  a(:,istart) = a(:,j)
2648  a(:,j) = tmp
2649  qsort_partition = j
2650  return
2651  else cross ! exchange values
2652  tmp = a(:,i)
2653  a(:,i) = a(:,j)
2654  a(:,j) = tmp
2655  endif cross
2656  enddo
2657 
2658  end function qsort_partition
2659 
2660 end subroutine math_sort
2661 
2662 
2663 !--------------------------------------------------------------------------------------------------
2667 !--------------------------------------------------------------------------------------------------
2668 pure function math_expand(what,how)
2670  real(preal), dimension(:), intent(in) :: what
2671  integer, dimension(:), intent(in) :: how
2672  real(preal), dimension(sum(how)) :: math_expand
2673  integer :: i
2674 
2675  if (sum(how) == 0) return
2676 
2677  do i = 1, size(how)
2678  math_expand(sum(how(1:i-1))+1:sum(how(1:i))) = what(mod(i-1,size(what))+1)
2679  enddo
2680 
2681 end function math_expand
2682 
2683 
2684 !--------------------------------------------------------------------------------------------------
2686 !--------------------------------------------------------------------------------------------------
2687 pure function math_range(N)
2689  integer, intent(in) :: n
2690  integer :: i
2691  integer, dimension(N) :: math_range
2692 
2693  math_range = [(i,i=1,n)]
2694 
2695 end function math_range
2696 
2697 
2698 !--------------------------------------------------------------------------------------------------
2700 !--------------------------------------------------------------------------------------------------
2701 pure function math_identity2nd(d)
2703  integer, intent(in) :: d
2704  integer :: i
2705  real(preal), dimension(d,d) :: math_identity2nd
2706 
2707  math_identity2nd = 0.0_preal
2708  do i=1,d
2709  math_identity2nd(i,i) = 1.0_preal
2710  enddo
2711 
2712 end function math_identity2nd
2713 
2714 
2715 !--------------------------------------------------------------------------------------------------
2717 ! from http://en.wikipedia.org/wiki/Tensor_derivative_(continuum_mechanics)#Derivative_of_a_second-order_tensor_with_respect_to_itself
2718 !--------------------------------------------------------------------------------------------------
2719 pure function math_identity4th(d)
2721  integer, intent(in) :: d
2722  integer :: i,j,k,l
2723  real(preal), dimension(d,d,d,d) :: math_identity4th
2724  real(preal), dimension(d,d) :: identity2nd
2725 
2726  identity2nd = math_identity2nd(d)
2727  do i=1,d; do j=1,d; do k=1,d; do l=1,d
2728  math_identity4th(i,j,k,l) = 0.5_preal &
2729  *(identity2nd(i,k)*identity2nd(j,l)+identity2nd(i,l)*identity2nd(j,k))
2730  enddo; enddo; enddo; enddo
2731 
2732 end function math_identity4th
2733 
2734 
2735 !--------------------------------------------------------------------------------------------------
2737 ! e_ijk = 1 if even permutation of ijk
2738 ! e_ijk = -1 if odd permutation of ijk
2739 ! e_ijk = 0 otherwise
2740 !--------------------------------------------------------------------------------------------------
2741 real(preal) pure function math_levicivita(i,j,k)
2743  integer, intent(in) :: i,j,k
2744 
2745  if (all([i,j,k] == [1,2,3]) .or. all([i,j,k] == [2,3,1]) .or. all([i,j,k] == [3,1,2])) then
2746  math_levicivita = +1.0_preal
2747  elseif (all([i,j,k] == [3,2,1]) .or. all([i,j,k] == [2,1,3]) .or. all([i,j,k] == [1,3,2])) then
2748  math_levicivita = -1.0_preal
2749  else
2750  math_levicivita = 0.0_preal
2751  endif
2752 
2753 end function math_levicivita
2754 
2755 
2756 !--------------------------------------------------------------------------------------------------
2758 ! d_ij = 1 if i = j
2759 ! d_ij = 0 otherwise
2760 !--------------------------------------------------------------------------------------------------
2761 real(preal) pure function math_delta(i,j)
2763  integer, intent (in) :: i,j
2764 
2765  math_delta = merge(0.0_preal, 1.0_preal, i /= j)
2766 
2767 end function math_delta
2768 
2769 
2770 !--------------------------------------------------------------------------------------------------
2772 !--------------------------------------------------------------------------------------------------
2773 pure function math_cross(A,B)
2775  real(preal), dimension(3), intent(in) :: a,b
2776  real(preal), dimension(3) :: math_cross
2777 
2778  math_cross = [ a(2)*b(3) -a(3)*b(2), &
2779  a(3)*b(1) -a(1)*b(3), &
2780  a(1)*b(2) -a(2)*b(1) ]
2781 
2782 end function math_cross
2783 
2784 
2785 !--------------------------------------------------------------------------------------------------
2787 !--------------------------------------------------------------------------------------------------
2788 pure function math_outer(A,B)
2790  real(preal), dimension(:), intent(in) :: a,b
2791  real(preal), dimension(size(A,1),size(B,1)) :: math_outer
2792  integer :: i,j
2793 
2794  do i=1,size(a,1); do j=1,size(b,1)
2795  math_outer(i,j) = a(i)*b(j)
2796  enddo; enddo
2797 
2798 end function math_outer
2799 
2800 
2801 !--------------------------------------------------------------------------------------------------
2803 !--------------------------------------------------------------------------------------------------
2804 real(preal) pure function math_inner(a,b)
2806  real(preal), dimension(:), intent(in) :: a
2807  real(preal), dimension(size(A,1)), intent(in) :: b
2808 
2809  math_inner = sum(a*b)
2810 
2811 end function math_inner
2812 
2813 
2814 !--------------------------------------------------------------------------------------------------
2816 !--------------------------------------------------------------------------------------------------
2817 real(preal) pure function math_tensordot(a,b)
2819  real(preal), dimension(3,3), intent(in) :: a,b
2820 
2821  math_tensordot = sum(a*b)
2822 
2823 end function math_tensordot
2824 
2825 
2826 !--------------------------------------------------------------------------------------------------
2828 !--------------------------------------------------------------------------------------------------
2829 pure function math_mul3333xx33(A,B)
2831  real(preal), dimension(3,3,3,3), intent(in) :: a
2832  real(preal), dimension(3,3), intent(in) :: b
2833  real(preal), dimension(3,3) :: math_mul3333xx33
2834  integer :: i,j
2835 
2836  do i=1,3; do j=1,3
2837  math_mul3333xx33(i,j) = sum(a(i,j,1:3,1:3)*b(1:3,1:3))
2838  enddo; enddo
2839 
2840 end function math_mul3333xx33
2841 
2842 
2843 !--------------------------------------------------------------------------------------------------
2845 !--------------------------------------------------------------------------------------------------
2846 pure function math_mul3333xx3333(A,B)
2848  integer :: i,j,k,l
2849  real(preal), dimension(3,3,3,3), intent(in) :: a
2850  real(preal), dimension(3,3,3,3), intent(in) :: b
2851  real(preal), dimension(3,3,3,3) :: math_mul3333xx3333
2852 
2853  do i=1,3; do j=1,3; do k=1,3; do l=1,3
2854  math_mul3333xx3333(i,j,k,l) = sum(a(i,j,1:3,1:3)*b(1:3,1:3,k,l))
2855  enddo; enddo; enddo; enddo
2856 
2857 end function math_mul3333xx3333
2858 
2859 
2860 !--------------------------------------------------------------------------------------------------
2862 !--------------------------------------------------------------------------------------------------
2863 pure function math_exp33(A,n)
2865  real(preal), dimension(3,3), intent(in) :: a
2866  integer, intent(in), optional :: n
2867  real(preal), dimension(3,3) :: b, math_exp33
2868 
2869  real(preal) :: invfac
2870  integer :: n_,i
2871 
2872  if (present(n)) then
2873  n_ = n
2874  else
2875  n_ = 5
2876  endif
2877 
2878  invfac = 1.0_preal ! 0!
2879  b = math_i3
2880  math_exp33 = math_i3 ! A^0 = I
2881 
2882  do i = 1, n_
2883  invfac = invfac/real(i,preal) ! invfac = 1/(i!)
2884  b = matmul(b,a)
2885  math_exp33 = math_exp33 + invfac*b ! exp = SUM (A^i)/(i!)
2886  enddo
2887 
2888 end function math_exp33
2889 
2890 
2891 !--------------------------------------------------------------------------------------------------
2894 ! if determinant is close to zero
2895 !--------------------------------------------------------------------------------------------------
2896 pure function math_inv33(A)
2898  real(preal), dimension(3,3), intent(in) :: a
2899  real(preal), dimension(3,3) :: math_inv33
2900 
2901  real(preal) :: deta
2902  logical :: error
2903 
2904  call math_invert33(math_inv33,deta,error,a)
2905  if(error) math_inv33 = 0.0_preal
2906 
2907 end function math_inv33
2908 
2909 
2910 !--------------------------------------------------------------------------------------------------
2913 ! Returns an error if not possible, i.e. if determinant is close to zero
2914 !--------------------------------------------------------------------------------------------------
2915 pure subroutine math_invert33(InvA, DetA, error, A)
2917  real(preal), dimension(3,3), intent(out) :: inva
2918  real(preal), intent(out) :: deta
2919  logical, intent(out) :: error
2920  real(preal), dimension(3,3), intent(in) :: a
2921 
2922  inva(1,1) = a(2,2) * a(3,3) - a(2,3) * a(3,2)
2923  inva(2,1) = -a(2,1) * a(3,3) + a(2,3) * a(3,1)
2924  inva(3,1) = a(2,1) * a(3,2) - a(2,2) * a(3,1)
2925 
2926  deta = a(1,1) * inva(1,1) + a(1,2) * inva(2,1) + a(1,3) * inva(3,1)
2927 
2928  if (deq0(deta)) then
2929  inva = 0.0_preal
2930  error = .true.
2931  else
2932  inva(1,2) = -a(1,2) * a(3,3) + a(1,3) * a(3,2)
2933  inva(2,2) = a(1,1) * a(3,3) - a(1,3) * a(3,1)
2934  inva(3,2) = -a(1,1) * a(3,2) + a(1,2) * a(3,1)
2935 
2936  inva(1,3) = a(1,2) * a(2,3) - a(1,3) * a(2,2)
2937  inva(2,3) = -a(1,1) * a(2,3) + a(1,3) * a(2,1)
2938  inva(3,3) = a(1,1) * a(2,2) - a(1,2) * a(2,1)
2939 
2940  inva = inva/deta
2941  error = .false.
2942  endif
2943 
2944 end subroutine math_invert33
2945 
2946 
2947 !--------------------------------------------------------------------------------------------------
2949 !--------------------------------------------------------------------------------------------------
2950 function math_invsym3333(A)
2952  real(preal),dimension(3,3,3,3) :: math_invsym3333
2953 
2954  real(preal),dimension(3,3,3,3),intent(in) :: a
2955 
2956  integer :: ierr
2957  integer, dimension(6) :: ipiv6
2958  real(preal), dimension(6,6) :: temp66
2959  real(preal), dimension(6*(64+2)) :: work
2960  logical :: error
2961  external :: &
2962  dgetrf, &
2963  dgetri
2964 
2965  temp66 = math_sym3333to66(a)
2966  call dgetrf(6,6,temp66,6,ipiv6,ierr)
2967  error = (ierr /= 0)
2968  call dgetri(6,temp66,6,ipiv6,work,size(work,1),ierr)
2969  error = error .or. (ierr /= 0)
2970  if (error) then
2971  call io_error(400, ext_msg = 'math_invSym3333')
2972  else
2974  endif
2975 
2976 end function math_invsym3333
2977 
2978 
2979 !--------------------------------------------------------------------------------------------------
2981 !--------------------------------------------------------------------------------------------------
2982 subroutine math_invert(InvA, error, A)
2984  real(pReal), dimension(:,:), intent(in) :: A
2985  real(pReal), dimension(size(A,1),size(A,1)), intent(out) :: invA
2986  logical, intent(out) :: error
2987 
2988  integer, dimension(size(A,1)) :: ipiv
2989  real(pReal), dimension(size(A,1)*(64+2)) :: work
2990  integer :: ierr
2991  external :: &
2992  dgetrf, &
2993  dgetri
2994 
2995  inva = a
2996  call dgetrf(size(a,1),size(a,1),inva,size(a,1),ipiv,ierr)
2997  error = (ierr /= 0)
2998  call dgetri(size(a,1),inva,size(a,1),ipiv,work,size(work,1),ierr)
2999  error = error .or. (ierr /= 0)
3000 
3001 end subroutine math_invert
3002 
3003 
3004 !--------------------------------------------------------------------------------------------------
3006 !--------------------------------------------------------------------------------------------------
3007 pure function math_symmetric33(m)
3009  real(preal), dimension(3,3) :: math_symmetric33
3010  real(preal), dimension(3,3), intent(in) :: m
3011 
3012  math_symmetric33 = 0.5_preal * (m + transpose(m))
3013 
3014 end function math_symmetric33
3015 
3016 
3017 !--------------------------------------------------------------------------------------------------
3019 !--------------------------------------------------------------------------------------------------
3020 pure function math_symmetric66(m)
3022  real(preal), dimension(6,6) :: math_symmetric66
3023  real(preal), dimension(6,6), intent(in) :: m
3024 
3025  math_symmetric66 = 0.5_preal * (m + transpose(m))
3026 
3027 end function math_symmetric66
3028 
3029 
3030 !--------------------------------------------------------------------------------------------------
3032 !--------------------------------------------------------------------------------------------------
3033 pure function math_skew33(m)
3035  real(preal), dimension(3,3) :: math_skew33
3036  real(preal), dimension(3,3), intent(in) :: m
3037 
3038  math_skew33 = m - math_symmetric33(m)
3039 
3040 end function math_skew33
3041 
3042 
3043 !--------------------------------------------------------------------------------------------------
3045 !--------------------------------------------------------------------------------------------------
3046 pure function math_spherical33(m)
3048  real(preal), dimension(3,3) :: math_spherical33
3049  real(preal), dimension(3,3), intent(in) :: m
3050 
3051  math_spherical33 = math_i3 * math_trace33(m)/3.0_preal
3052 
3053 end function math_spherical33
3054 
3055 
3056 !--------------------------------------------------------------------------------------------------
3058 !--------------------------------------------------------------------------------------------------
3059 pure function math_deviatoric33(m)
3061  real(preal), dimension(3,3) :: math_deviatoric33
3062  real(preal), dimension(3,3), intent(in) :: m
3063 
3065 
3066 end function math_deviatoric33
3067 
3068 
3069 !--------------------------------------------------------------------------------------------------
3071 !--------------------------------------------------------------------------------------------------
3072 real(preal) pure function math_trace33(m)
3074  real(preal), dimension(3,3), intent(in) :: m
3075 
3076  math_trace33 = m(1,1) + m(2,2) + m(3,3)
3077 
3078 end function math_trace33
3079 
3080 
3081 !--------------------------------------------------------------------------------------------------
3083 !--------------------------------------------------------------------------------------------------
3084 real(preal) pure function math_det33(m)
3086  real(preal), dimension(3,3), intent(in) :: m
3087 
3088  math_det33 = m(1,1)* (m(2,2)*m(3,3)-m(2,3)*m(3,2)) &
3089  - m(1,2)* (m(2,1)*m(3,3)-m(2,3)*m(3,1)) &
3090  + m(1,3)* (m(2,1)*m(3,2)-m(2,2)*m(3,1))
3091 
3092 end function math_det33
3093 
3094 
3095 !--------------------------------------------------------------------------------------------------
3097 !--------------------------------------------------------------------------------------------------
3098 real(preal) pure function math_detsym33(m)
3100  real(preal), dimension(3,3), intent(in) :: m
3101 
3102  math_detsym33 = -(m(1,1)*m(2,3)**2 + m(2,2)*m(1,3)**2 + m(3,3)*m(1,2)**2) &
3103  + m(1,1)*m(2,2)*m(3,3) + 2.0_preal * m(1,2)*m(1,3)*m(2,3)
3104 
3105 end function math_detsym33
3106 
3107 
3108 !--------------------------------------------------------------------------------------------------
3110 !--------------------------------------------------------------------------------------------------
3111 pure function math_33to9(m33)
3113  real(preal), dimension(9) :: math_33to9
3114  real(preal), dimension(3,3), intent(in) :: m33
3115 
3116  integer :: i
3117 
3118  do i = 1, 9
3119  math_33to9(i) = m33(mapplain(1,i),mapplain(2,i))
3120  enddo
3121 
3122 end function math_33to9
3123 
3124 
3125 !--------------------------------------------------------------------------------------------------
3127 !--------------------------------------------------------------------------------------------------
3128 pure function math_9to33(v9)
3130  real(preal), dimension(3,3) :: math_9to33
3131  real(preal), dimension(9), intent(in) :: v9
3132 
3133  integer :: i
3134 
3135  do i = 1, 9
3136  math_9to33(mapplain(1,i),mapplain(2,i)) = v9(i)
3137  enddo
3138 
3139 end function math_9to33
3140 
3141 
3142 !--------------------------------------------------------------------------------------------------
3145 ! components according to Mandel. Advisable for matrix operations.
3146 ! Unweighted conversion only changes order according to Nye
3147 !--------------------------------------------------------------------------------------------------
3148 pure function math_sym33to6(m33,weighted)
3150  real(preal), dimension(6) :: math_sym33to6
3151  real(preal), dimension(3,3), intent(in) :: m33
3152  logical, optional, intent(in) :: weighted
3153 
3154  real(preal), dimension(6) :: w
3155  integer :: i
3156 
3157  if(present(weighted)) then
3158  w = merge(nrmmandel,1.0_preal,weighted)
3159  else
3160  w = nrmmandel
3161  endif
3162 
3163  do i = 1, 6
3164  math_sym33to6(i) = w(i)*m33(mapnye(1,i),mapnye(2,i))
3165  enddo
3166 
3167 end function math_sym33to6
3168 
3169 
3170 !--------------------------------------------------------------------------------------------------
3173 ! components according to Mandel. Advisable for matrix operations.
3174 ! Unweighted conversion only changes order according to Nye
3175 !--------------------------------------------------------------------------------------------------
3176 pure function math_6tosym33(v6,weighted)
3178  real(preal), dimension(3,3) :: math_6tosym33
3179  real(preal), dimension(6), intent(in) :: v6
3180  logical, optional, intent(in) :: weighted
3181 
3182  real(preal), dimension(6) :: w
3183  integer :: i
3184 
3185  if(present(weighted)) then
3186  w = merge(invnrmmandel,1.0_preal,weighted)
3187  else
3188  w = invnrmmandel
3189  endif
3190 
3191  do i=1,6
3192  math_6tosym33(mapnye(1,i),mapnye(2,i)) = w(i)*v6(i)
3193  math_6tosym33(mapnye(2,i),mapnye(1,i)) = w(i)*v6(i)
3194  enddo
3195 
3196 end function math_6tosym33
3197 
3198 
3199 !--------------------------------------------------------------------------------------------------
3201 !--------------------------------------------------------------------------------------------------
3202 pure function math_3333to99(m3333)
3204  real(preal), dimension(9,9) :: math_3333to99
3205  real(preal), dimension(3,3,3,3), intent(in) :: m3333
3206 
3207  integer :: i,j
3208 
3209  do i=1,9; do j=1,9
3210  math_3333to99(i,j) = m3333(mapplain(1,i),mapplain(2,i),mapplain(1,j),mapplain(2,j))
3211  enddo; enddo
3212 
3213 end function math_3333to99
3214 
3215 
3216 !--------------------------------------------------------------------------------------------------
3218 !--------------------------------------------------------------------------------------------------
3219 pure function math_99to3333(m99)
3221  real(preal), dimension(3,3,3,3) :: math_99to3333
3222  real(preal), dimension(9,9), intent(in) :: m99
3223 
3224  integer :: i,j
3225 
3226  do i=1,9; do j=1,9
3227  math_99to3333(mapplain(1,i),mapplain(2,i),mapplain(1,j),mapplain(2,j)) = m99(i,j)
3228  enddo; enddo
3229 
3230 end function math_99to3333
3231 
3232 
3233 !--------------------------------------------------------------------------------------------------
3236 ! components according to Mandel. Advisable for matrix operations.
3237 ! Unweighted conversion only rearranges order according to Nye
3238 !--------------------------------------------------------------------------------------------------
3239 pure function math_sym3333to66(m3333,weighted)
3241  real(preal), dimension(6,6) :: math_sym3333to66
3242  real(preal), dimension(3,3,3,3), intent(in) :: m3333
3243  logical, optional, intent(in) :: weighted
3244 
3245  real(preal), dimension(6) :: w
3246  integer :: i,j
3247 
3248  if(present(weighted)) then
3249  w = merge(nrmmandel,1.0_preal,weighted)
3250  else
3251  w = nrmmandel
3252  endif
3253 
3254  do i=1,6; do j=1,6
3255  math_sym3333to66(i,j) = w(i)*w(j)*m3333(mapnye(1,i),mapnye(2,i),mapnye(1,j),mapnye(2,j))
3256  enddo; enddo
3257 
3258 end function math_sym3333to66
3259 
3260 
3261 !--------------------------------------------------------------------------------------------------
3264 ! components according to Mandel. Advisable for matrix operations.
3265 ! Unweighted conversion only rearranges order according to Nye
3266 !--------------------------------------------------------------------------------------------------
3267 pure function math_66tosym3333(m66,weighted)
3269  real(preal), dimension(3,3,3,3) :: math_66tosym3333
3270  real(preal), dimension(6,6), intent(in) :: m66
3271  logical, optional, intent(in) :: weighted
3272 
3273  real(preal), dimension(6) :: w
3274  integer :: i,j
3275 
3276  if(present(weighted)) then
3277  w = merge(invnrmmandel,1.0_preal,weighted)
3278  else
3279  w = invnrmmandel
3280  endif
3281 
3282  do i=1,6; do j=1,6
3283  math_66tosym3333(mapnye(1,i),mapnye(2,i),mapnye(1,j),mapnye(2,j)) = w(i)*w(j)*m66(i,j)
3284  math_66tosym3333(mapnye(2,i),mapnye(1,i),mapnye(1,j),mapnye(2,j)) = w(i)*w(j)*m66(i,j)
3285  math_66tosym3333(mapnye(1,i),mapnye(2,i),mapnye(2,j),mapnye(1,j)) = w(i)*w(j)*m66(i,j)
3286  math_66tosym3333(mapnye(2,i),mapnye(1,i),mapnye(2,j),mapnye(1,j)) = w(i)*w(j)*m66(i,j)
3287  enddo; enddo
3288 
3289 end function math_66tosym3333
3290 
3291 
3292 !--------------------------------------------------------------------------------------------------
3294 !--------------------------------------------------------------------------------------------------
3295 pure function math_voigt66to3333(m66)
3297  real(preal), dimension(3,3,3,3) :: math_voigt66to3333
3298  real(preal), dimension(6,6), intent(in) :: m66
3299  integer :: i,j
3300 
3301  do i=1,6; do j=1, 6
3302  math_voigt66to3333(mapvoigt(1,i),mapvoigt(2,i),mapvoigt(1,j),mapvoigt(2,j)) = m66(i,j)
3303  math_voigt66to3333(mapvoigt(2,i),mapvoigt(1,i),mapvoigt(1,j),mapvoigt(2,j)) = m66(i,j)
3304  math_voigt66to3333(mapvoigt(1,i),mapvoigt(2,i),mapvoigt(2,j),mapvoigt(1,j)) = m66(i,j)
3305  math_voigt66to3333(mapvoigt(2,i),mapvoigt(1,i),mapvoigt(2,j),mapvoigt(1,j)) = m66(i,j)
3306  enddo; enddo
3307 
3308 end function math_voigt66to3333
3309 
3310 
3311 !--------------------------------------------------------------------------------------------------
3313 !--------------------------------------------------------------------------------------------------
3314 real(pReal) function math_samplegaussvar(meanvalue, stddev, width)
3316  real(preal), intent(in) :: meanvalue, & !< meanvalue of gauss distribution
3317  stddev
3318  real(preal), intent(in), optional :: width
3319 
3320  real(preal), dimension(2) :: rnd ! random numbers
3321  real(preal) :: scatter, & ! normalized scatter around meanvalue
3322  width_
3323 
3324  if (abs(stddev) < tol_math_check) then
3325  math_samplegaussvar = meanvalue
3326  else
3327  if (present(width)) then
3328  width_ = width
3329  else
3330  width_ = 3.0_preal ! use +-3*sigma as default scatter
3331  endif
3332 
3333  do
3334  call random_number(rnd)
3335  scatter = width_ * (2.0_preal * rnd(1) - 1.0_preal)
3336  if (rnd(2) <= exp(-0.5_preal * scatter ** 2.0_preal)) exit ! test if scattered value is drawn
3337  enddo
3338 
3339  math_samplegaussvar = scatter * stddev
3340  endif
3341 
3342 end function math_samplegaussvar
3343 
3344 
3345 !--------------------------------------------------------------------------------------------------
3347 ! ToDo: has wrong oder of arguments
3348 !--------------------------------------------------------------------------------------------------
3349 subroutine math_eigh(m,w,v,error)
3351  real(pReal), dimension(:,:), intent(in) :: m
3352  real(pReal), dimension(size(m,1)), intent(out) :: w
3353  real(pReal), dimension(size(m,1),size(m,1)), intent(out) :: v
3354 
3355  logical, intent(out) :: error
3356  integer :: ierr
3357  real(pReal), dimension((64+2)*size(m,1)) :: work ! block size of 64 taken from http://www.netlib.org/lapack/double/dsyev.f
3358  external :: &
3359  dsyev
3360 
3361  v = m ! copy matrix to input (doubles as output) array
3362  call dsyev('V','U',size(m,1),v,size(m,1),w,work,size(work,1),ierr)
3363  error = (ierr /= 0)
3364 
3365 end subroutine math_eigh
3366 
3367 
3368 !--------------------------------------------------------------------------------------------------
3374 ! ToDo: has wrong oder of arguments
3375 !--------------------------------------------------------------------------------------------------
3376 subroutine math_eigh33(m,w,v)
3378  real(pReal), dimension(3,3),intent(in) :: m
3379  real(pReal), dimension(3), intent(out) :: w
3380  real(pReal), dimension(3,3),intent(out) :: v
3381 
3382  real(pReal) :: T, U, norm, threshold
3383  logical :: error
3384 
3385  w = math_eigvalsh33(m)
3386 
3387  v(1:3,2) = [ m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2), &
3388  m(1, 3) * m(1, 2) - m(2, 3) * m(1, 1), &
3389  m(1, 2)**2]
3390 
3391  t = maxval(abs(w))
3392  u = max(t, t**2)
3393  threshold = sqrt(5.68e-14_preal * u**2)
3394 
3395  v(1:3,1) = [ v(1,2) + m(1, 3) * w(1), &
3396  v(2,2) + m(2, 3) * w(1), &
3397  (m(1,1) - w(1)) * (m(2,2) - w(1)) - v(3,2)]
3398  norm = norm2(v(1:3, 1))
3399  fallback1: if(norm < threshold) then
3400  call math_eigh(m,w,v,error)
3401  else fallback1
3402  v(1:3,1) = v(1:3, 1) / norm
3403  v(1:3,2) = [ v(1,2) + m(1, 3) * w(2), &
3404  v(2,2) + m(2, 3) * w(2), &
3405  (m(1,1) - w(2)) * (m(2,2) - w(2)) - v(3,2)]
3406  norm = norm2(v(1:3, 2))
3407  fallback2: if(norm < threshold) then
3408  call math_eigh(m,w,v,error)
3409  else fallback2
3410  v(1:3,2) = v(1:3, 2) / norm
3411  v(1:3,3) = math_cross(v(1:3,1),v(1:3,2))
3412  endif fallback2
3413  endif fallback1
3414 
3415 end subroutine math_eigh33
3416 
3417 
3418 
3419 
3420 !--------------------------------------------------------------------------------------------------
3422 !--------------------------------------------------------------------------------------------------
3423 function math_rotationalpart(m)
3425  real(preal), intent(in), dimension(3,3) :: m
3426  real(preal), dimension(3,3) :: math_rotationalpart
3427  real(preal), dimension(3,3) :: u , uinv
3428 
3429  u = eigenvectorbasis(matmul(transpose(m),m))
3430  uinv = math_inv33(u)
3431 
3432  inversionfailed: if (all(deq0(uinv))) then
3434  call io_warning(650)
3435  else inversionfailed
3436  math_rotationalpart = matmul(m,uinv)
3437  endif inversionfailed
3438 
3439 contains
3440  !--------------------------------------------------------------------------------------------------
3442  !--------------------------------------------------------------------------------------------------
3443  pure function eigenvectorbasis(m)
3445  real(preal), dimension(3,3) :: eigenvectorbasis
3446  real(preal), dimension(3,3), intent(in) :: m
3447 
3448  real(preal), dimension(3) :: i, v
3449  real(preal) :: p, q, rho, phi
3450  real(preal), parameter :: tol=1.e-14_preal
3451  real(preal), dimension(3,3,3) :: n, eb
3452 
3453  i = math_invariantssym33(m)
3454 
3455  p = i(2)-i(1)**2.0_preal/3.0_preal
3456  q = -2.0_preal/27.0_preal*i(1)**3.0_preal+product(i(1:2))/3.0_preal-i(3)
3457 
3458  threesimilareigvals: if(all(abs([p,q]) < tol)) then
3459  v = i(1)/3.0_preal
3460  ! this is not really correct, but at least the basis is correct
3461  eb = 0.0_preal
3462  eb(1,1,1)=1.0_preal
3463  eb(2,2,2)=1.0_preal
3464  eb(3,3,3)=1.0_preal
3465  else threesimilareigvals
3466  rho=sqrt(-3.0_preal*p**3.0_preal)/9.0_preal
3467  phi=acos(math_clip(-q/rho*0.5_preal,-1.0_preal,1.0_preal))
3468  v = 2.0_preal*rho**(1.0_preal/3.0_preal)* [cos((phi )/3.0_preal), &
3469  cos((phi+2.0_preal*pi)/3.0_preal), &
3470  cos((phi+4.0_preal*pi)/3.0_preal) &
3471  ] + i(1)/3.0_preal
3472  n(1:3,1:3,1) = m-v(1)*math_i3
3473  n(1:3,1:3,2) = m-v(2)*math_i3
3474  n(1:3,1:3,3) = m-v(3)*math_i3
3475  twosimilareigvals: if(abs(v(1)-v(2)) < tol) then
3476  eb(1:3,1:3,3) = matmul(n(1:3,1:3,1),n(1:3,1:3,2))/((v(3)-v(1))*(v(3)-v(2)))
3477  eb(1:3,1:3,1) = math_i3-eb(1:3,1:3,3)
3478  eb(1:3,1:3,2) = 0.0_preal
3479  elseif (abs(v(2)-v(3)) < tol) then twosimilareigvals
3480  eb(1:3,1:3,1) = matmul(n(1:3,1:3,2),n(1:3,1:3,3))/((v(1)-v(2))*(v(1)-v(3)))
3481  eb(1:3,1:3,2) = math_i3-eb(1:3,1:3,1)
3482  eb(1:3,1:3,3) = 0.0_preal
3483  elseif (abs(v(3)-v(1)) < tol) then twosimilareigvals
3484  eb(1:3,1:3,2) = matmul(n(1:3,1:3,3),n(1:3,1:3,1))/((v(2)-v(3))*(v(2)-v(1)))
3485  eb(1:3,1:3,3) = math_i3-eb(1:3,1:3,2)
3486  eb(1:3,1:3,1) = 0.0_preal
3487  else twosimilareigvals
3488  eb(1:3,1:3,1) = matmul(n(1:3,1:3,2),n(1:3,1:3,3))/((v(1)-v(2))*(v(1)-v(3)))
3489  eb(1:3,1:3,2) = matmul(n(1:3,1:3,3),n(1:3,1:3,1))/((v(2)-v(3))*(v(2)-v(1)))
3490  eb(1:3,1:3,3) = matmul(n(1:3,1:3,1),n(1:3,1:3,2))/((v(3)-v(1))*(v(3)-v(2)))
3491  endif twosimilareigvals
3492  endif threesimilareigvals
3493 
3494  eigenvectorbasis = sqrt(v(1)) * eb(1:3,1:3,1) &
3495  + sqrt(v(2)) * eb(1:3,1:3,2) &
3496  + sqrt(v(3)) * eb(1:3,1:3,3)
3497 
3498  end function eigenvectorbasis
3499 
3500 end function math_rotationalpart
3501 
3502 
3503 !--------------------------------------------------------------------------------------------------
3505 ! will return NaN on error
3506 !--------------------------------------------------------------------------------------------------
3507 function math_eigvalsh(m)
3509  real(preal), dimension(:,:), intent(in) :: m
3510  real(preal), dimension(size(m,1)) :: math_eigvalsh
3511 
3512  real(preal), dimension(size(m,1),size(m,1)) :: m_
3513  integer :: ierr
3514  real(preal), dimension((64+2)*size(m,1)) :: work ! block size of 64 taken from http://www.netlib.org/lapack/double/dsyev.f
3515  external :: &
3516  dsyev
3517 
3518  m_= m ! copy matrix to input (will be destroyed)
3519  call dsyev('N','U',size(m,1),m_,size(m,1),math_eigvalsh,work,size(work,1),ierr)
3520  if (ierr /= 0) math_eigvalsh = ieee_value(1.0_preal,ieee_quiet_nan)
3521 
3522 end function math_eigvalsh
3523 
3524 
3525 !--------------------------------------------------------------------------------------------------
3531 !--------------------------------------------------------------------------------------------------
3532 function math_eigvalsh33(m)
3534  real(preal), intent(in), dimension(3,3) :: m
3535  real(preal), dimension(3) :: math_eigvalsh33,i
3536  real(preal) :: p, q, rho, phi
3537  real(preal), parameter :: tol=1.e-14_preal
3538 
3539  i = math_invariantssym33(m) ! invariants are coefficients in characteristic polynomial apart for the sign of c0 and c2 in http://arxiv.org/abs/physics/0610206
3540 
3541  p = i(2)-i(1)**2.0_preal/3.0_preal ! different from http://arxiv.org/abs/physics/0610206 (this formulation was in DAMASK)
3542  q = product(i(1:2))/3.0_preal &
3543  - 2.0_preal/27.0_preal*i(1)**3.0_preal &
3544  - i(3) ! different from http://arxiv.org/abs/physics/0610206 (this formulation was in DAMASK)
3545 
3546  if(all(abs([p,q]) < tol)) then
3548  else
3549  rho=sqrt(-3.0_preal*p**3.0_preal)/9.0_preal
3550  phi=acos(math_clip(-q/rho*0.5_preal,-1.0_preal,1.0_preal))
3551  math_eigvalsh33 = 2.0_preal*rho**(1.0_preal/3.0_preal)* &
3552  [cos(phi/3.0_preal), &
3553  cos((phi+2.0_preal*pi)/3.0_preal), &
3554  cos((phi+4.0_preal*pi)/3.0_preal) &
3555  ] &
3556  + i(1)/3.0_preal
3557  endif
3558 
3559 end function math_eigvalsh33
3560 
3561 
3562 !--------------------------------------------------------------------------------------------------
3564 !--------------------------------------------------------------------------------------------------
3565 pure function math_invariantssym33(m)
3567  real(preal), dimension(3,3), intent(in) :: m
3568  real(preal), dimension(3) :: math_invariantssym33
3569 
3571  math_invariantssym33(2) = m(1,1)*m(2,2) + m(1,1)*m(3,3) + m(2,2)*m(3,3) &
3572  -(m(1,2)**2 + m(1,3)**2 + m(2,3)**2)
3574 
3575 end function math_invariantssym33
3576 
3577 
3578 !--------------------------------------------------------------------------------------------------
3580 !--------------------------------------------------------------------------------------------------
3581 integer pure function math_factorial(n)
3583  integer, intent(in) :: n
3584 
3585  math_factorial = product(math_range(n))
3586 
3587 end function math_factorial
3588 
3589 
3590 !--------------------------------------------------------------------------------------------------
3592 !--------------------------------------------------------------------------------------------------
3593 integer pure function math_binomial(n,k)
3595  integer, intent(in) :: n, k
3596  integer :: i, k_, n_
3597 
3598  k_ = min(k,n-k)
3599  n_ = n
3600  math_binomial = merge(1,0,k_>-1) ! handling special cases k < 0 or k > n
3601  do i = 1, k_
3602  math_binomial = (math_binomial * n_)/i
3603  n_ = n_ -1
3604  enddo
3605 
3606 end function math_binomial
3607 
3608 
3609 !--------------------------------------------------------------------------------------------------
3611 !--------------------------------------------------------------------------------------------------
3612 integer pure function math_multinomial(alpha)
3614  integer, intent(in), dimension(:) :: alpha
3615  integer :: i
3616 
3617  math_multinomial = 1
3618  do i = 1, size(alpha)
3619  math_multinomial = math_multinomial*math_binomial(sum(alpha(1:i)),alpha(i))
3620  enddo
3621 
3622 end function math_multinomial
3623 
3624 
3625 !--------------------------------------------------------------------------------------------------
3627 !--------------------------------------------------------------------------------------------------
3628 real(preal) pure function math_voltetrahedron(v1,v2,v3,v4)
3630  real(preal), dimension (3), intent(in) :: v1,v2,v3,v4
3631  real(preal), dimension (3,3) :: m
3632 
3633  m(1:3,1) = v1-v2
3634  m(1:3,2) = v1-v3
3635  m(1:3,3) = v1-v4
3636 
3637  math_voltetrahedron = abs(math_det33(m))/6.0_preal
3638 
3639 end function math_voltetrahedron
3640 
3641 
3642 !--------------------------------------------------------------------------------------------------
3644 !--------------------------------------------------------------------------------------------------
3645 real(preal) pure function math_areatriangle(v1,v2,v3)
3647  real(preal), dimension (3), intent(in) :: v1,v2,v3
3648 
3649  math_areatriangle = 0.5_preal * norm2(math_cross(v1-v2,v1-v3))
3650 
3651 end function math_areatriangle
3652 
3653 
3654 !--------------------------------------------------------------------------------------------------
3656 ! Will return NaN if left > right
3657 !--------------------------------------------------------------------------------------------------
3658 real(preal) pure elemental function math_clip(a, left, right)
3660  real(preal), intent(in) :: a
3661  real(preal), intent(in), optional :: left, right
3662 
3663  math_clip = a
3664  if (present(left)) math_clip = max(left,math_clip)
3665  if (present(right)) math_clip = min(right,math_clip)
3666  if (present(left) .and. present(right)) &
3667  math_clip = merge(ieee_value(1.0_preal,ieee_quiet_nan),math_clip, left>right)
3668 
3669 end function math_clip
3670 
3671 
3672 !--------------------------------------------------------------------------------------------------
3674 !--------------------------------------------------------------------------------------------------
3675 subroutine unittest
3677  integer, dimension(2,4) :: &
3678  sort_in_ = reshape([+1,+5, +5,+6, -1,-1, +3,-2],[2,4])
3679  integer, dimension(2,4), parameter :: &
3680  sort_out_ = reshape([-1,-1, +1,+5, +5,+6, +3,-2],[2,4])
3681 
3682  integer, dimension(5) :: range_out_ = [1,2,3,4,5]
3683  integer, dimension(3) :: ijk
3684 
3685  real(preal) :: det
3686  real(preal), dimension(3) :: v3_1,v3_2,v3_3,v3_4
3687  real(preal), dimension(6) :: v6
3688  real(preal), dimension(9) :: v9
3689  real(preal), dimension(3,3) :: t33,t33_2
3690  real(preal), dimension(6,6) :: t66
3691  real(preal), dimension(9,9) :: t99,t99_2
3692  real(preal), dimension(:,:), &
3693  allocatable :: txx,txx_2
3694  real(preal) :: r
3695  integer :: d
3696  logical :: e
3697 
3698  if (any(abs([1.0_preal,2.0_preal,2.0_preal,3.0_preal,3.0_preal,3.0_preal] - &
3699  math_expand([1.0_preal,2.0_preal,3.0_preal],[1,2,3,0])) > tol_math_check)) &
3700  call io_error(0,ext_msg='math_expand [1,2,3] by [1,2,3,0] => [1,2,2,3,3,3]')
3701 
3702  if (any(abs([1.0_preal,2.0_preal,2.0_preal] - &
3703  math_expand([1.0_preal,2.0_preal,3.0_preal],[1,2])) > tol_math_check)) &
3704  call io_error(0,ext_msg='math_expand [1,2,3] by [1,2] => [1,2,2]')
3705 
3706  if (any(abs([1.0_preal,2.0_preal,2.0_preal,1.0_preal,1.0_preal,1.0_preal] - &
3707  math_expand([1.0_preal,2.0_preal],[1,2,3])) > tol_math_check)) &
3708  call io_error(0,ext_msg='math_expand [1,2] by [1,2,3] => [1,2,2,1,1,1]')
3709 
3710  call math_sort(sort_in_,1,3,2)
3711  if(any(sort_in_ /= sort_out_)) &
3712  call io_error(0,ext_msg='math_sort')
3713 
3714  if(any(math_range(5) /= range_out_)) &
3715  call io_error(0,ext_msg='math_range')
3716 
3717  if(any(dneq(math_exp33(math_i3,0),math_i3))) &
3718  call io_error(0,ext_msg='math_exp33(math_I3,1)')
3719  if(any(dneq(math_exp33(math_i3,256),exp(1.0_preal)*math_i3))) &
3720  call io_error(0,ext_msg='math_exp33(math_I3,256)')
3721 
3722  call random_number(v9)
3723  if(any(dneq(math_33to9(math_9to33(v9)),v9))) &
3724  call io_error(0,ext_msg='math_33to9/math_9to33')
3725 
3726  call random_number(t99)
3727  if(any(dneq(math_3333to99(math_99to3333(t99)),t99))) &
3728  call io_error(0,ext_msg='math_3333to99/math_99to3333')
3729 
3730  call random_number(v6)
3731  if(any(dneq(math_sym33to6(math_6tosym33(v6)),v6))) &
3732  call io_error(0,ext_msg='math_sym33to6/math_6toSym33')
3733 
3734  call random_number(t66)
3735  if(any(dneq(math_sym3333to66(math_66tosym3333(t66)),t66))) &
3736  call io_error(0,ext_msg='math_sym3333to66/math_66toSym3333')
3737 
3738  call random_number(v6)
3739  if(any(dneq0(math_6tosym33(v6) - math_symmetric33(math_6tosym33(v6))))) &
3740  call io_error(0,ext_msg='math_symmetric33')
3741 
3742  call random_number(v3_1)
3743  call random_number(v3_2)
3744  call random_number(v3_3)
3745  call random_number(v3_4)
3746 
3747  if(dneq(abs(dot_product(math_cross(v3_1-v3_4,v3_2-v3_4),v3_3-v3_4))/6.0, &
3748  math_voltetrahedron(v3_1,v3_2,v3_3,v3_4),tol=1.0e-12_preal)) &
3749  call io_error(0,ext_msg='math_volTetrahedron')
3750 
3751  call random_number(t33)
3752  if(dneq(math_det33(math_symmetric33(t33)),math_detsym33(math_symmetric33(t33)),tol=1.0e-12_preal)) &
3753  call io_error(0,ext_msg='math_det33/math_detSym33')
3754 
3755  if(any(dneq0(math_identity2nd(3),math_inv33(math_i3)))) &
3756  call io_error(0,ext_msg='math_inv33(math_I3)')
3757 
3758  do while(abs(math_det33(t33))<1.0e-9_preal)
3759  call random_number(t33)
3760  enddo
3761  if(any(dneq0(matmul(t33,math_inv33(t33)) - math_identity2nd(3),tol=1.0e-9_preal))) &
3762  call io_error(0,ext_msg='math_inv33')
3763 
3764  call math_invert33(t33_2,det,e,t33)
3765  if(any(dneq0(matmul(t33,t33_2) - math_identity2nd(3),tol=1.0e-9_preal)) .or. e) &
3766  call io_error(0,ext_msg='math_invert33: T:T^-1 != I')
3767  if(dneq(det,math_det33(t33),tol=1.0e-12_preal)) &
3768  call io_error(0,ext_msg='math_invert33 (determinant)')
3769 
3770  call math_invert(t33_2,e,t33)
3771  if(any(dneq0(matmul(t33,t33_2) - math_identity2nd(3),tol=1.0e-9_preal)) .or. e) &
3772  call io_error(0,ext_msg='math_invert t33')
3773 
3774  do while(math_det33(t33)<1.0e-2_preal) ! O(det(F)) = 1
3775  call random_number(t33)
3776  enddo
3777  t33_2 = math_rotationalpart(transpose(t33))
3778  t33 = math_rotationalpart(t33)
3779  if(any(dneq0(matmul(t33_2,t33) - math_i3,tol=1.0e-10_preal))) &
3780  call io_error(0,ext_msg='math_rotationalPart')
3781 
3782  call random_number(r)
3783  d = int(r*5.0_preal) + 1
3784  txx = math_identity2nd(d)
3785  allocate(txx_2(d,d))
3786  call math_invert(txx_2,e,txx)
3787  if(any(dneq0(txx_2,txx) .or. e)) &
3788  call io_error(0,ext_msg='math_invert(txx)/math_identity2nd')
3789 
3790  call math_invert(t99_2,e,t99) ! not sure how likely it is that we get a singular matrix
3791  if(any(dneq0(matmul(t99_2,t99)-math_identity2nd(9),tol=1.0e-9_preal)) .or. e) &
3792  call io_error(0,ext_msg='math_invert(t99)')
3793 
3794  if(any(dneq(math_clip([4.0_preal,9.0_preal],5.0_preal,6.5_preal),[5.0_preal,6.5_preal]))) &
3795  call io_error(0,ext_msg='math_clip')
3796 
3797  if(math_factorial(10) /= 3628800) &
3798  call io_error(0,ext_msg='math_factorial')
3799 
3800  if(math_binomial(49,6) /= 13983816) &
3801  call io_error(0,ext_msg='math_binomial')
3802 
3803  ijk = cshift([1,2,3],int(r*1.0e2_preal))
3804  if(dneq(math_levicivita(ijk(1),ijk(2),ijk(3)),+1.0_preal)) &
3805  call io_error(0,ext_msg='math_LeviCivita(even)')
3806  ijk = cshift([3,2,1],int(r*2.0e2_preal))
3807  if(dneq(math_levicivita(ijk(1),ijk(2),ijk(3)),-1.0_preal)) &
3808  call io_error(0,ext_msg='math_LeviCivita(odd)')
3809  ijk = cshift([2,2,1],int(r*2.0e2_preal))
3810  if(dneq0(math_levicivita(ijk(1),ijk(2),ijk(3))))&
3811  call io_error(0,ext_msg='math_LeviCivita')
3812 
3813 end subroutine unittest
3814 
3815 end module math
3816 # 13 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
3817 
3818 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/quaternions.f90" 1
3819 !---------------------------------------------------------------------------------------------------
3825 !---------------------------------------------------------------------------------------------------
3827  use prec
3828  use io
3829 
3830  implicit none
3831  private
3832 
3833  real(preal), parameter, public :: p = -1.0_preal
3834 
3835  type, public :: quaternion
3836  real(preal), private :: w = 0.0_preal
3837  real(preal), private :: x = 0.0_preal
3838  real(preal), private :: y = 0.0_preal
3839  real(preal), private :: z = 0.0_preal
3840 
3841 
3842  contains
3843  procedure, private :: add__
3844  procedure, private :: pos__
3845  generic, public :: operator(+) => add__,pos__
3846 
3847  procedure, private :: sub__
3848  procedure, private :: neg__
3849  generic, public :: operator(-) => sub__,neg__
3850 
3851  procedure, private :: mul_quat__
3852  procedure, private :: mul_scal__
3853  generic, public :: operator(*) => mul_quat__, mul_scal__
3854 
3855  procedure, private :: div_quat__
3856  procedure, private :: div_scal__
3857  generic, public :: operator(/) => div_quat__, div_scal__
3858 
3859  procedure, private :: eq__
3860  generic, public :: operator(==) => eq__
3861 
3862  procedure, private :: neq__
3863  generic, public :: operator(/=) => neq__
3864 
3865  procedure, private :: pow_quat__
3866  procedure, private :: pow_scal__
3867  generic, public :: operator(**) => pow_quat__, pow_scal__
3868 
3869  procedure, public :: abs => abs__
3870  procedure, public :: conjg => conjg__
3871  procedure, public :: real => real__
3872  procedure, public :: aimag => aimag__
3873 
3874  procedure, public :: homomorphed
3875  procedure, public :: asarray
3876  procedure, public :: inverse
3877 
3878  end type
3879 
3880  interface assignment (=)
3881  module procedure assign_quat__
3882  module procedure assign_vec__
3883  end interface assignment (=)
3884 
3885  interface quaternion
3886  module procedure init__
3887  end interface quaternion
3888 
3889  interface abs
3890  procedure abs__
3891  end interface abs
3892 
3893  interface dot_product
3894  procedure dot_product__
3895  end interface dot_product
3896 
3897  interface conjg
3898  module procedure conjg__
3899  end interface conjg
3900 
3901  interface exp
3902  module procedure exp__
3903  end interface exp
3904 
3905  interface log
3906  module procedure log__
3907  end interface log
3908 
3909  interface real
3910  module procedure real__
3911  end interface real
3912 
3913  interface aimag
3914  module procedure aimag__
3915  end interface aimag
3916 
3917  public :: &
3918  quaternions_init, &
3919  assignment(=), &
3920  conjg, aimag, &
3921  log, exp, &
3922  real
3923 
3924 contains
3925 
3926 
3927 !--------------------------------------------------------------------------------------------------
3929 !--------------------------------------------------------------------------------------------------
3930 subroutine quaternions_init
3932  write(6,'(/,a)') ' <<<+- quaternions init -+>>>'; flush(6)
3933  call unittest
3934 
3935 end subroutine quaternions_init
3936 
3937 
3938 !---------------------------------------------------------------------------------------------------
3940 !---------------------------------------------------------------------------------------------------
3941 type(quaternion) pure function init__(array)
3943  real(preal), intent(in), dimension(4) :: array
3944 
3945  init__%w = array(1)
3946  init__%x = array(2)
3947  init__%y = array(3)
3948  init__%z = array(4)
3949 
3950 end function init__
3951 
3952 
3953 !---------------------------------------------------------------------------------------------------
3955 !---------------------------------------------------------------------------------------------------
3956 elemental pure subroutine assign_quat__(self,other)
3958  type(quaternion), intent(out) :: self
3959  type(quaternion), intent(in) :: other
3960 
3961  self = [other%w,other%x,other%y,other%z]
3962 
3963 end subroutine assign_quat__
3964 
3965 
3966 !---------------------------------------------------------------------------------------------------
3968 !---------------------------------------------------------------------------------------------------
3969 pure subroutine assign_vec__(self,other)
3971  type(quaternion), intent(out) :: self
3972  real(preal), intent(in), dimension(4) :: other
3973 
3974  self%w = other(1)
3975  self%x = other(2)
3976  self%y = other(3)
3977  self%z = other(4)
3978 
3979 end subroutine assign_vec__
3980 
3981 
3982 !---------------------------------------------------------------------------------------------------
3984 !---------------------------------------------------------------------------------------------------
3985 type(quaternion) elemental pure function add__(self,other)
3987  class(quaternion), intent(in) :: self,other
3988 
3989  add__ = [ self%w, self%x, self%y ,self%z] &
3990  + [other%w, other%x, other%y,other%z]
3991 
3992 end function add__
3993 
3994 
3995 !---------------------------------------------------------------------------------------------------
3997 !---------------------------------------------------------------------------------------------------
3998 type(quaternion) elemental pure function pos__(self)
4000  class(quaternion), intent(in) :: self
4001 
4002  pos__ = self * (+1.0_preal)
4003 
4004 end function pos__
4005 
4006 
4007 !---------------------------------------------------------------------------------------------------
4009 !---------------------------------------------------------------------------------------------------
4010 type(quaternion) elemental pure function sub__(self,other)
4012  class(quaternion), intent(in) :: self,other
4013 
4014  sub__ = [ self%w, self%x, self%y ,self%z] &
4015  - [other%w, other%x, other%y,other%z]
4016 
4017 end function sub__
4018 
4019 
4020 !---------------------------------------------------------------------------------------------------
4022 !---------------------------------------------------------------------------------------------------
4023 type(quaternion) elemental pure function neg__(self)
4025  class(quaternion), intent(in) :: self
4026 
4027  neg__ = self * (-1.0_preal)
4028 
4029 end function neg__
4030 
4031 
4032 !---------------------------------------------------------------------------------------------------
4034 !---------------------------------------------------------------------------------------------------
4035 type(quaternion) elemental pure function mul_quat__(self,other)
4037  class(quaternion), intent(in) :: self, other
4038 
4039  mul_quat__%w = self%w*other%w - self%x*other%x - self%y*other%y - self%z*other%z
4040  mul_quat__%x = self%w*other%x + self%x*other%w + p * (self%y*other%z - self%z*other%y)
4041  mul_quat__%y = self%w*other%y + self%y*other%w + p * (self%z*other%x - self%x*other%z)
4042  mul_quat__%z = self%w*other%z + self%z*other%w + p * (self%x*other%y - self%y*other%x)
4043 
4044 end function mul_quat__
4045 
4046 
4047 !---------------------------------------------------------------------------------------------------
4049 !---------------------------------------------------------------------------------------------------
4050 type(quaternion) elemental pure function mul_scal__(self,scal)
4052  class(quaternion), intent(in) :: self
4053  real(preal), intent(in) :: scal
4054 
4055  mul_scal__ = [self%w,self%x,self%y,self%z]*scal
4056 
4057 end function mul_scal__
4058 
4059 
4060 !---------------------------------------------------------------------------------------------------
4062 !---------------------------------------------------------------------------------------------------
4063 type(quaternion) elemental pure function div_quat__(self,other)
4065  class(quaternion), intent(in) :: self, other
4066 
4067  div_quat__ = self * (conjg(other)/(abs(other)**2.0_preal))
4068 
4069 end function div_quat__
4070 
4071 
4072 !---------------------------------------------------------------------------------------------------
4074 !---------------------------------------------------------------------------------------------------
4075 type(quaternion) elemental pure function div_scal__(self,scal)
4077  class(quaternion), intent(in) :: self
4078  real(preal), intent(in) :: scal
4079 
4080  div_scal__ = [self%w,self%x,self%y,self%z]/scal
4081 
4082 end function div_scal__
4083 
4084 
4085 !---------------------------------------------------------------------------------------------------
4087 !---------------------------------------------------------------------------------------------------
4088 logical elemental pure function eq__(self,other)
4090  class(quaternion), intent(in) :: self,other
4091 
4092  eq__ = all(deq([ self%w, self%x, self%y, self%z], &
4093  [other%w,other%x,other%y,other%z]))
4094 
4095 end function eq__
4096 
4097 
4098 !---------------------------------------------------------------------------------------------------
4100 !---------------------------------------------------------------------------------------------------
4101 logical elemental pure function neq__(self,other)
4103  class(quaternion), intent(in) :: self,other
4104 
4105  neq__ = .not. self%eq__(other)
4106 
4107 end function neq__
4108 
4109 
4110 !---------------------------------------------------------------------------------------------------
4112 !---------------------------------------------------------------------------------------------------
4113 type(quaternion) elemental pure function pow_quat__(self,expon)
4115  class(quaternion), intent(in) :: self
4116  type(quaternion), intent(in) :: expon
4117 
4118  pow_quat__ = exp(log(self)*expon)
4119 
4120 end function pow_quat__
4121 
4122 
4123 !---------------------------------------------------------------------------------------------------
4125 !---------------------------------------------------------------------------------------------------
4126 type(quaternion) elemental pure function pow_scal__(self,expon)
4128  class(quaternion), intent(in) :: self
4129  real(preal), intent(in) :: expon
4130 
4131  pow_scal__ = exp(log(self)*expon)
4132 
4133 end function pow_scal__
4134 
4135 
4136 !---------------------------------------------------------------------------------------------------
4138 !---------------------------------------------------------------------------------------------------
4139 type(quaternion) elemental pure function exp__(a)
4141  class(quaternion), intent(in) :: a
4142  real(preal) :: absimag
4143 
4144  absimag = norm2(aimag(a))
4145 
4146  exp__ = merge(exp(a%w) * [ cos(absimag), &
4147  a%x/absimag * sin(absimag), &
4148  a%y/absimag * sin(absimag), &
4149  a%z/absimag * sin(absimag)], &
4150  ieee_value(1.0_preal,ieee_signaling_nan), &
4151  dneq0(absimag))
4152 
4153 end function exp__
4154 
4155 
4156 !---------------------------------------------------------------------------------------------------
4158 !---------------------------------------------------------------------------------------------------
4159 type(quaternion) elemental pure function log__(a)
4161  class(quaternion), intent(in) :: a
4162  real(preal) :: absimag
4163 
4164  absimag = norm2(aimag(a))
4165 
4166  log__ = merge([log(abs(a)), &
4167  a%x/absimag * acos(a%w/abs(a)), &
4168  a%y/absimag * acos(a%w/abs(a)), &
4169  a%z/absimag * acos(a%w/abs(a))], &
4170  ieee_value(1.0_preal,ieee_signaling_nan), &
4171  dneq0(absimag))
4172 
4173 end function log__
4174 
4175 
4176 !---------------------------------------------------------------------------------------------------
4178 !---------------------------------------------------------------------------------------------------
4179 real(preal) elemental pure function abs__(self)
4181  class(quaternion), intent(in) :: self
4182 
4183  abs__ = norm2([self%w,self%x,self%y,self%z])
4184 
4185 end function abs__
4186 
4187 
4188 !---------------------------------------------------------------------------------------------------
4190 !---------------------------------------------------------------------------------------------------
4191 real(preal) elemental pure function dot_product__(a,b)
4193  class(quaternion), intent(in) :: a,b
4194 
4195  dot_product__ = a%w*b%w + a%x*b%x + a%y*b%y + a%z*b%z
4196 
4197 end function dot_product__
4198 
4199 
4200 !---------------------------------------------------------------------------------------------------
4202 !---------------------------------------------------------------------------------------------------
4203 type(quaternion) elemental pure function conjg__(self)
4205  class(quaternion), intent(in) :: self
4206 
4207  conjg__ = [self%w,-self%x,-self%y,-self%z]
4208 
4209 end function conjg__
4210 
4211 
4212 !---------------------------------------------------------------------------------------------------
4214 !---------------------------------------------------------------------------------------------------
4215 type(quaternion) elemental pure function homomorphed(self)
4217  class(quaternion), intent(in) :: self
4218 
4219  homomorphed = - self
4220 
4221 end function homomorphed
4222 
4223 
4224 !---------------------------------------------------------------------------------------------------
4226 !---------------------------------------------------------------------------------------------------
4227 pure function asarray(self)
4229  real(preal), dimension(4) :: asarray
4230  class(quaternion), intent(in) :: self
4231 
4232  asarray = [self%w,self%x,self%y,self%z]
4233 
4234 end function asarray
4235 
4236 
4237 !---------------------------------------------------------------------------------------------------
4239 !---------------------------------------------------------------------------------------------------
4240 pure function real__(self)
4242  real(preal) :: real__
4243  class(quaternion), intent(in) :: self
4244 
4245  real__ = self%w
4246 
4247 end function real__
4248 
4249 
4250 !---------------------------------------------------------------------------------------------------
4252 !---------------------------------------------------------------------------------------------------
4253 pure function aimag__(self)
4255  real(preal), dimension(3) :: aimag__
4256  class(quaternion), intent(in) :: self
4257 
4258  aimag__ = [self%x,self%y,self%z]
4259 
4260 end function aimag__
4261 
4262 
4263 !---------------------------------------------------------------------------------------------------
4265 !---------------------------------------------------------------------------------------------------
4266 type(quaternion) elemental pure function inverse(self)
4268  class(quaternion), intent(in) :: self
4269 
4270  inverse = conjg(self)/abs(self)**2.0_preal
4271 
4272 end function inverse
4273 
4274 
4275 !--------------------------------------------------------------------------------------------------
4277 !--------------------------------------------------------------------------------------------------
4278 subroutine unittest
4280  real(pReal), dimension(4) :: qu
4281  type(quaternion) :: q, q_2
4282 
4283  call random_number(qu)
4284  qu = (qu-0.5_preal) * 2.0_preal
4285  q = quaternion(qu)
4286 
4287  q_2= qu
4288  if(any(dneq(q%asArray(),q_2%asArray()))) call io_error(0,ext_msg='assign_vec__')
4289 
4290  q_2 = q + q
4291  if(any(dneq(q_2%asArray(),2.0_preal*qu))) call io_error(0,ext_msg='add__')
4292 
4293  q_2 = q - q
4294  if(any(dneq0(q_2%asArray()))) call io_error(0,ext_msg='sub__')
4295 
4296  q_2 = q * 5.0_preal
4297  if(any(dneq(q_2%asArray(),5.0_preal*qu))) call io_error(0,ext_msg='mul__')
4298 
4299  q_2 = q / 0.5_preal
4300  if(any(dneq(q_2%asArray(),2.0_preal*qu))) call io_error(0,ext_msg='div__')
4301 
4302  q_2 = q * 0.3_preal
4303  if(dneq0(abs(q)) .and. q_2 == q) call io_error(0,ext_msg='eq__')
4304 
4305  q_2 = q
4306  if(q_2 /= q) call io_error(0,ext_msg='neq__')
4307 
4308  if(dneq(abs(q),norm2(qu))) call io_error(0,ext_msg='abs__')
4309  if(dneq(abs(q)**2.0_preal, real(q*q%conjg()),1.0e-14_preal)) &
4310  call io_error(0,ext_msg='abs__/*conjg')
4311 
4312  if(any(dneq(q%asArray(),qu))) call io_error(0,ext_msg='eq__')
4313  if(dneq(q%real(), qu(1))) call io_error(0,ext_msg='real()')
4314  if(any(dneq(q%aimag(), qu(2:4)))) call io_error(0,ext_msg='aimag()')
4315 
4316  q_2 = q%homomorphed()
4317  if(q /= q_2* (-1.0_preal)) call io_error(0,ext_msg='homomorphed')
4318  if(dneq(q_2%real(), qu(1)* (-1.0_preal))) call io_error(0,ext_msg='homomorphed/real')
4319  if(any(dneq(q_2%aimag(),qu(2:4)*(-1.0_preal)))) call io_error(0,ext_msg='homomorphed/aimag')
4320 
4321  q_2 = conjg(q)
4322  if(dneq(abs(q),abs(q_2))) call io_error(0,ext_msg='conjg/abs')
4323  if(q /= conjg(q_2)) call io_error(0,ext_msg='conjg/involution')
4324  if(dneq(q_2%real(), q%real())) call io_error(0,ext_msg='conjg/real')
4325  if(any(dneq(q_2%aimag(),q%aimag()*(-1.0_preal)))) call io_error(0,ext_msg='conjg/aimag')
4326 
4327  if(abs(q) > 0.0_preal) then
4328  q_2 = q * q%inverse()
4329  if( dneq(real(q_2), 1.0_preal,1.0e-15_preal)) call io_error(0,ext_msg='inverse/real')
4330  if(any(dneq0(aimag(q_2), 1.0e-15_preal))) call io_error(0,ext_msg='inverse/aimag')
4331 
4332  q_2 = q/abs(q)
4333  q_2 = conjg(q_2) - inverse(q_2)
4334  if(any(dneq0(q_2%asArray(),1.0e-15_preal))) call io_error(0,ext_msg='inverse/conjg')
4335  endif
4336  if(dneq(dot_product(qu,qu),dot_product(q,q))) call io_error(0,ext_msg='dot_product')
4337 
4338 
4339 
4340 
4341 
4342 
4343 
4344 
4345 end subroutine unittest
4346 
4347 
4348 end module quaternions
4349 # 14 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
4350 
4351 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/Lambert.f90" 1
4352 ! ###################################################################
4353 ! Copyright (c) 2013-2015, Marc De Graef/Carnegie Mellon University
4354 ! Modified 2017-2019, Martin Diehl/Max-Planck-Institut für Eisenforschung GmbH
4355 ! All rights reserved.
4356 !
4357 ! Redistribution and use in source and binary forms, with or without modification, are
4358 ! permitted provided that the following conditions are met:
4359 !
4360 ! - Redistributions of source code must retain the above copyright notice, this list
4361 ! of conditions and the following disclaimer.
4362 ! - Redistributions in binary form must reproduce the above copyright notice, this
4363 ! list of conditions and the following disclaimer in the documentation and/or
4364 ! other materials provided with the distribution.
4365 ! - Neither the names of Marc De Graef, Carnegie Mellon University nor the names
4366 ! of its contributors may be used to endorse or promote products derived from
4367 ! this software without specific prior written permission.
4368 !
4369 ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
4370 ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4371 ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4372 ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
4373 ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4374 ! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
4375 ! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
4376 ! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
4377 ! OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
4378 ! USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4379 ! ###################################################################
4380 
4381 !--------------------------------------------------------------------------
4385 !
4390 !--------------------------------------------------------------------------
4391 module lambert
4392  use prec
4393  use math
4394 
4395  implicit none
4396  private
4397 
4398  real(preal), parameter :: &
4399  spi = sqrt(pi), &
4400  pref = sqrt(6.0_preal/pi), &
4401  a = pi**(5.0_preal/6.0_preal)/6.0_preal**(1.0_preal/6.0_preal), &
4402  ap = pi**(2.0_preal/3.0_preal), &
4403  sc = a/ap, &
4404  beta = a/2.0_preal, &
4405  r1 = (3.0_preal*pi/4.0_preal)**(1.0_preal/3.0_preal), &
4406  r2 = sqrt(2.0_preal), &
4407  pi12 = pi/12.0_preal, &
4408  prek = r1 * 2.0_preal**(1.0_preal/4.0_preal)/beta
4409 
4410  public :: &
4413 
4414 contains
4415 
4416 
4417 !--------------------------------------------------------------------------
4421 !--------------------------------------------------------------------------
4422 pure function lambert_cubetoball(cube) result(ball)
4424  real(preal), intent(in), dimension(3) :: cube
4425  real(preal), dimension(3) :: ball, lamxyz, xyz
4426  real(preal), dimension(2) :: t
4427  real(preal) :: c, s, q
4428  real(preal), parameter :: eps = 1.0e-8_preal
4429  integer, dimension(3) :: p
4430  integer, dimension(2) :: order
4431 
4432  if (maxval(abs(cube)) > ap/2.0+eps) then
4433  ball = ieee_value(cube,ieee_positive_inf)
4434  return
4435  end if
4436 
4437  ! transform to the sphere grid via the curved square, and intercept the zero point
4438  center: if (all(deq0(cube))) then
4439  ball = 0.0_preal
4440  else center
4441  ! get pyramide and scale by grid parameter ratio
4442  p = getpyramidorder(cube)
4443  xyz = cube(p) * sc
4444 
4445  ! intercept all the points along the z-axis
4446  special: if (all(deq0(xyz(1:2)))) then
4447  lamxyz = [ 0.0_preal, 0.0_preal, pref * xyz(3) ]
4448  else special
4449  order = merge( [2,1], [1,2], abs(xyz(2)) <= abs(xyz(1))) ! order of absolute values of XYZ
4450  q = pi12 * xyz(order(1))/xyz(order(2)) ! smaller by larger
4451  c = cos(q)
4452  s = sin(q)
4453  q = prek * xyz(order(2))/ sqrt(r2-c)
4454  t = [ (r2*c - 1.0), r2 * s] * q
4455 
4456  ! transform to sphere grid (inverse Lambert)
4457  ! [note that there is no need to worry about dividing by zero, since XYZ(3) can not become zero]
4458  c = sum(t**2)
4459  s = pi * c/(24.0*xyz(3)**2)
4460  c = spi * c / sqrt(24.0_preal) / xyz(3)
4461  q = sqrt( 1.0 - s )
4462  lamxyz = [ t(order(2)) * q, t(order(1)) * q, pref * xyz(3) - c ]
4463  endif special
4464 
4465  ! reverse the coordinates back to order according to the original pyramid number
4466  ball = lamxyz(p)
4467 
4468  endif center
4469 
4470 end function lambert_cubetoball
4471 
4472 
4473 !--------------------------------------------------------------------------
4477 !--------------------------------------------------------------------------
4478 pure function lambert_balltocube(xyz) result(cube)
4480  real(preal), intent(in), dimension(3) :: xyz
4481  real(preal), dimension(3) :: cube, xyz1, xyz3
4482  real(preal), dimension(2) :: tinv, xyz2
4483  real(preal) :: rs, qxy, q2, sq2, q, tt
4484  integer, dimension(3) :: p
4485 
4486  rs = norm2(xyz)
4487  if (rs > r1) then
4488  cube = ieee_value(cube,ieee_positive_inf)
4489  return
4490  endif
4491 
4492  center: if (all(deq0(xyz))) then
4493  cube = 0.0_preal
4494  else center
4495  p = getpyramidorder(xyz)
4496  xyz3 = xyz(p)
4497 
4498  ! inverse M_3
4499  xyz2 = xyz3(1:2) * sqrt( 2.0*rs/(rs+abs(xyz3(3))) )
4500 
4501  ! inverse M_2
4502  qxy = sum(xyz2**2)
4503 
4504  special: if (deq0(qxy)) then
4505  tinv = 0.0_preal
4506  else special
4507  q2 = qxy + maxval(abs(xyz2))**2
4508  sq2 = sqrt(q2)
4509  q = (beta/r2/r1) * sqrt(q2*qxy/(q2-maxval(abs(xyz2))*sq2))
4510  tt = (minval(abs(xyz2))**2+maxval(abs(xyz2))*sq2)/r2/qxy
4511  tinv = q * sign(1.0_preal,xyz2) * merge([ 1.0_preal, acos(math_clip(tt,-1.0_preal,1.0_preal))/pi12], &
4512  [ acos(math_clip(tt,-1.0_preal,1.0_preal))/pi12, 1.0_preal], &
4513  abs(xyz2(2)) <= abs(xyz2(1)))
4514  endif special
4515 
4516  ! inverse M_1
4517  xyz1 = [ tinv(1), tinv(2), sign(1.0_preal,xyz3(3)) * rs / pref ] /sc
4518 
4519  ! reverse the coordinates back to order according to the original pyramid number
4520  cube = xyz1(p)
4521 
4522  endif center
4523 
4524 end function lambert_balltocube
4525 
4526 
4527 !--------------------------------------------------------------------------
4531 !--------------------------------------------------------------------------
4532 pure function getpyramidorder(xyz)
4534  real(preal),intent(in),dimension(3) :: xyz
4535  integer, dimension(3) :: getpyramidorder
4536 
4537  if (((abs(xyz(1)) <= xyz(3)).and.(abs(xyz(2)) <= xyz(3))) .or. &
4538  ((abs(xyz(1)) <= -xyz(3)).and.(abs(xyz(2)) <= -xyz(3)))) then
4539  getpyramidorder = [1,2,3]
4540  else if (((abs(xyz(3)) <= xyz(1)).and.(abs(xyz(2)) <= xyz(1))) .or. &
4541  ((abs(xyz(3)) <= -xyz(1)).and.(abs(xyz(2)) <= -xyz(1)))) then
4542  getpyramidorder = [2,3,1]
4543  else if (((abs(xyz(1)) <= xyz(2)).and.(abs(xyz(3)) <= xyz(2))) .or. &
4544  ((abs(xyz(1)) <= -xyz(2)).and.(abs(xyz(3)) <= -xyz(2)))) then
4545  getpyramidorder = [3,1,2]
4546  else
4547  getpyramidorder = -1 ! should be impossible, but might simplify debugging
4548  end if
4549 
4550 end function getpyramidorder
4551 
4552 end module lambert
4553 # 15 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
4554 
4555 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/rotations.f90" 1
4556 ! ###################################################################
4557 ! Copyright (c) 2013-2014, Marc De Graef/Carnegie Mellon University
4558 ! Modified 2017-2020, Martin Diehl/Max-Planck-Institut für Eisenforschung GmbH
4559 ! All rights reserved.
4560 !
4561 ! Redistribution and use in source and binary forms, with or without modification, are
4562 ! permitted provided that the following conditions are met:
4563 !
4564 ! - Redistributions of source code must retain the above copyright notice, this list
4565 ! of conditions and the following disclaimer.
4566 ! - Redistributions in binary form must reproduce the above copyright notice, this
4567 ! list of conditions and the following disclaimer in the documentation and/or
4568 ! other materials provided with the distribution.
4569 ! - Neither the names of Marc De Graef, Carnegie Mellon University nor the names
4570 ! of its contributors may be used to endorse or promote products derived from
4571 ! this software without specific prior written permission.
4572 !
4573 ! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
4574 ! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4575 ! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4576 ! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
4577 ! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4578 ! DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
4579 ! SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
4580 ! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
4581 ! OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
4582 ! USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4583 ! ###################################################################
4584 
4585 !---------------------------------------------------------------------------------------------------
4591 !
4592 ! All methods and naming conventions based on Rowenhorst_etal2015
4593 ! Convention 1: coordinate frames are right-handed
4594 ! Convention 2: a rotation angle ω is taken to be positive for a counterclockwise rotation
4595 ! when viewing from the end point of the rotation axis towards the origin
4596 ! Convention 3: rotations will be interpreted in the passive sense
4597 ! Convention 4: Euler angle triplets are implemented using the Bunge convention,
4598 ! with the angular ranges as [0, 2π],[0, π],[0, 2π]
4599 ! Convention 5: the rotation angle ω is limited to the interval [0, π]
4600 ! Convention 6: the real part of a quaternion is positive, Re(q) > 0
4601 ! Convention 7: P = -1
4602 !---------------------------------------------------------------------------------------------------
4603 
4605  use prec
4606  use io
4607  use math
4608  use lambert
4609  use quaternions
4610 
4611  implicit none
4612  private
4613 
4614  type, public :: rotation
4615  type(quaternion), private :: q
4616  contains
4617  procedure, public :: asquaternion
4618  procedure, public :: aseulers
4619  procedure, public :: asaxisangle
4620  procedure, public :: asrodrigues
4621  procedure, public :: asmatrix
4622  !------------------------------------------
4623  procedure, public :: fromquaternion
4624  procedure, public :: fromeulers
4625  procedure, public :: fromaxisangle
4626  procedure, public :: frommatrix
4627  !------------------------------------------
4628  procedure, private :: rotrot__
4629  generic, public :: operator(*) => rotrot__
4630  generic, public :: rotate => rotvector,rottensor2,rottensor4
4631  procedure, public :: rotvector
4632  procedure, public :: rottensor2
4633  procedure, public :: rottensor4
4634  procedure, public :: rottensor4sym
4635  procedure, public :: misorientation
4636  procedure, public :: standardize
4637  end type rotation
4638 
4639  public :: &
4640  rotations_init, &
4641  eu2om
4642 
4643 contains
4644 
4645 !--------------------------------------------------------------------------------------------------
4647 !--------------------------------------------------------------------------------------------------
4648 subroutine rotations_init
4650  call quaternions_init
4651  write(6,'(/,a)') ' <<<+- rotations init -+>>>'; flush(6)
4652  call unittest
4653 
4654 end subroutine rotations_init
4655 
4656 
4657 !---------------------------------------------------------------------------------------------------
4658 ! Return rotation in different representations
4659 !---------------------------------------------------------------------------------------------------
4660 pure function asquaternion(self)
4662  class(rotation), intent(in) :: self
4663  real(preal), dimension(4) :: asquaternion
4664 
4665  asquaternion = self%q%asArray()
4666 
4667 end function asquaternion
4668 !---------------------------------------------------------------------------------------------------
4669 pure function aseulers(self)
4671  class(rotation), intent(in) :: self
4672  real(preal), dimension(3) :: aseulers
4673 
4674  aseulers = qu2eu(self%q%asArray())
4675 
4676 end function aseulers
4677 !---------------------------------------------------------------------------------------------------
4678 pure function asaxisangle(self)
4680  class(rotation), intent(in) :: self
4681  real(preal), dimension(4) :: asaxisangle
4682 
4683  asaxisangle = qu2ax(self%q%asArray())
4684 
4685 end function asaxisangle
4686 !---------------------------------------------------------------------------------------------------
4687 pure function asmatrix(self)
4689  class(rotation), intent(in) :: self
4690  real(preal), dimension(3,3) :: asmatrix
4691 
4692  asmatrix = qu2om(self%q%asArray())
4693 
4694 end function asmatrix
4695 !---------------------------------------------------------------------------------------------------
4696 pure function asrodrigues(self)
4698  class(rotation), intent(in) :: self
4699  real(preal), dimension(4) :: asrodrigues
4700 
4701  asrodrigues = qu2ro(self%q%asArray())
4702 
4703 end function asrodrigues
4704 !---------------------------------------------------------------------------------------------------
4705 pure function ashomochoric(self)
4707  class(rotation), intent(in) :: self
4708  real(preal), dimension(3) :: ashomochoric
4709 
4710  ashomochoric = qu2ho(self%q%asArray())
4711 
4712 end function ashomochoric
4713 
4714 !---------------------------------------------------------------------------------------------------
4715 ! Initialize rotation from different representations
4716 !---------------------------------------------------------------------------------------------------
4717 subroutine fromquaternion(self,qu)
4719  class(rotation), intent(out) :: self
4720  real(pReal), dimension(4), intent(in) :: qu
4721 
4722  if (dneq(norm2(qu),1.0_preal)) &
4723  call io_error(402,ext_msg='fromQuaternion')
4724 
4725  self%q = qu
4726 
4727 end subroutine fromquaternion
4728 !---------------------------------------------------------------------------------------------------
4729 subroutine fromeulers(self,eu,degrees)
4731  class(rotation), intent(out) :: self
4732  real(pReal), dimension(3), intent(in) :: eu
4733  logical, intent(in), optional :: degrees
4734 
4735  real(pReal), dimension(3) :: Eulers
4736 
4737  if (.not. present(degrees)) then
4738  eulers = eu
4739  else
4740  eulers = merge(eu*inrad,eu,degrees)
4741  endif
4742 
4743  if (any(eulers<0.0_preal) .or. any(eulers>2.0_preal*pi) .or. eulers(2) > pi) &
4744  call io_error(402,ext_msg='fromEulers')
4745 
4746  self%q = eu2qu(eulers)
4747 
4748 end subroutine fromeulers
4749 !---------------------------------------------------------------------------------------------------
4750 subroutine fromaxisangle(self,ax,degrees,P)
4752  class(rotation), intent(out) :: self
4753  real(pReal), dimension(4), intent(in) :: ax
4754  logical, intent(in), optional :: degrees
4755  integer, intent(in), optional :: P
4756 
4757  real(pReal) :: angle
4758  real(pReal),dimension(3) :: axis
4759 
4760  if (.not. present(degrees)) then
4761  angle = ax(4)
4762  else
4763  angle = merge(ax(4)*inrad,ax(4),degrees)
4764  endif
4765 
4766  if (.not. present(p)) then
4767  axis = ax(1:3)
4768  else
4769  axis = ax(1:3) * merge(-1.0_preal,1.0_preal,p == 1)
4770  if(abs(p) /= 1) call io_error(402,ext_msg='fromAxisAngle (P)')
4771  endif
4772 
4773  if(dneq(norm2(axis),1.0_preal) .or. angle < 0.0_preal .or. angle > pi) &
4774  call io_error(402,ext_msg='fromAxisAngle')
4775 
4776  self%q = ax2qu([axis,angle])
4777 
4778 end subroutine fromaxisangle
4779 !---------------------------------------------------------------------------------------------------
4780 subroutine frommatrix(self,om)
4782  class(rotation), intent(out) :: self
4783  real(pReal), dimension(3,3), intent(in) :: om
4784 
4785  if (dneq(math_det33(om),1.0_preal,tol=1.0e-5_preal)) &
4786  call io_error(402,ext_msg='fromMatrix')
4787 
4788  self%q = om2qu(om)
4789 
4790 end subroutine frommatrix
4791 !---------------------------------------------------------------------------------------------------
4792 
4793 
4794 !---------------------------------------------------------------------------------------------------
4796 !---------------------------------------------------------------------------------------------------
4797 pure elemental function rotrot__(self,R) result(rRot)
4799  type(rotation) :: rrot
4800  class(rotation), intent(in) :: self,r
4801 
4802  rrot = rotation(self%q*r%q)
4803  call rrot%standardize()
4804 
4805 end function rotrot__
4806 
4807 
4808 !---------------------------------------------------------------------------------------------------
4810 !---------------------------------------------------------------------------------------------------
4811 pure elemental subroutine standardize(self)
4813  class(rotation), intent(inout) :: self
4814 
4815  if (real(self%q) < 0.0_preal) self%q = self%q%homomorphed()
4816 
4817 end subroutine standardize
4818 
4819 
4820 !---------------------------------------------------------------------------------------------------
4823 !---------------------------------------------------------------------------------------------------
4824 pure function rotvector(self,v,active) result(vRot)
4826  real(preal), dimension(3) :: vrot
4827  class(rotation), intent(in) :: self
4828  real(preal), intent(in), dimension(3) :: v
4829  logical, intent(in), optional :: active
4830 
4831  real(preal), dimension(3) :: v_normed
4832  type(quaternion) :: q
4833  logical :: passive
4834 
4835  if (present(active)) then
4836  passive = .not. active
4837  else
4838  passive = .true.
4839  endif
4840 
4841  if (deq0(norm2(v))) then
4842  vrot = v
4843  else
4844  v_normed = v/norm2(v)
4845  if (passive) then
4846  q = self%q * (quaternion([0.0_preal, v_normed(1), v_normed(2), v_normed(3)]) * conjg(self%q) )
4847  else
4848  q = conjg(self%q) * (quaternion([0.0_preal, v_normed(1), v_normed(2), v_normed(3)]) * self%q )
4849  endif
4850  vrot = q%aimag()*norm2(v)
4851  endif
4852 
4853 end function rotvector
4854 
4855 
4856 !---------------------------------------------------------------------------------------------------
4860 !---------------------------------------------------------------------------------------------------
4861 pure function rottensor2(self,T,active) result(tRot)
4863  real(preal), dimension(3,3) :: trot
4864  class(rotation), intent(in) :: self
4865  real(preal), intent(in), dimension(3,3) :: t
4866  logical, intent(in), optional :: active
4867 
4868  logical :: passive
4869 
4870  if (present(active)) then
4871  passive = .not. active
4872  else
4873  passive = .true.
4874  endif
4875 
4876  if (passive) then
4877  trot = matmul(matmul(self%asMatrix(),t),transpose(self%asMatrix()))
4878  else
4879  trot = matmul(matmul(transpose(self%asMatrix()),t),self%asMatrix())
4880  endif
4881 
4882 end function rottensor2
4883 
4884 
4885 !---------------------------------------------------------------------------------------------------
4890 !---------------------------------------------------------------------------------------------------
4891 pure function rottensor4(self,T,active) result(tRot)
4893  real(preal), dimension(3,3,3,3) :: trot
4894  class(rotation), intent(in) :: self
4895  real(preal), intent(in), dimension(3,3,3,3) :: t
4896  logical, intent(in), optional :: active
4897 
4898  real(preal), dimension(3,3) :: r
4899  integer :: i,j,k,l,m,n,o,p
4900 
4901  if (present(active)) then
4902  r = merge(transpose(self%asMatrix()),self%asMatrix(),active)
4903  else
4904  r = self%asMatrix()
4905  endif
4906 
4907  trot = 0.0_preal
4908  do i = 1,3;do j = 1,3;do k = 1,3;do l = 1,3
4909  do m = 1,3;do n = 1,3;do o = 1,3;do p = 1,3
4910  trot(i,j,k,l) = trot(i,j,k,l) &
4911  + r(i,m) * r(j,n) * r(k,o) * r(l,p) * t(m,n,o,p)
4912  enddo; enddo; enddo; enddo; enddo; enddo; enddo; enddo
4913 
4914 end function rottensor4
4915 
4916 
4917 !---------------------------------------------------------------------------------------------------
4921 !---------------------------------------------------------------------------------------------------
4922 pure function rottensor4sym(self,T,active) result(tRot)
4924  real(preal), dimension(6,6) :: trot
4925  class(rotation), intent(in) :: self
4926  real(preal), intent(in), dimension(6,6) :: t
4927  logical, intent(in), optional :: active
4928 
4929  if (present(active)) then
4930  trot = math_sym3333to66(rottensor4(self,math_66tosym3333(t),active))
4931  else
4933  endif
4934 
4935 end function rottensor4sym
4936 
4937 
4938 !---------------------------------------------------------------------------------------------------
4940 !---------------------------------------------------------------------------------------------------
4941 pure elemental function misorientation(self,other)
4943  type(rotation) :: misorientation
4944  class(rotation), intent(in) :: self, other
4945 
4946  misorientation%q = other%q * conjg(self%q)
4947 
4948 end function misorientation
4949 
4950 
4951 !---------------------------------------------------------------------------------------------------
4954 !---------------------------------------------------------------------------------------------------
4955 pure function qu2om(qu) result(om)
4957  real(preal), intent(in), dimension(4) :: qu
4958  real(preal), dimension(3,3) :: om
4959 
4960  real(preal) :: qq
4961 
4962  qq = qu(1)**2-sum(qu(2:4)**2)
4963 
4964 
4965  om(1,1) = qq+2.0_preal*qu(2)**2
4966  om(2,2) = qq+2.0_preal*qu(3)**2
4967  om(3,3) = qq+2.0_preal*qu(4)**2
4968 
4969  om(1,2) = 2.0_preal*(qu(2)*qu(3)-qu(1)*qu(4))
4970  om(2,3) = 2.0_preal*(qu(3)*qu(4)-qu(1)*qu(2))
4971  om(3,1) = 2.0_preal*(qu(4)*qu(2)-qu(1)*qu(3))
4972  om(2,1) = 2.0_preal*(qu(3)*qu(2)+qu(1)*qu(4))
4973  om(3,2) = 2.0_preal*(qu(4)*qu(3)+qu(1)*qu(2))
4974  om(1,3) = 2.0_preal*(qu(2)*qu(4)+qu(1)*qu(3))
4975 
4976  if (p < 0.0_preal) om = transpose(om)
4977 
4978 end function qu2om
4979 
4980 
4981 !---------------------------------------------------------------------------------------------------
4984 !---------------------------------------------------------------------------------------------------
4985 pure function qu2eu(qu) result(eu)
4987  real(preal), intent(in), dimension(4) :: qu
4988  real(preal), dimension(3) :: eu
4989 
4990  real(preal) :: q12, q03, chi, chiinv
4991 
4992  q03 = qu(1)**2+qu(4)**2
4993  q12 = qu(2)**2+qu(3)**2
4994  chi = sqrt(q03*q12)
4995 
4996  degenerated: if (deq0(chi)) then
4997  eu = merge([atan2(-p*2.0_preal*qu(1)*qu(4),qu(1)**2-qu(4)**2), 0.0_preal, 0.0_preal], &
4998  [atan2( 2.0_preal*qu(2)*qu(3),qu(2)**2-qu(3)**2), pi, 0.0_preal], &
4999  deq0(q12))
5000  else degenerated
5001  chiinv = 1.0_preal/chi
5002  eu = [atan2((-p*qu(1)*qu(3)+qu(2)*qu(4))*chi, (-p*qu(1)*qu(2)-qu(3)*qu(4))*chi ), &
5003  atan2( 2.0_preal*chi, q03-q12 ), &
5004  atan2(( p*qu(1)*qu(3)+qu(2)*qu(4))*chi, (-p*qu(1)*qu(2)+qu(3)*qu(4))*chi )]
5005  endif degenerated
5006  where(eu<0.0_preal) eu = mod(eu+2.0_preal*pi,[2.0_preal*pi,pi,2.0_preal*pi])
5007 
5008 end function qu2eu
5009 
5010 
5011 !---------------------------------------------------------------------------------------------------
5014 !---------------------------------------------------------------------------------------------------
5015 pure function qu2ax(qu) result(ax)
5017  real(preal), intent(in), dimension(4) :: qu
5018  real(preal), dimension(4) :: ax
5019 
5020  real(preal) :: omega, s
5021 
5022  if (deq0(sum(qu(2:4)**2))) then
5023  ax = [ 0.0_preal, 0.0_preal, 1.0_preal, 0.0_preal ] ! axis = [001]
5024  elseif (dneq0(qu(1))) then
5025  s = sign(1.0_preal,qu(1))/norm2(qu(2:4))
5026  omega = 2.0_preal * acos(math_clip(qu(1),-1.0_preal,1.0_preal))
5027  ax = [ qu(2)*s, qu(3)*s, qu(4)*s, omega ]
5028  else
5029  ax = [ qu(2), qu(3), qu(4), pi ]
5030  end if
5031 
5032 end function qu2ax
5033 
5034 
5035 !---------------------------------------------------------------------------------------------------
5038 !---------------------------------------------------------------------------------------------------
5039 pure function qu2ro(qu) result(ro)
5041  real(preal), intent(in), dimension(4) :: qu
5042  real(preal), dimension(4) :: ro
5043 
5044  real(preal) :: s
5045  real(preal), parameter :: thr = 1.0e-8_preal
5046 
5047  if (abs(qu(1)) < thr) then
5048  ro = [qu(2), qu(3), qu(4), ieee_value(1.0_preal,ieee_positive_inf)]
5049  else
5050  s = norm2(qu(2:4))
5051  if (s < thr) then
5052  ro = [0.0_preal, 0.0_preal, p, 0.0_preal]
5053  else
5054  ro = [qu(2)/s,qu(3)/s,qu(4)/s, tan(acos(math_clip(qu(1),-1.0_preal,1.0_preal)))]
5055  endif
5056 
5057  end if
5058 
5059 end function qu2ro
5060 
5061 
5062 !---------------------------------------------------------------------------------------------------
5065 !---------------------------------------------------------------------------------------------------
5066 pure function qu2ho(qu) result(ho)
5068  real(preal), intent(in), dimension(4) :: qu
5069  real(preal), dimension(3) :: ho
5070 
5071  real(preal) :: omega, f
5072 
5073  omega = 2.0 * acos(math_clip(qu(1),-1.0_preal,1.0_preal))
5074 
5075  if (deq0(omega)) then
5076  ho = [ 0.0_preal, 0.0_preal, 0.0_preal ]
5077  else
5078  ho = qu(2:4)
5079  f = 0.75_preal * ( omega - sin(omega) )
5080  ho = ho/norm2(ho)* f**(1.0_preal/3.0_preal)
5081  end if
5082 
5083 end function qu2ho
5084 
5085 
5086 !---------------------------------------------------------------------------------------------------
5089 !---------------------------------------------------------------------------------------------------
5090 pure function qu2cu(qu) result(cu)
5092  real(preal), intent(in), dimension(4) :: qu
5093  real(preal), dimension(3) :: cu
5094 
5095  cu = ho2cu(qu2ho(qu))
5096 
5097 end function qu2cu
5098 
5099 
5100 !---------------------------------------------------------------------------------------------------
5104 !---------------------------------------------------------------------------------------------------
5105 pure function om2qu(om) result(qu)
5107  real(preal), intent(in), dimension(3,3) :: om
5108  real(preal), dimension(4) :: qu
5109 
5110  qu = eu2qu(om2eu(om))
5111 
5112 end function om2qu
5113 
5114 
5115 !---------------------------------------------------------------------------------------------------
5118 !---------------------------------------------------------------------------------------------------
5119 pure function om2eu(om) result(eu)
5121  real(preal), intent(in), dimension(3,3) :: om
5122  real(preal), dimension(3) :: eu
5123  real(preal) :: zeta
5124 
5125  if (abs(om(3,3)) < 1.0_preal) then
5126  zeta = 1.0_preal/sqrt(1.0_preal-om(3,3)**2.0_preal)
5127  eu = [atan2(om(3,1)*zeta,-om(3,2)*zeta), &
5128  acos(om(3,3)), &
5129  atan2(om(1,3)*zeta, om(2,3)*zeta)]
5130  else
5131  eu = [atan2(om(1,2),om(1,1)), 0.5_preal*pi*(1.0_preal-om(3,3)),0.0_preal ]
5132  end if
5133 
5134  where(eu<0.0_preal) eu = mod(eu+2.0_preal*pi,[2.0_preal*pi,pi,2.0_preal*pi])
5135 
5136 end function om2eu
5137 
5138 
5139 !---------------------------------------------------------------------------------------------------
5142 !---------------------------------------------------------------------------------------------------
5143 function om2ax(om) result(ax)
5145  real(preal), intent(in), dimension(3,3) :: om
5146  real(preal), dimension(4) :: ax
5147 
5148  real(preal) :: t
5149  real(preal), dimension(3) :: wr, wi
5150  real(preal), dimension((64+2)*3) :: work
5151  real(preal), dimension(3,3) :: vr, devnull, om_
5152  integer :: ierr, i
5153 
5154  external :: dgeev
5155 
5156  om_ = om
5157 
5158  ! first get the rotation angle
5159  t = 0.5_preal * (math_trace33(om) - 1.0_preal)
5160  ax(4) = acos(math_clip(t,-1.0_preal,1.0_preal))
5161 
5162  if (deq0(ax(4))) then
5163  ax(1:3) = [ 0.0_preal, 0.0_preal, 1.0_preal ]
5164  else
5165  call dgeev('N','V',3,om_,3,wr,wi,devnull,3,vr,3,work,size(work,1),ierr)
5166  if (ierr /= 0) call io_error(401,ext_msg='Error in om2ax: DGEEV return not zero')
5167 
5168  i = maxloc(merge(1,0,ceq(cmplx(wr,wi,preal),cmplx(1.0_preal,0.0_preal,preal),tol=1.0e-14_preal)),dim=1)
5169 
5170 
5171 
5172  if (i == 0) call io_error(401,ext_msg='Error in om2ax Real: eigenvalue not found')
5173  ax(1:3) = vr(1:3,i)
5174  where ( dneq0([om(2,3)-om(3,2), om(3,1)-om(1,3), om(1,2)-om(2,1)])) &
5175  ax(1:3) = sign(ax(1:3),-p *[om(2,3)-om(3,2), om(3,1)-om(1,3), om(1,2)-om(2,1)])
5176  endif
5177 
5178 end function om2ax
5179 
5180 
5181 !---------------------------------------------------------------------------------------------------
5184 !---------------------------------------------------------------------------------------------------
5185 pure function om2ro(om) result(ro)
5187  real(preal), intent(in), dimension(3,3) :: om
5188  real(preal), dimension(4) :: ro
5189 
5190  ro = eu2ro(om2eu(om))
5191 
5192 end function om2ro
5193 
5194 
5195 !---------------------------------------------------------------------------------------------------
5198 !---------------------------------------------------------------------------------------------------
5199 function om2ho(om) result(ho)
5201  real(preal), intent(in), dimension(3,3) :: om
5202  real(preal), dimension(3) :: ho
5203 
5204  ho = ax2ho(om2ax(om))
5205 
5206 end function om2ho
5207 
5208 
5209 !---------------------------------------------------------------------------------------------------
5212 !---------------------------------------------------------------------------------------------------
5213 function om2cu(om) result(cu)
5215  real(preal), intent(in), dimension(3,3) :: om
5216  real(preal), dimension(3) :: cu
5217 
5218  cu = ho2cu(om2ho(om))
5219 
5220 end function om2cu
5221 
5222 
5223 !---------------------------------------------------------------------------------------------------
5226 !---------------------------------------------------------------------------------------------------
5227 pure function eu2qu(eu) result(qu)
5229  real(preal), intent(in), dimension(3) :: eu
5230  real(preal), dimension(4) :: qu
5231  real(preal), dimension(3) :: ee
5232  real(preal) :: cphi, sphi
5233 
5234  ee = 0.5_preal*eu
5235 
5236  cphi = cos(ee(2))
5237  sphi = sin(ee(2))
5238 
5239  qu = [ cphi*cos(ee(1)+ee(3)), &
5240  -p*sphi*cos(ee(1)-ee(3)), &
5241  -p*sphi*sin(ee(1)-ee(3)), &
5242  -p*cphi*sin(ee(1)+ee(3))]
5243  if(qu(1) < 0.0_preal) qu = qu * (-1.0_preal)
5244 
5245 end function eu2qu
5246 
5247 
5248 !---------------------------------------------------------------------------------------------------
5251 !---------------------------------------------------------------------------------------------------
5252 pure function eu2om(eu) result(om)
5254  real(preal), intent(in), dimension(3) :: eu
5255  real(preal), dimension(3,3) :: om
5256 
5257  real(preal), dimension(3) :: c, s
5258 
5259  c = cos(eu)
5260  s = sin(eu)
5261 
5262  om(1,1) = c(1)*c(3)-s(1)*s(3)*c(2)
5263  om(1,2) = s(1)*c(3)+c(1)*s(3)*c(2)
5264  om(1,3) = s(3)*s(2)
5265  om(2,1) = -c(1)*s(3)-s(1)*c(3)*c(2)
5266  om(2,2) = -s(1)*s(3)+c(1)*c(3)*c(2)
5267  om(2,3) = c(3)*s(2)
5268  om(3,1) = s(1)*s(2)
5269  om(3,2) = -c(1)*s(2)
5270  om(3,3) = c(2)
5271 
5272  where(deq0(om)) om = 0.0_preal
5273 
5274 end function eu2om
5275 
5276 
5277 !---------------------------------------------------------------------------------------------------
5280 !---------------------------------------------------------------------------------------------------
5281 pure function eu2ax(eu) result(ax)
5283  real(preal), intent(in), dimension(3) :: eu
5284  real(preal), dimension(4) :: ax
5285 
5286  real(preal) :: t, delta, tau, alpha, sigma
5287 
5288  t = tan(eu(2)*0.5_preal)
5289  sigma = 0.5_preal*(eu(1)+eu(3))
5290  delta = 0.5_preal*(eu(1)-eu(3))
5291  tau = sqrt(t**2+sin(sigma)**2)
5292 
5293  alpha = merge(pi, 2.0_preal*atan(tau/cos(sigma)), deq(sigma,pi*0.5_preal,tol=1.0e-15_preal))
5294 
5295  if (deq0(alpha)) then ! return a default identity axis-angle pair
5296  ax = [ 0.0_preal, 0.0_preal, 1.0_preal, 0.0_preal ]
5297  else
5298  ax(1:3) = -p/tau * [ t*cos(delta), t*sin(delta), sin(sigma) ] ! passive axis-angle pair so a minus sign in front
5299  ax(4) = alpha
5300  if (alpha < 0.0_preal) ax = -ax ! ensure alpha is positive
5301  end if
5302 
5303 end function eu2ax
5304 
5305 
5306 !---------------------------------------------------------------------------------------------------
5309 !---------------------------------------------------------------------------------------------------
5310 pure function eu2ro(eu) result(ro)
5312  real(preal), intent(in), dimension(3) :: eu
5313  real(preal), dimension(4) :: ro
5314 
5315  ro = eu2ax(eu)
5316  if (ro(4) >= pi) then
5317  ro(4) = ieee_value(ro(4),ieee_positive_inf)
5318  elseif(deq0(ro(4))) then
5319  ro = [ 0.0_preal, 0.0_preal, p, 0.0_preal ]
5320  else
5321  ro(4) = tan(ro(4)*0.5_preal)
5322  end if
5323 
5324 end function eu2ro
5325 
5326 
5327 !---------------------------------------------------------------------------------------------------
5330 !---------------------------------------------------------------------------------------------------
5331 pure function eu2ho(eu) result(ho)
5333  real(preal), intent(in), dimension(3) :: eu
5334  real(preal), dimension(3) :: ho
5335 
5336  ho = ax2ho(eu2ax(eu))
5337 
5338 end function eu2ho
5339 
5340 
5341 !---------------------------------------------------------------------------------------------------
5344 !---------------------------------------------------------------------------------------------------
5345 function eu2cu(eu) result(cu)
5347  real(preal), intent(in), dimension(3) :: eu
5348  real(preal), dimension(3) :: cu
5349 
5350  cu = ho2cu(eu2ho(eu))
5351 
5352 end function eu2cu
5353 
5354 
5355 !---------------------------------------------------------------------------------------------------
5358 !---------------------------------------------------------------------------------------------------
5359 pure function ax2qu(ax) result(qu)
5361  real(preal), intent(in), dimension(4) :: ax
5362  real(preal), dimension(4) :: qu
5363 
5364  real(preal) :: c, s
5365 
5366 
5367  if (deq0(ax(4))) then
5368  qu = [ 1.0_preal, 0.0_preal, 0.0_preal, 0.0_preal ]
5369  else
5370  c = cos(ax(4)*0.5_preal)
5371  s = sin(ax(4)*0.5_preal)
5372  qu = [ c, ax(1)*s, ax(2)*s, ax(3)*s ]
5373  end if
5374 
5375 end function ax2qu
5376 
5377 
5378 !---------------------------------------------------------------------------------------------------
5381 !---------------------------------------------------------------------------------------------------
5382 pure function ax2om(ax) result(om)
5384  real(preal), intent(in), dimension(4) :: ax
5385  real(preal), dimension(3,3) :: om
5386 
5387  real(preal) :: q, c, s, omc
5388 
5389  c = cos(ax(4))
5390  s = sin(ax(4))
5391  omc = 1.0_preal-c
5392 
5393  om(1,1) = ax(1)**2*omc + c
5394  om(2,2) = ax(2)**2*omc + c
5395  om(3,3) = ax(3)**2*omc + c
5396 
5397  q = omc*ax(1)*ax(2)
5398  om(1,2) = q + s*ax(3)
5399  om(2,1) = q - s*ax(3)
5400 
5401  q = omc*ax(2)*ax(3)
5402  om(2,3) = q + s*ax(1)
5403  om(3,2) = q - s*ax(1)
5404 
5405  q = omc*ax(3)*ax(1)
5406  om(3,1) = q + s*ax(2)
5407  om(1,3) = q - s*ax(2)
5408 
5409  if (p > 0.0_preal) om = transpose(om)
5410 
5411 end function ax2om
5412 
5413 
5414 !---------------------------------------------------------------------------------------------------
5417 !---------------------------------------------------------------------------------------------------
5418 pure function ax2eu(ax) result(eu)
5420  real(preal), intent(in), dimension(4) :: ax
5421  real(preal), dimension(3) :: eu
5422 
5423  eu = om2eu(ax2om(ax))
5424 
5425 end function ax2eu
5426 
5427 
5428 !---------------------------------------------------------------------------------------------------
5431 !---------------------------------------------------------------------------------------------------
5432 pure function ax2ro(ax) result(ro)
5434  real(preal), intent(in), dimension(4) :: ax
5435  real(preal), dimension(4) :: ro
5436 
5437  real(preal), parameter :: thr = 1.0e-7_preal
5438 
5439  if (deq0(ax(4))) then
5440  ro = [ 0.0_preal, 0.0_preal, p, 0.0_preal ]
5441  else
5442  ro(1:3) = ax(1:3)
5443  ! we need to deal with the 180 degree case
5444  ro(4) = merge(ieee_value(ro(4),ieee_positive_inf),tan(ax(4)*0.5_preal),abs(ax(4)-pi) < thr)
5445  end if
5446 
5447 end function ax2ro
5448 
5449 
5450 !---------------------------------------------------------------------------------------------------
5453 !---------------------------------------------------------------------------------------------------
5454 pure function ax2ho(ax) result(ho)
5456  real(preal), intent(in), dimension(4) :: ax
5457  real(preal), dimension(3) :: ho
5458 
5459  real(preal) :: f
5460 
5461  f = 0.75_preal * ( ax(4) - sin(ax(4)) )
5462  f = f**(1.0_preal/3.0_preal)
5463  ho = ax(1:3) * f
5464 
5465 end function ax2ho
5466 
5467 
5468 !---------------------------------------------------------------------------------------------------
5471 !---------------------------------------------------------------------------------------------------
5472 function ax2cu(ax) result(cu)
5474  real(preal), intent(in), dimension(4) :: ax
5475  real(preal), dimension(3) :: cu
5476 
5477  cu = ho2cu(ax2ho(ax))
5478 
5479 end function ax2cu
5480 
5481 
5482 !---------------------------------------------------------------------------------------------------
5485 !---------------------------------------------------------------------------------------------------
5486 pure function ro2qu(ro) result(qu)
5488  real(preal), intent(in), dimension(4) :: ro
5489  real(preal), dimension(4) :: qu
5490 
5491  qu = ax2qu(ro2ax(ro))
5492 
5493 end function ro2qu
5494 
5495 
5496 !---------------------------------------------------------------------------------------------------
5499 !---------------------------------------------------------------------------------------------------
5500 pure function ro2om(ro) result(om)
5502  real(preal), intent(in), dimension(4) :: ro
5503  real(preal), dimension(3,3) :: om
5504 
5505  om = ax2om(ro2ax(ro))
5506 
5507 end function ro2om
5508 
5509 
5510 !---------------------------------------------------------------------------------------------------
5513 !---------------------------------------------------------------------------------------------------
5514 pure function ro2eu(ro) result(eu)
5516  real(preal), intent(in), dimension(4) :: ro
5517  real(preal), dimension(3) :: eu
5518 
5519  eu = om2eu(ro2om(ro))
5520 
5521 end function ro2eu
5522 
5523 
5524 !---------------------------------------------------------------------------------------------------
5527 !---------------------------------------------------------------------------------------------------
5528 pure function ro2ax(ro) result(ax)
5530  real(preal), intent(in), dimension(4) :: ro
5531  real(preal), dimension(4) :: ax
5532 
5533  real(preal) :: ta, angle
5534 
5535  ta = ro(4)
5536 
5537  if (.not. ieee_is_finite(ta)) then
5538  ax = [ ro(1), ro(2), ro(3), pi ]
5539  elseif (deq0(ta)) then
5540  ax = [ 0.0_preal, 0.0_preal, 1.0_preal, 0.0_preal ]
5541  else
5542  angle = 2.0_preal*atan(ta)
5543  ta = 1.0_preal/norm2(ro(1:3))
5544  ax = [ ro(1)/ta, ro(2)/ta, ro(3)/ta, angle ]
5545  end if
5546 
5547 end function ro2ax
5548 
5549 
5550 !---------------------------------------------------------------------------------------------------
5553 !---------------------------------------------------------------------------------------------------
5554 pure function ro2ho(ro) result(ho)
5556  real(preal), intent(in), dimension(4) :: ro
5557  real(preal), dimension(3) :: ho
5558 
5559  real(preal) :: f
5560 
5561  if (deq0(norm2(ro(1:3)))) then
5562  ho = [ 0.0_preal, 0.0_preal, 0.0_preal ]
5563  else
5564  f = merge(2.0_preal*atan(ro(4)) - sin(2.0_preal*atan(ro(4))),pi, ieee_is_finite(ro(4)))
5565  ho = ro(1:3) * (0.75_preal*f)**(1.0_preal/3.0_preal)
5566  end if
5567 
5568 end function ro2ho
5569 
5570 
5571 !---------------------------------------------------------------------------------------------------
5574 !---------------------------------------------------------------------------------------------------
5575 pure function ro2cu(ro) result(cu)
5577  real(preal), intent(in), dimension(4) :: ro
5578  real(preal), dimension(3) :: cu
5579 
5580  cu = ho2cu(ro2ho(ro))
5581 
5582 end function ro2cu
5583 
5584 
5585 !---------------------------------------------------------------------------------------------------
5588 !---------------------------------------------------------------------------------------------------
5589 pure function ho2qu(ho) result(qu)
5591  real(preal), intent(in), dimension(3) :: ho
5592  real(preal), dimension(4) :: qu
5593 
5594  qu = ax2qu(ho2ax(ho))
5595 
5596 end function ho2qu
5597 
5598 
5599 !---------------------------------------------------------------------------------------------------
5602 !---------------------------------------------------------------------------------------------------
5603 pure function ho2om(ho) result(om)
5605  real(preal), intent(in), dimension(3) :: ho
5606  real(preal), dimension(3,3) :: om
5607 
5608  om = ax2om(ho2ax(ho))
5609 
5610 end function ho2om
5611 
5612 
5613 !---------------------------------------------------------------------------------------------------
5616 !---------------------------------------------------------------------------------------------------
5617 pure function ho2eu(ho) result(eu)
5619  real(preal), intent(in), dimension(3) :: ho
5620  real(preal), dimension(3) :: eu
5621 
5622  eu = ax2eu(ho2ax(ho))
5623 
5624 end function ho2eu
5625 
5626 
5627 !---------------------------------------------------------------------------------------------------
5630 !---------------------------------------------------------------------------------------------------
5631 pure function ho2ax(ho) result(ax)
5633  real(preal), intent(in), dimension(3) :: ho
5634  real(preal), dimension(4) :: ax
5635 
5636  integer :: i
5637  real(preal) :: hmag_squared, s, hm
5638  real(preal), parameter, dimension(16) :: &
5639  tfit = [ 1.0000000000018852_preal, -0.5000000002194847_preal, &
5640  -0.024999992127593126_preal, -0.003928701544781374_preal, &
5641  -0.0008152701535450438_preal, -0.0002009500426119712_preal, &
5642  -0.00002397986776071756_preal, -0.00008202868926605841_preal, &
5643  +0.00012448715042090092_preal, -0.0001749114214822577_preal, &
5644  +0.0001703481934140054_preal, -0.00012062065004116828_preal, &
5645  +0.000059719705868660826_preal, -0.00001980756723965647_preal, &
5646  +0.000003953714684212874_preal, -0.00000036555001439719544_preal ]
5647 
5648  ! normalize h and store the magnitude
5649  hmag_squared = sum(ho**2.0_preal)
5650  if (deq0(hmag_squared)) then
5651  ax = [ 0.0_preal, 0.0_preal, 1.0_preal, 0.0_preal ]
5652  else
5653  hm = hmag_squared
5654 
5655  ! convert the magnitude to the rotation angle
5656  s = tfit(1) + tfit(2) * hmag_squared
5657  do i=3,16
5658  hm = hm*hmag_squared
5659  s = s + tfit(i) * hm
5660  end do
5661  ax = [ho/sqrt(hmag_squared), 2.0_preal*acos(s)]
5662  end if
5663 
5664 end function ho2ax
5665 
5666 
5667 !---------------------------------------------------------------------------------------------------
5670 !---------------------------------------------------------------------------------------------------
5671 pure function ho2ro(ho) result(ro)
5673  real(preal), intent(in), dimension(3) :: ho
5674  real(preal), dimension(4) :: ro
5675 
5676  ro = ax2ro(ho2ax(ho))
5677 
5678 end function ho2ro
5679 
5680 
5681 !---------------------------------------------------------------------------------------------------
5684 !---------------------------------------------------------------------------------------------------
5685 pure function ho2cu(ho) result(cu)
5687  real(preal), intent(in), dimension(3) :: ho
5688  real(preal), dimension(3) :: cu
5689 
5690  cu = lambert_balltocube(ho)
5691 
5692 end function ho2cu
5693 
5694 
5695 !---------------------------------------------------------------------------------------------------
5698 !---------------------------------------------------------------------------------------------------
5699 pure function cu2qu(cu) result(qu)
5701  real(preal), intent(in), dimension(3) :: cu
5702  real(preal), dimension(4) :: qu
5703 
5704  qu = ho2qu(cu2ho(cu))
5705 
5706 end function cu2qu
5707 
5708 
5709 !---------------------------------------------------------------------------------------------------
5712 !---------------------------------------------------------------------------------------------------
5713 pure function cu2om(cu) result(om)
5715  real(preal), intent(in), dimension(3) :: cu
5716  real(preal), dimension(3,3) :: om
5717 
5718  om = ho2om(cu2ho(cu))
5719 
5720 end function cu2om
5721 
5722 
5723 !---------------------------------------------------------------------------------------------------
5726 !---------------------------------------------------------------------------------------------------
5727 pure function cu2eu(cu) result(eu)
5729  real(preal), intent(in), dimension(3) :: cu
5730  real(preal), dimension(3) :: eu
5731 
5732  eu = ho2eu(cu2ho(cu))
5733 
5734 end function cu2eu
5735 
5736 
5737 !---------------------------------------------------------------------------------------------------
5740 !---------------------------------------------------------------------------------------------------
5741 function cu2ax(cu) result(ax)
5743  real(preal), intent(in), dimension(3) :: cu
5744  real(preal), dimension(4) :: ax
5745 
5746  ax = ho2ax(cu2ho(cu))
5747 
5748 end function cu2ax
5749 
5750 
5751 !---------------------------------------------------------------------------------------------------
5754 !---------------------------------------------------------------------------------------------------
5755 pure function cu2ro(cu) result(ro)
5757  real(preal), intent(in), dimension(3) :: cu
5758  real(preal), dimension(4) :: ro
5759 
5760  ro = ho2ro(cu2ho(cu))
5761 
5762 end function cu2ro
5763 
5764 
5765 !---------------------------------------------------------------------------------------------------
5768 !---------------------------------------------------------------------------------------------------
5769 pure function cu2ho(cu) result(ho)
5771  real(preal), intent(in), dimension(3) :: cu
5772  real(preal), dimension(3) :: ho
5773 
5774  ho = lambert_cubetoball(cu)
5775 
5776 end function cu2ho
5777 
5778 
5779 !--------------------------------------------------------------------------------------------------
5781 !--------------------------------------------------------------------------------------------------
5782 subroutine unittest
5784  type(rotation) :: R
5785  real(pReal), dimension(4) :: qu, ax, ro
5786  real(pReal), dimension(3) :: x, eu, ho, v3
5787  real(pReal), dimension(3,3) :: om, t33
5788  real(pReal), dimension(3,3,3,3) :: t3333
5789  character(len=pStringLen) :: msg
5790  real :: A,B
5791  integer :: i
5792 
5793  do i=1,10
5794 
5795  msg = ''
5796 
5797 
5798  if(i<7) cycle
5799 
5800 
5801  if(i==1) then
5802  qu = om2qu(math_i3)
5803  elseif(i==2) then
5804  qu = eu2qu([0.0_preal,0.0_preal,0.0_preal])
5805  elseif(i==3) then
5806  qu = eu2qu([2.0_preal*pi,pi,2.0_preal*pi])
5807  elseif(i==4) then
5808  qu = [0.0_preal,0.0_preal,1.0_preal,0.0_preal]
5809  elseif(i==5) then
5810  qu = ro2qu([1.0_preal,0.0_preal,0.0_preal,ieee_value(1.0_preal, ieee_positive_inf)])
5811  elseif(i==6) then
5812  qu = ax2qu([1.0_preal,0.0_preal,0.0_preal,0.0_preal])
5813  else
5814  call random_number(x)
5815  a = sqrt(x(3))
5816  b = sqrt(1-0_preal -x(3))
5817  qu = [cos(2.0_preal*pi*x(1))*a,&
5818  sin(2.0_preal*pi*x(2))*b,&
5819  cos(2.0_preal*pi*x(2))*b,&
5820  sin(2.0_preal*pi*x(1))*a]
5821  if(qu(1)<0.0_preal) qu = qu * (-1.0_preal)
5822  endif
5823 
5824  if(dneq0(norm2(om2qu(qu2om(qu))-qu),1.0e-12_preal)) msg = trim(msg)//'om2qu/qu2om,'
5825  if(dneq0(norm2(eu2qu(qu2eu(qu))-qu),1.0e-12_preal)) msg = trim(msg)//'eu2qu/qu2eu,'
5826  if(dneq0(norm2(ax2qu(qu2ax(qu))-qu),1.0e-12_preal)) msg = trim(msg)//'ax2qu/qu2ax,'
5827  if(dneq0(norm2(ro2qu(qu2ro(qu))-qu),1.0e-12_preal)) msg = trim(msg)//'ro2qu/qu2ro,'
5828  if(dneq0(norm2(ho2qu(qu2ho(qu))-qu),1.0e-7_preal)) msg = trim(msg)//'ho2qu/qu2ho,'
5829  if(dneq0(norm2(cu2qu(qu2cu(qu))-qu),1.0e-7_preal)) msg = trim(msg)//'cu2qu/qu2cu,'
5830 
5831 
5832  om = qu2om(qu)
5833 
5834  if(dneq0(norm2(om2qu(eu2om(om2eu(om)))-qu),1.0e-7_preal)) msg = trim(msg)//'eu2om/om2eu,'
5835  if(dneq0(norm2(om2qu(ax2om(om2ax(om)))-qu),1.0e-7_preal)) msg = trim(msg)//'ax2om/om2ax,'
5836  if(dneq0(norm2(om2qu(ro2om(om2ro(om)))-qu),1.0e-12_preal)) msg = trim(msg)//'ro2om/om2ro,'
5837  if(dneq0(norm2(om2qu(ho2om(om2ho(om)))-qu),1.0e-7_preal)) msg = trim(msg)//'ho2om/om2ho,'
5838  if(dneq0(norm2(om2qu(cu2om(om2cu(om)))-qu),1.0e-7_preal)) msg = trim(msg)//'cu2om/om2cu,'
5839 
5840 
5841  eu = qu2eu(qu)
5842 
5843  if(dneq0(norm2(eu2qu(ax2eu(eu2ax(eu)))-qu),1.0e-12_preal)) msg = trim(msg)//'ax2eu/eu2ax,'
5844  if(dneq0(norm2(eu2qu(ro2eu(eu2ro(eu)))-qu),1.0e-12_preal)) msg = trim(msg)//'ro2eu/eu2ro,'
5845  if(dneq0(norm2(eu2qu(ho2eu(eu2ho(eu)))-qu),1.0e-7_preal)) msg = trim(msg)//'ho2eu/eu2ho,'
5846  if(dneq0(norm2(eu2qu(cu2eu(eu2cu(eu)))-qu),1.0e-7_preal)) msg = trim(msg)//'cu2eu/eu2cu,'
5847 
5848 
5849  ax = qu2ax(qu)
5850 
5851  if(dneq0(norm2(ax2qu(ro2ax(ax2ro(ax)))-qu),1.0e-12_preal)) msg = trim(msg)//'ro2ax/ax2ro,'
5852  if(dneq0(norm2(ax2qu(ho2ax(ax2ho(ax)))-qu),1.0e-7_preal)) msg = trim(msg)//'ho2ax/ax2ho,'
5853  if(dneq0(norm2(ax2qu(cu2ax(ax2cu(ax)))-qu),1.0e-7_preal)) msg = trim(msg)//'cu2ax/ax2cu,'
5854 
5855 
5856  ro = qu2ro(qu)
5857 
5858  if(dneq0(norm2(ro2qu(ho2ro(ro2ho(ro)))-qu),1.0e-7_preal)) msg = trim(msg)//'ho2ro/ro2ho,'
5859  if(dneq0(norm2(ro2qu(cu2ro(ro2cu(ro)))-qu),1.0e-7_preal)) msg = trim(msg)//'cu2ro/ro2cu,'
5860 
5861 
5862  ho = qu2ho(qu)
5863 
5864  if(dneq0(norm2(ho2qu(cu2ho(ho2cu(ho)))-qu),1.0e-7_preal)) msg = trim(msg)//'cu2ho/ho2cu,'
5865 
5866 
5867  call r%fromMatrix(om)
5868 
5869  call random_number(v3)
5870  if(all(dneq(r%rotVector(r%rotVector(v3),active=.true.),v3,1.0e-12_preal))) &
5871  msg = trim(msg)//'rotVector,'
5872 
5873  call random_number(t33)
5874  if(all(dneq(r%rotTensor2(r%rotTensor2(t33),active=.true.),t33,1.0e-12_preal))) &
5875  msg = trim(msg)//'rotTensor2,'
5876 
5877  call random_number(t3333)
5878  if(all(dneq(r%rotTensor4(r%rotTensor4(t3333),active=.true.),t3333,1.0e-12_preal))) &
5879  msg = trim(msg)//'rotTensor4,'
5880 
5881  if(len_trim(msg) /= 0) call io_error(0,ext_msg=msg)
5882 
5883  enddo
5884 
5885 end subroutine unittest
5886 
5887 
5888 end module rotations
5889 # 16 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
5890 
5891 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/FEsolving.f90" 1
5892 !--------------------------------------------------------------------------------------------------
5896 !--------------------------------------------------------------------------------------------------
5898 
5899  implicit none
5900  public
5901 
5902  logical :: &
5903  terminallyill = .false.
5904 
5905  integer, dimension(2) :: &
5906  fesolving_execelem, & !< for ping-pong scheme always whole range, otherwise one specific element
5908 
5909 
5910  logical, dimension(:,:), allocatable :: &
5911  calcmode
5912 
5913 
5914 end module fesolving
5915 # 17 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
5916 
5917 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/element.f90" 1
5918 !--------------------------------------------------------------------------------------------------
5921 !--------------------------------------------------------------------------------------------------
5922 module element
5923  use io
5924 
5925  implicit none
5926  private
5927 
5928 !---------------------------------------------------------------------------------------------------
5930 !---------------------------------------------------------------------------------------------------
5931  type, public :: telement
5932  integer :: &
5933  elemtype, &
5934  geomtype, & !< geometry type (same for same dimension and same number of integration points)
5935  celltype, &
5936  nnodes, &
5937  ncellnodes, &
5938  ncellnodespercell, &
5939  nips, &
5940  nipneighbors
5941  character(len=:), allocatable :: &
5942  vtktype
5943  integer, dimension(:,:), allocatable :: &
5944  cell, & !< intra-element (cell) nodes that constitute a cell
5945  ipneighbor, &
5946  cellface
5947  integer, dimension(:,:), allocatable :: &
5948  ! center of gravity of the weighted nodes gives the position of the cell node.
5949  ! example: face-centered cell node with face nodes 1,2,5,6 to be used in,
5950  ! e.g., an 8 node element, would be encoded: 1, 1, 0, 0, 1, 1, 0, 0
5951  cellnodeparentnodeweights
5952  contains
5953  procedure :: init => telement_init
5954  end type telement
5955 
5956 
5957  integer, parameter :: &
5958  nelemtype = 13
5959 
5960  integer, dimension(NELEMTYPE), parameter :: nnode = &
5961  [ &
5962  3, & ! 2D, 1 IP
5963  6, & ! 2D, 3 IP
5964  4, & ! 2D, 4 IP
5965  8, & ! 2D, 9 IP
5966  8, & ! 2D, 4 IP
5967  !----------------------
5968  4, & ! 3D, 1 IP
5969  5, & ! 3D, 4 IP
5970  10, & ! 3D, 4 IP
5971  6, & ! 3D, 6 IP
5972  8, & ! 3D, 1 IP
5973  8, & ! 3D, 8 IP
5974  20, & ! 3D, 8 IP
5975  20 & ! 3D, 27 IP
5976  ]
5977 
5978  integer, dimension(NELEMTYPE), parameter :: geomtype = &
5979  [ &
5980  1, & ! 1 triangle
5981  2, & ! 3 quadrilaterals
5982  3, & ! 4 quadrilaterals
5983  4, & ! 9 quadrilaterals
5984  3, & ! 4 quadrilaterals
5985  !----------------------
5986  5, & ! 1 tetrahedron
5987  6, & ! 4 hexahedrons
5988  6, & ! 4 hexahedrons
5989  7, & ! 6 hexahedrons
5990  8, & ! 1 hexahedron
5991  9, & ! 8 hexahedrons
5992  9, & ! 8 hexahedrons
5993  10 & ! 27 hexahedrons
5994  ]
5995 
5996  integer, dimension(maxval(GEOMTYPE)), parameter :: ncellnode = &
5997  [ &
5998  3, &
5999  7, &
6000  9, &
6001  16, &
6002  4, &
6003  15, &
6004  21, &
6005  8, &
6006  27, &
6007  64 &
6008  ]
6009 
6010  integer, dimension(maxval(GEOMTYPE)), parameter :: nip = &
6011  [ &
6012  1, &
6013  3, &
6014  4, &
6015  9, &
6016  1, &
6017  4, &
6018  6, &
6019  1, &
6020  8, &
6021  27 &
6022  ]
6023 
6024  integer, dimension(maxval(GEOMTYPE)), parameter :: celltype = &
6025  [ &
6026  1, & ! 2D, 3 node (Triangle)
6027  2, & ! 2D, 4 node (Quadrilateral)
6028  2, & ! - " -
6029  2, & ! - " -
6030  3, & ! 3D, 4 node (Tetrahedron)
6031  4, & ! 3D, 4 node (Hexahedron)
6032  4, & ! - " -
6033  4, & ! - " -
6034  4, & ! - " -
6035  4 & ! - " -
6036  ]
6037 
6038  integer, dimension(maxval(CELLTYPE)), parameter :: nipneighbor = &
6039  [ &
6040  3, &
6041  4, &
6042  4, &
6043  6 &
6044  ]
6045 
6046  integer, dimension(maxval(CELLTYPE)), parameter :: ncellnodepercellface = &
6047  [ &
6048  2, &
6049  2, &
6050  3, &
6051  4 &
6052  ]
6053 
6054  integer, dimension(maxval(CELLTYPE)), parameter :: ncellnodepercell = &
6055  [ &
6056  3, &
6057  4, &
6058  4, &
6059  8 &
6060  ]
6061 
6062  ! *** IPneighbor ***
6063  ! list of the neighborhood of each IP.
6064  ! It is sorted in (local) +x,-x, +y,-y, +z,-z direction.
6065  ! Positive integers denote an intra-element IP identifier.
6066  ! Negative integers denote the interface behind which the neighboring (extra-element) IP will be located.
6067 
6068  integer, dimension(NIPNEIGHBOR(CELLTYPE(1)),NIP(1)), parameter :: ipneighbor1 = &
6069  reshape([&
6070  -2,-3,-1 &
6071 
6072 
6073 
6074  ],[nipneighbor(celltype(1)),nip(1)])
6075 
6076 
6077  integer, dimension(NIPNEIGHBOR(CELLTYPE(2)),NIP(2)), parameter :: ipneighbor2 = &
6078  reshape([&
6079  2,-3, 3,-1, &
6080  -2, 1, 3,-1, &
6081  2,-3,-2, 1 &
6082 
6083 
6084 
6085  ],[nipneighbor(celltype(2)),nip(2)])
6086 
6087 
6088  integer, dimension(NIPNEIGHBOR(CELLTYPE(3)),NIP(3)), parameter :: ipneighbor3 = &
6089  reshape([&
6090  2,-4, 3,-1, &
6091  -2, 1, 4,-1, &
6092  4,-4,-3, 1, &
6093  -2, 3,-3, 2 &
6094 
6095 
6096 
6097  ],[nipneighbor(celltype(3)),nip(3)])
6098 
6099 
6100  integer, dimension(NIPNEIGHBOR(CELLTYPE(4)),NIP(4)), parameter :: ipneighbor4 = &
6101  reshape([&
6102  2,-4, 4,-1, &
6103  3, 1, 5,-1, &
6104  -2, 2, 6,-1, &
6105  5,-4, 7, 1, &
6106  6, 4, 8, 2, &
6107  -2, 5, 9, 3, &
6108  8,-4,-3, 4, &
6109  9, 7,-3, 5, &
6110  -2, 8,-3, 6 &
6111 
6112 
6113 
6114  ],[nipneighbor(celltype(4)),nip(4)])
6115 
6116 
6117  integer, dimension(NIPNEIGHBOR(CELLTYPE(5)),NIP(5)), parameter :: ipneighbor5 = &
6118  reshape([&
6119  -1,-2,-3,-4 &
6120 
6121 
6122 
6123  ],[nipneighbor(celltype(5)),nip(5)])
6124 
6125 
6126  integer, dimension(NIPNEIGHBOR(CELLTYPE(6)),NIP(6)), parameter :: ipneighbor6 = &
6127  reshape([&
6128  2,-4, 3,-2, 4,-1, &
6129  -2, 1, 3,-2, 4,-1, &
6130  2,-4,-3, 1, 4,-1, &
6131  2,-4, 3,-2,-3, 1 &
6132 
6133 
6134 
6135  ],[nipneighbor(celltype(6)),nip(6)])
6136 
6137 
6138  integer, dimension(NIPNEIGHBOR(CELLTYPE(7)),NIP(7)), parameter :: ipneighbor7 = &
6139  reshape([&
6140  2,-4, 3,-2, 4,-1, &
6141  -3, 1, 3,-2, 5,-1, &
6142  2,-4,-3, 1, 6,-1, &
6143  5,-4, 6,-2,-5, 1, &
6144  -3, 4, 6,-2,-5, 2, &
6145  5,-4,-3, 4,-5, 3 &
6146 
6147 
6148 
6149  ],[nipneighbor(celltype(7)),nip(7)])
6150 
6151 
6152  integer, dimension(NIPNEIGHBOR(CELLTYPE(8)),NIP(8)), parameter :: ipneighbor8 = &
6153  reshape([&
6154  -3,-5,-4,-2,-6,-1 &
6155 
6156 
6157 
6158  ],[nipneighbor(celltype(8)),nip(8)])
6159 
6160 
6161  integer, dimension(NIPNEIGHBOR(CELLTYPE(9)),NIP(9)), parameter :: ipneighbor9 = &
6162  reshape([&
6163  2,-5, 3,-2, 5,-1, &
6164  -3, 1, 4,-2, 6,-1, &
6165  4,-5,-4, 1, 7,-1, &
6166  -3, 3,-4, 2, 8,-1, &
6167  6,-5, 7,-2,-6, 1, &
6168  -3, 5, 8,-2,-6, 2, &
6169  8,-5,-4, 5,-6, 3, &
6170  -3, 7,-4, 6,-6, 4 &
6171 
6172 
6173 
6174  ],[nipneighbor(celltype(9)),nip(9)])
6175 
6176 
6177  integer, dimension(NIPNEIGHBOR(CELLTYPE(10)),NIP(10)), parameter :: ipneighbor10 = &
6178  reshape([&
6179  2,-5, 4,-2,10,-1, &
6180  3, 1, 5,-2,11,-1, &
6181  -3, 2, 6,-2,12,-1, &
6182  5,-5, 7, 1,13,-1, &
6183  6, 4, 8, 2,14,-1, &
6184  -3, 5, 9, 3,15,-1, &
6185  8,-5,-4, 4,16,-1, &
6186  9, 7,-4, 5,17,-1, &
6187  -3, 8,-4, 6,18,-1, &
6188  11,-5,13,-2,19, 1, &
6189  12,10,14,-2,20, 2, &
6190  -3,11,15,-2,21, 3, &
6191  14,-5,16,10,22, 4, &
6192  15,13,17,11,23, 5, &
6193  -3,14,18,12,24, 6, &
6194  17,-5,-4,13,25, 7, &
6195  18,16,-4,14,26, 8, &
6196  -3,17,-4,15,27, 9, &
6197  20,-5,22,-2,-6,10, &
6198  21,19,23,-2,-6,11, &
6199  -3,20,24,-2,-6,12, &
6200  23,-5,25,19,-6,13, &
6201  24,22,26,20,-6,14, &
6202  -3,23,27,21,-6,15, &
6203  26,-5,-4,22,-6,16, &
6204  27,25,-4,23,-6,17, &
6205  -3,26,-4,24,-6,18 &
6206 
6207 
6208 
6209  ],[nipneighbor(celltype(10)),nip(10)])
6210 
6211 
6212 
6213  integer, dimension(NNODE(1),NCELLNODE(GEOMTYPE(1))), parameter :: cellnodeparentnodeweights1 = &
6214  reshape([&
6215  1, 0, 0, &
6216  0, 1, 0, &
6217  0, 0, 1 &
6218 
6219 
6220 
6221  ],[nnode(1),ncellnode(geomtype(1))])
6222 
6223 
6224  integer, dimension(NNODE(2),NCELLNODE(GEOMTYPE(2))), parameter :: cellnodeparentnodeweights2 = &
6225  reshape([&
6226  1, 0, 0, 0, 0, 0, &
6227  0, 1, 0, 0, 0, 0, &
6228  0, 0, 1, 0, 0, 0, &
6229  0, 0, 0, 1, 0, 0, &
6230  0, 0, 0, 0, 1, 0, &
6231  0, 0, 0, 0, 0, 1, &
6232  1, 1, 1, 2, 2, 2 &
6233 
6234 
6235 
6236  ],[nnode(2),ncellnode(geomtype(2))])
6237 
6238 
6239  integer, dimension(NNODE(3),NCELLNODE(GEOMTYPE(3))), parameter :: cellnodeparentnodeweights3 = &
6240  reshape([&
6241  1, 0, 0, 0, &
6242  0, 1, 0, 0, &
6243  0, 0, 1, 0, &
6244  0, 0, 0, 1, &
6245  1, 1, 0, 0, &
6246  0, 1, 1, 0, &
6247  0, 0, 1, 1, &
6248  1, 0, 0, 1, &
6249  1, 1, 1, 1 &
6250 
6251 
6252 
6253  ],[nnode(3),ncellnode(geomtype(3))])
6254 
6255 
6256  integer, dimension(NNODE(4),NCELLNODE(GEOMTYPE(4))), parameter :: cellnodeparentnodeweights4 = &
6257  reshape([&
6258  1, 0, 0, 0, 0, 0, 0, 0, &
6259  0, 1, 0, 0, 0, 0, 0, 0, &
6260  0, 0, 1, 0, 0, 0, 0, 0, &
6261  0, 0, 0, 1, 0, 0, 0, 0, &
6262  1, 0, 0, 0, 2, 0, 0, 0, &
6263  0, 1, 0, 0, 2, 0, 0, 0, &
6264  0, 1, 0, 0, 0, 2, 0, 0, &
6265  0, 0, 1, 0, 0, 2, 0, 0, &
6266  0, 0, 1, 0, 0, 0, 2, 0, &
6267  0, 0, 0, 1, 0, 0, 2, 0, &
6268  0, 0, 0, 1, 0, 0, 0, 2, &
6269  1, 0, 0, 0, 0, 0, 0, 2, &
6270  4, 1, 1, 1, 8, 2, 2, 8, &
6271  1, 4, 1, 1, 8, 8, 2, 2, &
6272  1, 1, 4, 1, 2, 8, 8, 2, &
6273  1, 1, 1, 4, 2, 2, 8, 8 &
6274 
6275 
6276 
6277  ],[nnode(4),ncellnode(geomtype(4))])
6278 
6279 
6280  integer, dimension(NNODE(5),NCELLNODE(GEOMTYPE(5))), parameter :: cellnodeparentnodeweights5 = &
6281  reshape([&
6282  1, 0, 0, 0, 0, 0, 0, 0, &
6283  0, 1, 0, 0, 0, 0, 0, 0, &
6284  0, 0, 1, 0, 0, 0, 0, 0, &
6285  0, 0, 0, 1, 0, 0, 0, 0, &
6286  0, 0, 0, 0, 1, 0, 0, 0, &
6287  0, 0, 0, 0, 0, 1, 0, 0, &
6288  0, 0, 0, 0, 0, 0, 1, 0, &
6289  0, 0, 0, 0, 0, 0, 0, 1, &
6290  1, 1, 1, 1, 2, 2, 2, 2 &
6291 
6292 
6293 
6294  ],[nnode(5),ncellnode(geomtype(5))])
6295 
6296 
6297  integer, dimension(NNODE(6),NcellNode(GEOMTYPE(6))), parameter :: cellnodeparentnodeweights6 = &
6298  reshape([&
6299  1, 0, 0, 0, &
6300  0, 1, 0, 0, &
6301  0, 0, 1, 0, &
6302  0, 0, 0, 1 &
6303 
6304 
6305 
6306  ],[nnode(6),ncellnode(geomtype(6))])
6307 
6308 
6309  integer, dimension(NNODE(7),NCELLNODE(GEOMTYPE(7))), parameter :: cellnodeparentnodeweights7 = &
6310  reshape([&
6311  1, 0, 0, 0, 0, &
6312  0, 1, 0, 0, 0, &
6313  0, 0, 1, 0, 0, &
6314  0, 0, 0, 1, 0, &
6315  1, 1, 0, 0, 0, &
6316  0, 1, 1, 0, 0, &
6317  1, 0, 1, 0, 0, &
6318  1, 0, 0, 1, 0, &
6319  0, 1, 0, 1, 0, &
6320  0, 0, 1, 1, 0, &
6321  1, 1, 1, 0, 0, &
6322  1, 1, 0, 1, 0, &
6323  0, 1, 1, 1, 0, &
6324  1, 0, 1, 1, 0, &
6325  0, 0, 0, 0, 1 &
6326 
6327 
6328 
6329  ],[nnode(7),ncellnode(geomtype(7))])
6330 
6331 
6332  integer, dimension(NNODE(8),NCELLNODE(GEOMTYPE(8))), parameter :: cellnodeparentnodeweights8 = &
6333  reshape([&
6334  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, &
6335  0, 1, 0, 0, 0, 0, 0, 0, 0, 0, &
6336  0, 0, 1, 0, 0, 0, 0, 0, 0, 0, &
6337  0, 0, 0, 1, 0, 0, 0, 0, 0, 0, &
6338  0, 0, 0, 0, 1, 0, 0, 0, 0, 0, &
6339  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, &
6340  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, &
6341  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, &
6342  0, 0, 0, 0, 0, 0, 0, 0, 1, 0, &
6343  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, &
6344  1, 1, 1, 0, 2, 2, 2, 0, 0, 0, &
6345  1, 1, 0, 1, 2, 0, 0, 2, 2, 0, &
6346  0, 1, 1, 1, 0, 2, 0, 0, 2, 2, &
6347  1, 0, 1, 1, 0, 0, 2, 2, 0, 2, &
6348  3, 3, 3, 3, 4, 4, 4, 4, 4, 4 &
6349 
6350 
6351 
6352  ],[nnode(8),ncellnode(geomtype(8))])
6353 
6354 
6355  integer, dimension(NNODE(9),NCELLNODE(GEOMTYPE(9))), parameter :: cellnodeparentnodeweights9 = &
6356  reshape([&
6357  1, 0, 0, 0, 0, 0, &
6358  0, 1, 0, 0, 0, 0, &
6359  0, 0, 1, 0, 0, 0, &
6360  0, 0, 0, 1, 0, 0, &
6361  0, 0, 0, 0, 1, 0, &
6362  0, 0, 0, 0, 0, 1, &
6363  1, 1, 0, 0, 0, 0, &
6364  0, 1, 1, 0, 0, 0, &
6365  1, 0, 1, 0, 0, 0, &
6366  1, 0, 0, 1, 0, 0, &
6367  0, 1, 0, 0, 1, 0, &
6368  0, 0, 1, 0, 0, 1, &
6369  0, 0, 0, 1, 1, 0, &
6370  0, 0, 0, 0, 1, 1, &
6371  0, 0, 0, 1, 0, 1, &
6372  1, 1, 1, 0, 0, 0, &
6373  1, 1, 0, 1, 1, 0, &
6374  0, 1, 1, 0, 1, 1, &
6375  1, 0, 1, 1, 0, 1, &
6376  0, 0, 0, 1, 1, 1, &
6377  1, 1, 1, 1, 1, 1 &
6378 
6379 
6380 
6381  ],[nnode(9),ncellnode(geomtype(9))])
6382 
6383 
6384  integer, dimension(NNODE(10),NCELLNODE(GEOMTYPE(10))), parameter :: cellnodeparentnodeweights10 = &
6385  reshape([&
6386  1, 0, 0, 0, 0, 0, 0, 0, &
6387  0, 1, 0, 0, 0, 0, 0, 0, &
6388  0, 0, 1, 0, 0, 0, 0, 0, &
6389  0, 0, 0, 1, 0, 0, 0, 0, &
6390  0, 0, 0, 0, 1, 0, 0, 0, &
6391  0, 0, 0, 0, 0, 1, 0, 0, &
6392  0, 0, 0, 0, 0, 0, 1, 0, &
6393  0, 0, 0, 0, 0, 0, 0, 1 &
6394 
6395 
6396 
6397  ],[nnode(10),ncellnode(geomtype(10))])
6398 
6399 
6400  integer, dimension(NNODE(11),NCELLNODE(GEOMTYPE(11))), parameter :: cellnodeparentnodeweights11 = &
6401  reshape([&
6402  1, 0, 0, 0, 0, 0, 0, 0, & !
6403  0, 1, 0, 0, 0, 0, 0, 0, & !
6404  0, 0, 1, 0, 0, 0, 0, 0, & !
6405  0, 0, 0, 1, 0, 0, 0, 0, & !
6406  0, 0, 0, 0, 1, 0, 0, 0, & ! 5
6407  0, 0, 0, 0, 0, 1, 0, 0, & !
6408  0, 0, 0, 0, 0, 0, 1, 0, & !
6409  0, 0, 0, 0, 0, 0, 0, 1, & !
6410  1, 1, 0, 0, 0, 0, 0, 0, & !
6411  0, 1, 1, 0, 0, 0, 0, 0, & ! 10
6412  0, 0, 1, 1, 0, 0, 0, 0, & !
6413  1, 0, 0, 1, 0, 0, 0, 0, & !
6414  0, 0, 0, 0, 1, 1, 0, 0, & !
6415  0, 0, 0, 0, 0, 1, 1, 0, & !
6416  0, 0, 0, 0, 0, 0, 1, 1, & ! 15
6417  0, 0, 0, 0, 1, 0, 0, 1, & !
6418  1, 0, 0, 0, 1, 0, 0, 0, & !
6419  0, 1, 0, 0, 0, 1, 0, 0, & !
6420  0, 0, 1, 0, 0, 0, 1, 0, & !
6421  0, 0, 0, 1, 0, 0, 0, 1, & ! 20
6422  1, 1, 1, 1, 0, 0, 0, 0, & !
6423  1, 1, 0, 0, 1, 1, 0, 0, & !
6424  0, 1, 1, 0, 0, 1, 1, 0, & !
6425  0, 0, 1, 1, 0, 0, 1, 1, & !
6426  1, 0, 0, 1, 1, 0, 0, 1, & ! 25
6427  0, 0, 0, 0, 1, 1, 1, 1, & !
6428  1, 1, 1, 1, 1, 1, 1, 1 & !
6429 
6430 
6431 
6432  ],[nnode(11),ncellnode(geomtype(11))])
6433 
6434 
6435  integer, dimension(NNODE(12),NCELLNODE(GEOMTYPE(12))), parameter :: cellnodeparentnodeweights12 = &
6436  reshape([&
6437  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6438  0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6439  0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6440  0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6441  0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & ! 5
6442  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6443  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6444  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6445  0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6446  0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & ! 10
6447  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6448  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, & !
6449  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, & !
6450  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, & !
6451  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, & ! 15
6452  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, & !
6453  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, & !
6454  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, & !
6455  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, & !
6456  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, & ! 20
6457  1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, & !
6458  1, 1, 0, 0, 1, 1, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, & !
6459  0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 2, 0, & !
6460  0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 2, & !
6461  1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 2, & ! 25
6462  0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, & !
6463  3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 & !
6464 
6465 
6466 
6467  ],[nnode(12),ncellnode(geomtype(12))])
6468 
6469 
6470  integer, dimension(NNODE(13),NCELLNODE(GEOMTYPE(13))), parameter :: cellnodeparentnodeweights13 = &
6471  reshape([&
6472  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6473  0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6474  0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6475  0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6476  0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & ! 5
6477  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6478  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6479  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6480  1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6481  0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & ! 10
6482  0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6483  0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6484  0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6485  0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, & !
6486  0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, & ! 15
6487  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, & !
6488  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, & !
6489  0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, & !
6490  0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, & !
6491  0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, & ! 20
6492  0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, & !
6493  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, & !
6494  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, & !
6495  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, & !
6496  0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, & ! 25
6497  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, & !
6498  0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, & !
6499  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, & !
6500  0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, & !
6501  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, & ! 30
6502  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, & !
6503  0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, & !
6504  4, 1, 1, 1, 0, 0, 0, 0, 8, 2, 2, 8, 0, 0, 0, 0, 0, 0, 0, 0, & !
6505  1, 4, 1, 1, 0, 0, 0, 0, 8, 8, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, & !
6506  1, 1, 4, 1, 0, 0, 0, 0, 2, 8, 8, 2, 0, 0, 0, 0, 0, 0, 0, 0, & ! 35
6507  1, 1, 1, 4, 0, 0, 0, 0, 2, 2, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, & !
6508  4, 1, 0, 0, 1, 1, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 8, 2, 0, 0, & !
6509  1, 4, 0, 0, 1, 1, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 2, 8, 0, 0, & !
6510  0, 4, 1, 0, 0, 1, 1, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 8, 2, 0, & !
6511  0, 1, 4, 0, 0, 1, 1, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 2, 8, 0, & ! 40
6512  0, 0, 4, 1, 0, 0, 1, 1, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 8, 2, & !
6513  0, 0, 1, 4, 0, 0, 1, 1, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 2, 8, & !
6514  1, 0, 0, 4, 1, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 2, 2, 0, 0, 8, & !
6515  4, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 2, 8, 0, 0, 2, & !
6516  1, 1, 0, 0, 4, 1, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, 0, & ! 45
6517  1, 1, 0, 0, 1, 4, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 2, 8, 0, 0, & !
6518  0, 1, 1, 0, 0, 4, 1, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 2, 0, & !
6519  0, 1, 1, 0, 0, 1, 4, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 2, 8, 0, & !
6520  0, 0, 1, 1, 0, 0, 4, 1, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 8, 2, & !
6521  0, 0, 1, 1, 0, 0, 1, 4, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 2, 8, & ! 50
6522  1, 0, 0, 1, 1, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 8, 2, 0, 0, 8, & !
6523  1, 0, 0, 1, 4, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 8, 8, 0, 0, 2, & !
6524  0, 0, 0, 0, 4, 1, 1, 1, 0, 0, 0, 0, 8, 2, 2, 8, 0, 0, 0, 0, & !
6525  0, 0, 0, 0, 1, 4, 1, 1, 0, 0, 0, 0, 8, 8, 2, 2, 0, 0, 0, 0, & !
6526  0, 0, 0, 0, 1, 1, 4, 1, 0, 0, 0, 0, 2, 8, 8, 2, 0, 0, 0, 0, & ! 55
6527  0, 0, 0, 0, 1, 1, 1, 4, 0, 0, 0, 0, 2, 2, 8, 8, 0, 0, 0, 0, & !
6528  24, 8, 4, 8, 8, 4, 3, 4, 32,12,12,32, 12, 4, 4,12, 32,12, 4,12, & !
6529  8,24, 8, 4, 4, 8, 4, 3, 32,32,12,12, 12,12, 4, 4, 12,32,12, 4, & !
6530  4, 8,24, 8, 3, 4, 8, 4, 12,32,32,12, 4,12,12, 4, 4,12,32,12, & !
6531  8, 4, 8,24, 4, 3, 4, 8, 12,12,32,32, 4, 4,12,12, 12, 4,12,32, & ! 60
6532  8, 4, 3, 4, 24, 8, 4, 8, 12, 4, 4,12, 32,12,12,32, 32,12, 4,12, & !
6533  4, 8, 4, 3, 8,24, 8, 4, 12,12, 4, 4, 32,32,12,12, 12,32,12, 4, & !
6534  3, 4, 8, 4, 4, 8,24, 8, 4,12,12, 4, 12,32,32,12, 4,12,32,12, & !
6535  4, 3, 4, 8, 8, 4, 8,24, 4, 4,12,12, 12,12,32,32, 12, 4,12,32 & !
6536 
6537 
6538 
6539  ],[nnode(13),ncellnode(geomtype(13))])
6540 
6541 
6542 
6543  integer, dimension(NCELLNODEPERCELL(CELLTYPE(1)),NIP(1)), parameter :: cell1 = &
6544  reshape([&
6545  1,2,3 &
6546 
6547 
6548 
6549  ],[ncellnodepercell(celltype(1)),nip(1)])
6550 
6551 
6552  integer, dimension(NCELLNODEPERCELL(CELLTYPE(2)),NIP(2)), parameter :: cell2 = &
6553  reshape([&
6554  1, 4, 7, 6, &
6555  2, 5, 7, 4, &
6556  3, 6, 7, 5 &
6557 
6558 
6559 
6560  ],[ncellnodepercell(celltype(2)),nip(2)])
6561 
6562 
6563  integer, dimension(NCELLNODEPERCELL(CELLTYPE(3)),NIP(3)), parameter :: cell3 = &
6564  reshape([&
6565  1, 5, 9, 8, &
6566  5, 2, 6, 9, &
6567  8, 9, 7, 4, &
6568  9, 6, 3, 7 &
6569 
6570 
6571 
6572  ],[ncellnodepercell(celltype(3)),nip(3)])
6573 
6574 
6575  integer, dimension(NCELLNODEPERCELL(CELLTYPE(4)),NIP(4)), parameter :: cell4 = &
6576  reshape([&
6577  1, 5,13,12, &
6578  5, 6,14,13, &
6579  6, 2, 7,14, &
6580  12,13,16,11, &
6581  13,14,15,16, &
6582  14, 7, 8,15, &
6583  11,16,10, 4, &
6584  16,15, 9,10, &
6585  15, 8, 3, 9 &
6586 
6587 
6588 
6589  ],[ncellnodepercell(celltype(4)),nip(4)])
6590 
6591 
6592  integer, dimension(NCELLNODEPERCELL(CELLTYPE(5)),NIP(5)), parameter :: cell5 = &
6593  reshape([&
6594  1, 2, 3, 4 &
6595 
6596 
6597 
6598  ],[ncellnodepercell(celltype(5)),nip(5)])
6599 
6600 
6601  integer, dimension(NCELLNODEPERCELL(CELLTYPE(6)),NIP(6)), parameter :: cell6 = &
6602  reshape([&
6603  1, 5,11, 7, 8,12,15,14, &
6604  5, 2, 6,11,12, 9,13,15, &
6605  7,11, 6, 3,14,15,13,10, &
6606  8,12,15, 4, 4, 9,13,10 &
6607 
6608 
6609 
6610  ],[ncellnodepercell(celltype(6)),nip(6)])
6611 
6612 
6613  integer, dimension(NCELLNODEPERCELL(CELLTYPE(7)),NIP(7)), parameter :: cell7 = &
6614  reshape([&
6615  1, 7,16, 9,10,17,21,19, &
6616  7, 2, 8,16,17,11,18,21, &
6617  9,16, 8, 3,19,21,18,12, &
6618  10,17,21,19, 4,13,20,15, &
6619  17,11,18,21,13, 5,14,20, &
6620  19,21,18,12,15,20,14, 6 &
6621 
6622 
6623 
6624  ],[ncellnodepercell(celltype(7)),nip(7)])
6625 
6626 
6627  integer, dimension(NCELLNODEPERCELL(CELLTYPE(8)),NIP(8)), parameter :: cell8 = &
6628  reshape([&
6629  1, 2, 3, 4, 5, 6, 7, 8 &
6630 
6631 
6632 
6633  ],[ncellnodepercell(celltype(8)),nip(8)])
6634 
6635 
6636  integer, dimension(NCELLNODEPERCELL(CELLTYPE(9)),NIP(9)), parameter :: cell9 = &
6637  reshape([&
6638  1, 9,21,12,17,22,27,25, &
6639  9, 2,10,21,22,18,23,27, &
6640  12,21,11, 4,25,27,24,20, &
6641  21,10, 3,11,27,23,19,24, &
6642  17,22,27,25, 5,13,26,16, &
6643  22,18,23,27,13, 6,14,26, &
6644  25,27,24,20,16,26,15, 8, &
6645  27,23,19,24,26,14, 7,15 &
6646 
6647 
6648 
6649  ],[ncellnodepercell(celltype(9)),nip(9)])
6650 
6651 
6652  integer, dimension(NCELLNODEPERCELL(CELLTYPE(10)),NIP(10)), parameter :: cell10 = &
6653  reshape([&
6654  1, 9,33,16,17,37,57,44, &
6655  9,10,34,33,37,38,58,57, &
6656  10, 2,11,34,38,18,39,58, &
6657  16,33,36,15,44,57,60,43, &
6658  33,34,35,36,57,58,59,60, &
6659  34,11,12,35,58,39,40,59, &
6660  15,36,14, 4,43,60,42,20, &
6661  36,35,13,14,60,59,41,42, &
6662  35,12, 3,13,59,40,19,41, &
6663  17,37,57,44,21,45,61,52, &
6664  37,38,58,57,45,46,62,61, &
6665  38,18,39,58,46,22,47,62, &
6666  44,57,60,43,52,61,64,51, &
6667  57,58,59,60,61,62,63,64, &
6668  58,39,40,59,62,47,48,63, &
6669  43,60,42,20,51,64,50,24, &
6670  60,59,41,42,64,63,49,50, &
6671  59,40,19,41,63,48,23,49, &
6672  21,45,61,52, 5,25,53,32, &
6673  45,46,62,61,25,26,54,53, &
6674  46,22,47,62,26, 6,27,54, &
6675  52,61,64,51,32,53,56,31, &
6676  61,62,63,64,53,54,55,56, &
6677  62,47,48,63,54,27,28,55, &
6678  51,64,50,24,31,56,30, 8, &
6679  64,63,49,50,56,55,29,30, &
6680  63,48,23,49,55,28, 7,29 &
6681 
6682 
6683 
6684  ],[ncellnodepercell(celltype(10)),nip(10)])
6685 
6686 
6687 
6688  integer, dimension(NCELLNODEPERCELLFACE(1),NIPNEIGHBOR(1)), parameter :: cellface1 = &
6689  reshape([&
6690  2,3, &
6691  3,1, &
6692  1,2 &
6693 
6694 
6695 
6697 
6698 
6699  integer, dimension(NCELLNODEPERCELLFACE(2),NIPNEIGHBOR(2)), parameter :: cellface2 = &
6700  reshape([&
6701  2,3, &
6702  4,1, &
6703  3,4, &
6704  1,2 &
6705 
6706 
6707 
6709 
6710 
6711  integer, dimension(NCELLNODEPERCELLFACE(3),NIPNEIGHBOR(3)), parameter :: cellface3 = &
6712  reshape([&
6713  1,3,2, &
6714  1,2,4, &
6715  2,3,4, &
6716  1,4,3 &
6717 
6718 
6719 
6721 
6722 
6723  integer, dimension(NCELLNODEPERCELLFACE(4),NIPNEIGHBOR(4)), parameter :: cellface4 = &
6724  reshape([&
6725  2,3,7,6, &
6726  4,1,5,8, &
6727  3,4,8,7, &
6728  1,2,6,5, &
6729  5,6,7,8, &
6730  1,4,3,2 &
6731 
6732 
6733 
6735 
6736 
6737 
6738 contains
6739 
6740 
6741 !---------------------------------------------------------------------------------------------------
6743 !---------------------------------------------------------------------------------------------------
6744 subroutine telement_init(self,elemType)
6746  class(telement) :: self
6747  integer, intent(in) :: elemType
6748 
6749  self%elemType = elemtype
6750 
6751  self%Nnodes = nnode(self%elemType)
6752  self%geomType = geomtype(self%elemType)
6753 
6754  select case (self%elemType)
6755  case(1)
6756  self%cellNodeParentNodeWeights = cellnodeparentnodeweights1
6757  case(2)
6758  self%cellNodeParentNodeWeights = cellnodeparentnodeweights2
6759  case(3)
6760  self%cellNodeParentNodeWeights = cellnodeparentnodeweights3
6761  case(4)
6762  self%cellNodeParentNodeWeights = cellnodeparentnodeweights4
6763  case(5)
6764  self%cellNodeParentNodeWeights = cellnodeparentnodeweights5
6765  case(6)
6766  self%cellNodeParentNodeWeights = cellnodeparentnodeweights6
6767  case(7)
6768  self%cellNodeParentNodeWeights = cellnodeparentnodeweights7
6769  case(8)
6770  self%cellNodeParentNodeWeights = cellnodeparentnodeweights8
6771  case(9)
6772  self%cellNodeParentNodeWeights = cellnodeparentnodeweights9
6773  case(10)
6774  self%cellNodeParentNodeWeights = cellnodeparentnodeweights10
6775  case(11)
6776  self%cellNodeParentNodeWeights = cellnodeparentnodeweights11
6777  case(12)
6778  self%cellNodeParentNodeWeights = cellnodeparentnodeweights12
6779  case(13)
6780  self%cellNodeParentNodeWeights = cellnodeparentnodeweights13
6781  case default
6782  call io_error(0,ext_msg='invalid element type')
6783  end select
6784 
6785 
6786  self%NcellNodes = ncellnode(self%geomType)
6787  self%nIPs = nip(self%geomType)
6788  self%cellType = celltype(self%geomType)
6789 
6790  select case (self%geomType)
6791  case(1)
6792  self%IPneighbor = ipneighbor1
6793  self%cell = cell1
6794  case(2)
6795  self%IPneighbor = ipneighbor2
6796  self%cell = cell2
6797  case(3)
6798  self%IPneighbor = ipneighbor3
6799  self%cell = cell3
6800  case(4)
6801  self%IPneighbor = ipneighbor4
6802  self%cell = cell4
6803  case(5)
6804  self%IPneighbor = ipneighbor5
6805  self%cell = cell5
6806  case(6)
6807  self%IPneighbor = ipneighbor6
6808  self%cell = cell6
6809  case(7)
6810  self%IPneighbor = ipneighbor7
6811  self%cell = cell7
6812  case(8)
6813  self%IPneighbor = ipneighbor8
6814  self%cell = cell8
6815  case(9)
6816  self%IPneighbor = ipneighbor9
6817  self%cell = cell9
6818  case(10)
6819  self%IPneighbor = ipneighbor10
6820  self%cell = cell10
6821  end select
6822 
6823  self%NcellnodesPerCell = ncellnodepercell(self%cellType)
6824 
6825  select case(self%cellType)
6826  case(1)
6827  self%cellFace = cellface1
6828  self%vtkType = 'TRIANGLE'
6829  case(2)
6830  self%cellFace = cellface2
6831  self%vtkType = 'QUAD'
6832  case(3)
6833  self%cellFace = cellface3
6834  self%vtkType = 'TETRA'
6835  case(4)
6836  self%cellFace = cellface4
6837  self%vtkType = 'HEXAHEDRON'
6838  end select
6839 
6840  self%nIPneighbors = size(self%IPneighbor,1)
6841 
6842  write(6,'(/,a)') ' <<<+- element_init -+>>>'; flush(6)
6843 
6844  write(6,*) ' element type: ',self%elemType
6845  write(6,*) ' geom type: ',self%geomType
6846  write(6,*) ' cell type: ',self%cellType
6847  write(6,*) ' # node: ',self%Nnodes
6848  write(6,*) ' # IP: ',self%nIPs
6849  write(6,*) ' # cellnode: ',self%Ncellnodes
6850  write(6,*) ' # cellnode/cell: ',self%NcellnodesPerCell
6851  write(6,*) ' # IP neighbor: ',self%nIPneighbors
6852 
6853 end subroutine telement_init
6854 
6855 end module element
6856 # 18 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
6857 
6858 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/HDF5_utilities.f90" 1
6859 !--------------------------------------------------------------------------------------------------
6864 !--------------------------------------------------------------------------------------------------
6866  use hdf5
6867 
6868 
6869 
6870 
6871  use prec
6872  use io
6873  use rotations
6874  use numerics
6875 
6876  implicit none
6877  public
6878 
6879 !--------------------------------------------------------------------------------------------------
6882 !--------------------------------------------------------------------------------------------------
6883  interface hdf5_read
6884  module procedure hdf5_read_real1
6885  module procedure hdf5_read_real2
6886  module procedure hdf5_read_real3
6887  module procedure hdf5_read_real4
6888  module procedure hdf5_read_real5
6889  module procedure hdf5_read_real6
6890  module procedure hdf5_read_real7
6891 
6892  module procedure hdf5_read_int1
6893  module procedure hdf5_read_int2
6894  module procedure hdf5_read_int3
6895  module procedure hdf5_read_int4
6896  module procedure hdf5_read_int5
6897  module procedure hdf5_read_int6
6898  module procedure hdf5_read_int7
6899 
6900  end interface hdf5_read
6901 
6902 !--------------------------------------------------------------------------------------------------
6905 !--------------------------------------------------------------------------------------------------
6906  interface hdf5_write
6907  module procedure hdf5_write_real1
6908  module procedure hdf5_write_real2
6909  module procedure hdf5_write_real3
6910  module procedure hdf5_write_real4
6911  module procedure hdf5_write_real5
6912  module procedure hdf5_write_real6
6913  module procedure hdf5_write_real7
6914 
6915  module procedure hdf5_write_int1
6916  module procedure hdf5_write_int2
6917  module procedure hdf5_write_int3
6918  module procedure hdf5_write_int4
6919  module procedure hdf5_write_int5
6920  module procedure hdf5_write_int6
6921  module procedure hdf5_write_int7
6922 
6923  module procedure hdf5_write_rotation
6924 
6925  end interface hdf5_write
6926 
6927 !--------------------------------------------------------------------------------------------------
6929 !--------------------------------------------------------------------------------------------------
6931  module procedure hdf5_addattribute_str
6932  module procedure hdf5_addattribute_int
6933  module procedure hdf5_addattribute_real
6934  module procedure hdf5_addattribute_int_array
6935  module procedure hdf5_addattribute_real_array
6936  end interface hdf5_addattribute
6937 
6938 contains
6939 
6940 
6941 !--------------------------------------------------------------------------------------------------
6943 !--------------------------------------------------------------------------------------------------
6944 subroutine hdf5_utilities_init
6946  integer :: hdferr
6947  integer(SIZE_T) :: typeSize
6948 
6949  write(6,'(/,a)') ' <<<+- HDF5_Utilities init -+>>>'
6950 
6951 !--------------------------------------------------------------------------------------------------
6952 !initialize HDF5 library and check if integer and float type size match
6953  call h5open_f(hdferr)
6954  if (hdferr < 0) call io_error(1,ext_msg='HDF5_Utilities_init: h5open_f')
6955 
6956  call h5tget_size_f(h5t_native_integer,typesize, hdferr)
6957  if (hdferr < 0) call io_error(1,ext_msg='HDF5_Utilities_init: h5tget_size_f (int)')
6958  if (int(bit_size(0),size_t)/=typesize*8) &
6959  call io_error(0,ext_msg='Default integer size does not match H5T_NATIVE_INTEGER')
6960 
6961  call h5tget_size_f(h5t_native_double,typesize, hdferr)
6962  if (hdferr < 0) call io_error(1,ext_msg='HDF5_Utilities_init: h5tget_size_f (double)')
6963  if (int(storage_size(0.0_preal),size_t)/=typesize*8) &
6964  call io_error(0,ext_msg='pReal does not match H5T_NATIVE_DOUBLE')
6965 
6966 end subroutine hdf5_utilities_init
6967 
6968 
6969 !--------------------------------------------------------------------------------------------------
6971 !--------------------------------------------------------------------------------------------------
6972 integer(HID_T) function hdf5_openfile(fileName,mode,parallel)
6974  character(len=*), intent(in) :: filename
6975  character, intent(in), optional :: mode
6976  logical, intent(in), optional :: parallel
6977 
6978  character :: m
6979  integer(HID_T) :: plist_id
6980  integer :: hdferr
6981 
6982  if (present(mode)) then
6983  m = mode
6984  else
6985  m = 'r'
6986  endif
6987 
6988  call h5pcreate_f(h5p_file_access_f, plist_id, hdferr)
6989  if (hdferr < 0) call io_error(1,ext_msg='HDF5_openFile: h5pcreate_f')
6990 
6991 
6992 
6993 
6994 
6995 
6996 
6997 
6998  if (m == 'w') then
6999  call h5fcreate_f(filename,h5f_acc_trunc_f,hdf5_openfile,hdferr,access_prp = plist_id)
7000  if (hdferr < 0) call io_error(1,ext_msg='HDF5_openFile: h5fcreate_f (w)')
7001  elseif(m == 'a') then
7002  call h5fopen_f(filename,h5f_acc_rdwr_f,hdf5_openfile,hdferr,access_prp = plist_id)
7003  if (hdferr < 0) call io_error(1,ext_msg='HDF5_openFile: h5fopen_f (a)')
7004  elseif(m == 'r') then
7005  call h5fopen_f(filename,h5f_acc_rdonly_f,hdf5_openfile,hdferr,access_prp = plist_id)
7006  if (hdferr < 0) call io_error(1,ext_msg='HDF5_openFile: h5fopen_f (r)')
7007  else
7008  call io_error(1,ext_msg='HDF5_openFile: h5fopen_f unknown access mode: '//trim(m))
7009  endif
7010 
7011  call h5pclose_f(plist_id, hdferr)
7012  if (hdferr < 0) call io_error(1,ext_msg='HDF5_openFile: h5pclose_f')
7013 
7014 end function hdf5_openfile
7015 
7016 
7017 !--------------------------------------------------------------------------------------------------
7019 !--------------------------------------------------------------------------------------------------
7020 subroutine hdf5_closefile(fileHandle)
7022  integer(HID_T), intent(in) :: fileHandle
7023 
7024  integer :: hdferr
7025 
7026  call h5fclose_f(filehandle,hdferr)
7027  if (hdferr < 0) call io_error(1,ext_msg='HDF5_closeFile: h5fclose_f')
7028 
7029 end subroutine hdf5_closefile
7030 
7031 
7032 !--------------------------------------------------------------------------------------------------
7034 !--------------------------------------------------------------------------------------------------
7035 integer(HID_T) function hdf5_addgroup(fileHandle,groupName)
7037  integer(HID_T), intent(in) :: filehandle
7038  character(len=*), intent(in) :: groupname
7039 
7040  integer :: hdferr
7041  integer(HID_T) :: aplist_id
7042 
7043 !-------------------------------------------------------------------------------------------------
7044 ! creating a property list for data access properties
7045  call h5pcreate_f(h5p_group_access_f, aplist_id, hdferr)
7046  if (hdferr < 0) call io_error(1,ext_msg = 'HDF5_addGroup: h5pcreate_f ('//trim(groupname)//')')
7047 
7048 !-------------------------------------------------------------------------------------------------
7049 ! setting I/O mode to collective
7050 
7051 
7052 
7053 
7054 
7055 !-------------------------------------------------------------------------------------------------
7056 ! Create group
7057  call h5gcreate_f(filehandle, trim(groupname), hdf5_addgroup, hdferr, object_namelen_default_f,gapl_id = aplist_id)
7058  if (hdferr < 0) call io_error(1,ext_msg = 'HDF5_addGroup: h5gcreate_f ('//trim(groupname)//')')
7059 
7060  call h5pclose_f(aplist_id,hdferr)
7061 
7062 end function hdf5_addgroup
7063 
7064 
7065 !--------------------------------------------------------------------------------------------------
7067 !--------------------------------------------------------------------------------------------------
7068 integer(HID_T) function hdf5_opengroup(fileHandle,groupName)
7070  integer(HID_T), intent(in) :: filehandle
7071  character(len=*), intent(in) :: groupname
7072 
7073 
7074  integer :: hdferr
7075  integer(HID_T) :: aplist_id
7076  logical :: is_collective
7077 
7078 
7079  !-------------------------------------------------------------------------------------------------
7080  ! creating a property list for data access properties
7081  call h5pcreate_f(h5p_group_access_f, aplist_id, hdferr)
7082  if (hdferr < 0) call io_error(1,ext_msg = 'HDF5_openGroup: h5pcreate_f ('//trim(groupname)//')')
7083 
7084  !-------------------------------------------------------------------------------------------------
7085  ! setting I/O mode to collective
7086 
7087 
7088 
7089 
7090 
7091  !-------------------------------------------------------------------------------------------------
7092  ! opening the group
7093  call h5gopen_f(filehandle, trim(groupname), hdf5_opengroup, hdferr, gapl_id = aplist_id)
7094  if (hdferr < 0) call io_error(1,ext_msg = 'HDF5_openGroup: h5gopen_f ('//trim(groupname)//')')
7095 
7096  call h5pclose_f(aplist_id,hdferr)
7097 
7098 end function hdf5_opengroup
7099 
7100 
7101 !--------------------------------------------------------------------------------------------------
7103 !--------------------------------------------------------------------------------------------------
7104 subroutine hdf5_closegroup(group_id)
7106  integer(HID_T), intent(in) :: group_id
7107  integer :: hdferr
7108 
7109  call h5gclose_f(group_id, hdferr)
7110  if (hdferr < 0) call io_error(1,ext_msg = 'HDF5_closeGroup: h5gclose_f (el is ID)', el = int(group_id))
7111 
7112 end subroutine hdf5_closegroup
7113 
7114 
7115 !--------------------------------------------------------------------------------------------------
7117 !--------------------------------------------------------------------------------------------------
7118 logical function hdf5_objectexists(loc_id,path)
7120  integer(HID_T), intent(in) :: loc_id
7121  character(len=*), intent(in), optional :: path
7122 
7123  integer :: hdferr
7124  character(len=pStringLen) :: p
7125 
7126  if (present(path)) then
7127  p = trim(path)
7128  else
7129  p = '.'
7130  endif
7131 
7132  call h5lexists_f(loc_id, p, hdf5_objectexists, hdferr)
7133  if (hdferr < 0) call io_error(1,ext_msg = 'HDF5_objectExists: h5oexists_by_name_f')
7134 
7135  if(hdf5_objectexists) then
7136  call h5oexists_by_name_f(loc_id, p, hdf5_objectexists, hdferr)
7137  if (hdferr < 0) call io_error(1,ext_msg = 'HDF5_objectExists: h5oexists_by_name_f')
7138  endif
7139 
7140 end function hdf5_objectexists
7141 
7142 
7143 !--------------------------------------------------------------------------------------------------
7145 !--------------------------------------------------------------------------------------------------
7146 subroutine hdf5_addattribute_str(loc_id,attrLabel,attrValue,path)
7148  integer(HID_T), intent(in) :: loc_id
7149  character(len=*), intent(in) :: attrLabel, attrValue
7150  character(len=*), intent(in), optional :: path
7151 
7152  integer :: hdferr
7153  integer(HID_T) :: attr_id, space_id, type_id
7154  logical :: attrExists
7155  character(len=pStringLen) :: p
7156 
7157  if (present(path)) then
7158  p = trim(path)
7159  else
7160  p = '.'
7161  endif
7162 
7163  call h5screate_f(h5s_scalar_f,space_id,hdferr)
7164  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_str: h5screate_f')
7165  call h5tcopy_f(h5t_native_character, type_id, hdferr)
7166  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_str: h5tcopy_f')
7167  call h5tset_size_f(type_id, int(len_trim(attrvalue),hsize_t), hdferr)
7168  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_str: h5tset_size_f')
7169  call h5aexists_by_name_f(loc_id,trim(p),attrlabel,attrexists,hdferr)
7170  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_str: h5aexists_by_name_f')
7171  if (attrexists) then
7172  call h5adelete_by_name_f(loc_id, trim(p), attrlabel, hdferr)
7173  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_str: h5adelete_by_name_f')
7174  endif
7175  call h5acreate_by_name_f(loc_id,trim(p),trim(attrlabel),type_id,space_id,attr_id,hdferr)
7176  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_str: h5acreate_f')
7177  call h5awrite_f(attr_id, type_id, trim(attrvalue), int([1],hsize_t), hdferr)
7178  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_str: h5awrite_f')
7179  call h5aclose_f(attr_id,hdferr)
7180  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_str: h5aclose_f')
7181  call h5tclose_f(type_id,hdferr)
7182  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_str: h5tclose_f')
7183  call h5sclose_f(space_id,hdferr)
7184  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_str: h5sclose_f')
7185 
7186 end subroutine hdf5_addattribute_str
7187 
7188 
7189 !--------------------------------------------------------------------------------------------------
7191 !--------------------------------------------------------------------------------------------------
7192 subroutine hdf5_addattribute_int(loc_id,attrLabel,attrValue,path)
7194  integer(HID_T), intent(in) :: loc_id
7195  character(len=*), intent(in) :: attrLabel
7196  integer, intent(in) :: attrValue
7197  character(len=*), intent(in), optional :: path
7198 
7199  integer :: hdferr
7200  integer(HID_T) :: attr_id, space_id
7201  logical :: attrExists
7202  character(len=pStringLen) :: p
7203 
7204  if (present(path)) then
7205  p = trim(path)
7206  else
7207  p = '.'
7208  endif
7209 
7210  call h5screate_f(h5s_scalar_f,space_id,hdferr)
7211  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int: h5screate_f')
7212  call h5aexists_by_name_f(loc_id,trim(p),attrlabel,attrexists,hdferr)
7213  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int: h5aexists_by_name_f')
7214  if (attrexists) then
7215  call h5adelete_by_name_f(loc_id, trim(p), attrlabel, hdferr)
7216  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int: h5adelete_by_name_f')
7217  endif
7218  call h5acreate_by_name_f(loc_id,trim(p),trim(attrlabel),h5t_native_integer,space_id,attr_id,hdferr)
7219  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int: h5acreate_f')
7220  call h5awrite_f(attr_id, h5t_native_integer, attrvalue, int([1],hsize_t), hdferr)
7221  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int: h5awrite_f')
7222  call h5aclose_f(attr_id,hdferr)
7223  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int: h5tclose_f')
7224  call h5sclose_f(space_id,hdferr)
7225  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int: h5sclose_f')
7226 
7227 end subroutine hdf5_addattribute_int
7228 
7229 
7230 !--------------------------------------------------------------------------------------------------
7232 !--------------------------------------------------------------------------------------------------
7233 subroutine hdf5_addattribute_real(loc_id,attrLabel,attrValue,path)
7235  integer(HID_T), intent(in) :: loc_id
7236  character(len=*), intent(in) :: attrLabel
7237  real(pReal), intent(in) :: attrValue
7238  character(len=*), intent(in), optional :: path
7239 
7240  integer :: hdferr
7241  integer(HID_T) :: attr_id, space_id
7242  logical :: attrExists
7243  character(len=pStringLen) :: p
7244 
7245  if (present(path)) then
7246  p = trim(path)
7247  else
7248  p = '.'
7249  endif
7250 
7251  call h5screate_f(h5s_scalar_f,space_id,hdferr)
7252  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_real: h5screate_f')
7253  call h5aexists_by_name_f(loc_id,trim(p),attrlabel,attrexists,hdferr)
7254  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_real: h5aexists_by_name_f')
7255  if (attrexists) then
7256  call h5adelete_by_name_f(loc_id, trim(p), attrlabel, hdferr)
7257  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_real: h5adelete_by_name_f')
7258  endif
7259  call h5acreate_by_name_f(loc_id,trim(p),trim(attrlabel),h5t_native_double,space_id,attr_id,hdferr)
7260  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_real: h5acreate_f')
7261  call h5awrite_f(attr_id, h5t_native_double, attrvalue, int([1],hsize_t), hdferr)
7262  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_real: h5awrite_f')
7263  call h5aclose_f(attr_id,hdferr)
7264  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_real: h5tclose_f')
7265  call h5sclose_f(space_id,hdferr)
7266  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_real: h5sclose_f')
7267 
7268 end subroutine hdf5_addattribute_real
7269 
7270 
7271 !--------------------------------------------------------------------------------------------------
7273 !--------------------------------------------------------------------------------------------------
7274 subroutine hdf5_addattribute_int_array(loc_id,attrLabel,attrValue,path)
7276  integer(HID_T), intent(in) :: loc_id
7277  character(len=*), intent(in) :: attrLabel
7278  integer, intent(in), dimension(:) :: attrValue
7279  character(len=*), intent(in), optional :: path
7280 
7281  integer :: hdferr
7282  integer(HID_T) :: attr_id, space_id
7283  integer(HSIZE_T),dimension(1) :: array_size
7284  logical :: attrExists
7285  character(len=pStringLen) :: p
7286 
7287  if (present(path)) then
7288  p = trim(path)
7289  else
7290  p = '.'
7291  endif
7292 
7293  array_size = size(attrvalue,kind=hsize_t)
7294 
7295  call h5screate_simple_f(1, array_size, space_id, hdferr, array_size)
7296  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5screate_f')
7297  call h5aexists_by_name_f(loc_id,trim(p),attrlabel,attrexists,hdferr)
7298  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5aexists_by_name_f')
7299  if (attrexists) then
7300  call h5adelete_by_name_f(loc_id, trim(p), attrlabel, hdferr)
7301  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5adelete_by_name_f')
7302  endif
7303  call h5acreate_by_name_f(loc_id,trim(p),trim(attrlabel),h5t_native_integer,space_id,attr_id,hdferr)
7304  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5acreate_f')
7305  call h5awrite_f(attr_id, h5t_native_integer, attrvalue, array_size, hdferr)
7306  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5awrite_f')
7307  call h5aclose_f(attr_id,hdferr)
7308  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5tclose_f')
7309  call h5sclose_f(space_id,hdferr)
7310  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5sclose_f')
7311 
7312 end subroutine hdf5_addattribute_int_array
7313 
7314 
7315 !--------------------------------------------------------------------------------------------------
7317 !--------------------------------------------------------------------------------------------------
7318 subroutine hdf5_addattribute_real_array(loc_id,attrLabel,attrValue,path)
7320  integer(HID_T), intent(in) :: loc_id
7321  character(len=*), intent(in) :: attrLabel
7322  real(pReal), intent(in), dimension(:) :: attrValue
7323  character(len=*), intent(in), optional :: path
7324 
7325  integer :: hdferr
7326  integer(HID_T) :: attr_id, space_id
7327  integer(HSIZE_T),dimension(1) :: array_size
7328  logical :: attrExists
7329  character(len=pStringLen) :: p
7330 
7331  if (present(path)) then
7332  p = trim(path)
7333  else
7334  p = '.'
7335  endif
7336 
7337  array_size = size(attrvalue,kind=hsize_t)
7338 
7339  call h5screate_simple_f(1, array_size, space_id, hdferr, array_size)
7340  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5screate_f')
7341  call h5aexists_by_name_f(loc_id,trim(p),attrlabel,attrexists,hdferr)
7342  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5aexists_by_name_f')
7343  if (attrexists) then
7344  call h5adelete_by_name_f(loc_id, trim(p), attrlabel, hdferr)
7345  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5adelete_by_name_f')
7346  endif
7347  call h5acreate_by_name_f(loc_id,trim(p),trim(attrlabel),h5t_native_double,space_id,attr_id,hdferr)
7348  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5acreate_f')
7349  call h5awrite_f(attr_id, h5t_native_double, attrvalue, array_size, hdferr)
7350  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5awrite_f')
7351  call h5aclose_f(attr_id,hdferr)
7352  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5tclose_f')
7353  call h5sclose_f(space_id,hdferr)
7354  if (hdferr < 0) call io_error(1,ext_msg='HDF5_addAttribute_int_array: h5sclose_f')
7355 
7356 end subroutine hdf5_addattribute_real_array
7357 
7358 
7359 !--------------------------------------------------------------------------------------------------
7361 !--------------------------------------------------------------------------------------------------
7362 subroutine hdf5_setlink(loc_id,target_name,link_name)
7364  character(len=*), intent(in) :: target_name, link_name
7365  integer(HID_T), intent(in) :: loc_id
7366  integer :: hdferr
7367  logical :: linkExists
7368 
7369  call h5lexists_f(loc_id, link_name,linkexists, hdferr)
7370  if (hdferr < 0) call io_error(1,ext_msg = 'HDF5_setLink: h5lexists_soft_f ('//trim(link_name)//')')
7371  if (linkexists) then
7372  call h5ldelete_f(loc_id,link_name, hdferr)
7373  if (hdferr < 0) call io_error(1,ext_msg = 'HDF5_setLink: h5ldelete_soft_f ('//trim(link_name)//')')
7374  endif
7375  call h5lcreate_soft_f(target_name, loc_id, link_name, hdferr)
7376  if (hdferr < 0) call io_error(1,ext_msg = 'HDF5_setLink: h5lcreate_soft_f ('//trim(target_name)//' '//trim(link_name)//')')
7377 
7378 end subroutine hdf5_setlink
7379 
7380 
7381 !--------------------------------------------------------------------------------------------------
7383 !--------------------------------------------------------------------------------------------------
7384 subroutine hdf5_read_real1(loc_id,dataset,datasetName,parallel)
7386  real(pReal), intent(out), dimension(:) :: dataset
7387  integer(HID_T), intent(in) :: loc_id
7388  character(len=*), intent(in) :: datasetName
7389  logical, intent(in), optional :: parallel
7390 
7391  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7392  integer(HSIZE_T), dimension(size(shape(dataset))) :: & ! ToDo: Fortran 2018 size(shape(A)) = rank(A)
7393  myStart, &
7394  myShape, & !< shape of the dataset (this process)
7395  totalShape
7396  integer :: hdferr
7397 
7398 !---------------------------------------------------------------------------------------------------
7399 ! determine shape of dataset
7400  myshape = int(shape(dataset),hsize_t)
7401  if (any(myshape(1:size(myshape)-1) == 0)) return
7402 
7403 !---------------------------------------------------------------------------------------------------
7404 ! initialize HDF5 data structures
7405  if (present(parallel)) then
7406  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7407  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7408  else
7409  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7410  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7411  endif
7412 
7413  call h5dread_f(dset_id, h5t_native_double,dataset,totalshape, hdferr,&
7414  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7415  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_real1: h5dread_f')
7416 
7417  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7418 
7419 end subroutine hdf5_read_real1
7420 
7421 !--------------------------------------------------------------------------------------------------
7423 !--------------------------------------------------------------------------------------------------
7424 subroutine hdf5_read_real2(loc_id,dataset,datasetName,parallel)
7426  real(pReal), intent(out), dimension(:,:) :: dataset
7427  integer(HID_T), intent(in) :: loc_id
7428  character(len=*), intent(in) :: datasetName
7429  logical, intent(in), optional :: parallel
7430 
7431  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7432  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7433  myStart, &
7434  myShape, & !< shape of the dataset (this process)
7435  totalShape
7436  integer :: hdferr
7437 
7438 !---------------------------------------------------------------------------------------------------
7439 ! determine shape of dataset
7440  myshape = int(shape(dataset),hsize_t)
7441  if (any(myshape(1:size(myshape)-1) == 0)) return
7442 
7443 !---------------------------------------------------------------------------------------------------
7444 ! initialize HDF5 data structures
7445  if (present(parallel)) then
7446  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7447  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7448  else
7449  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7450  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7451  endif
7452 
7453  call h5dread_f(dset_id, h5t_native_double,dataset,totalshape, hdferr,&
7454  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7455  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_real2: h5dread_f')
7456 
7457  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7458 
7459 end subroutine hdf5_read_real2
7460 
7461 !--------------------------------------------------------------------------------------------------
7463 !--------------------------------------------------------------------------------------------------
7464 subroutine hdf5_read_real3(loc_id,dataset,datasetName,parallel)
7466  real(pReal), intent(out), dimension(:,:,:) :: dataset
7467  integer(HID_T), intent(in) :: loc_id
7468  character(len=*), intent(in) :: datasetName
7469  logical, intent(in), optional :: parallel
7470 
7471  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7472  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7473  myStart, &
7474  myShape, & !< shape of the dataset (this process)
7475  totalShape
7476  integer :: hdferr
7477 
7478 !---------------------------------------------------------------------------------------------------
7479 ! determine shape of dataset
7480  myshape = int(shape(dataset),hsize_t)
7481  if (any(myshape(1:size(myshape)-1) == 0)) return
7482 
7483 !---------------------------------------------------------------------------------------------------
7484 ! initialize HDF5 data structures
7485  if (present(parallel)) then
7486  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7487  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7488  else
7489  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7490  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7491  endif
7492 
7493  call h5dread_f(dset_id, h5t_native_double,dataset,totalshape, hdferr,&
7494  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7495  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_real3: h5dread_f')
7496 
7497  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7498 
7499 end subroutine hdf5_read_real3
7500 
7501 !--------------------------------------------------------------------------------------------------
7503 !--------------------------------------------------------------------------------------------------
7504 subroutine hdf5_read_real4(loc_id,dataset,datasetName,parallel)
7506  real(pReal), intent(out), dimension(:,:,:,:) :: dataset
7507  integer(HID_T), intent(in) :: loc_id
7508  character(len=*), intent(in) :: datasetName
7509  logical, intent(in), optional :: parallel
7510 
7511  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7512  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7513  myStart, &
7514  myShape, & !< shape of the dataset (this process)
7515  totalShape
7516  integer :: hdferr
7517 
7518 !---------------------------------------------------------------------------------------------------
7519 ! determine shape of dataset
7520  myshape = int(shape(dataset),hsize_t)
7521  if (any(myshape(1:size(myshape)-1) == 0)) return
7522 
7523 !---------------------------------------------------------------------------------------------------
7524 ! initialize HDF5 data structures
7525  if (present(parallel)) then
7526  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7527  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7528  else
7529  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7530  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7531  endif
7532 
7533  call h5dread_f(dset_id, h5t_native_double,dataset,totalshape, hdferr,&
7534  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7535  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_real4: h5dread_f')
7536 
7537  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7538 
7539 end subroutine hdf5_read_real4
7540 
7541 !--------------------------------------------------------------------------------------------------
7543 !--------------------------------------------------------------------------------------------------
7544 subroutine hdf5_read_real5(loc_id,dataset,datasetName,parallel)
7546  real(pReal), intent(out), dimension(:,:,:,:,:) :: dataset
7547  integer(HID_T), intent(in) :: loc_id
7548  character(len=*), intent(in) :: datasetName
7549  logical, intent(in), optional :: parallel
7550 
7551  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7552  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7553  myStart, &
7554  myShape, & !< shape of the dataset (this process)
7555  totalShape
7556  integer :: hdferr
7557 
7558 !---------------------------------------------------------------------------------------------------
7559 ! determine shape of dataset
7560  myshape = int(shape(dataset),hsize_t)
7561  if (any(myshape(1:size(myshape)-1) == 0)) return
7562 
7563 !---------------------------------------------------------------------------------------------------
7564 ! initialize HDF5 data structures
7565  if (present(parallel)) then
7566  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7567  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7568  else
7569  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7570  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7571  endif
7572 
7573  call h5dread_f(dset_id, h5t_native_double,dataset,totalshape, hdferr,&
7574  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7575  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_real5: h5dread_f')
7576 
7577  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7578 
7579 end subroutine hdf5_read_real5
7580 
7581 !--------------------------------------------------------------------------------------------------
7583 !--------------------------------------------------------------------------------------------------
7584 subroutine hdf5_read_real6(loc_id,dataset,datasetName,parallel)
7586  real(pReal), intent(out), dimension(:,:,:,:,:,:) :: dataset
7587  integer(HID_T), intent(in) :: loc_id
7588  character(len=*), intent(in) :: datasetName
7589  logical, intent(in), optional :: parallel
7590 
7591  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7592  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7593  myStart, &
7594  myShape, & !< shape of the dataset (this process)
7595  totalShape
7596  integer :: hdferr
7597 
7598 !---------------------------------------------------------------------------------------------------
7599 ! determine shape of dataset
7600  myshape = int(shape(dataset),hsize_t)
7601  if (any(myshape(1:size(myshape)-1) == 0)) return
7602 
7603 !---------------------------------------------------------------------------------------------------
7604 ! initialize HDF5 data structures
7605  if (present(parallel)) then
7606  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7607  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7608  else
7609  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7610  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7611  endif
7612 
7613  call h5dread_f(dset_id, h5t_native_double,dataset,totalshape, hdferr,&
7614  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7615  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_real6: h5dread_f')
7616 
7617  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7618 
7619 end subroutine hdf5_read_real6
7620 
7621 !--------------------------------------------------------------------------------------------------
7623 !--------------------------------------------------------------------------------------------------
7624 subroutine hdf5_read_real7(loc_id,dataset,datasetName,parallel)
7626  real(pReal), intent(out), dimension(:,:,:,:,:,:,:) :: dataset
7627  integer(HID_T), intent(in) :: loc_id
7628  character(len=*), intent(in) :: datasetName
7629  logical, intent(in), optional :: parallel
7630 
7631  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7632  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7633  myStart, &
7634  myShape, & !< shape of the dataset (this process)
7635  totalShape
7636  integer :: hdferr
7637 
7638 !---------------------------------------------------------------------------------------------------
7639 ! determine shape of dataset
7640  myshape = int(shape(dataset),hsize_t)
7641  if (any(myshape(1:size(myshape)-1) == 0)) return
7642 
7643 !---------------------------------------------------------------------------------------------------
7644 ! initialize HDF5 data structures
7645  if (present(parallel)) then
7646  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7647  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7648  else
7649  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7650  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7651  endif
7652 
7653  call h5dread_f(dset_id, h5t_native_double,dataset,totalshape, hdferr,&
7654  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7655  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_real7: h5dread_f')
7656 
7657  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7658 
7659 end subroutine hdf5_read_real7
7660 
7661 
7662 !--------------------------------------------------------------------------------------------------
7664 !--------------------------------------------------------------------------------------------------
7665 subroutine hdf5_read_int1(loc_id,dataset,datasetName,parallel)
7667  integer, intent(out), dimension(:) :: dataset
7668  integer(HID_T), intent(in) :: loc_id
7669  character(len=*), intent(in) :: datasetName
7670  logical, intent(in), optional :: parallel
7671 
7672 
7673  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7674  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7675  myStart, &
7676  myShape, & !< shape of the dataset (this process)
7677  totalShape
7678  integer :: hdferr
7679 
7680 !---------------------------------------------------------------------------------------------------
7681 ! determine shape of dataset
7682  myshape = int(shape(dataset),hsize_t)
7683  if (any(myshape(1:size(myshape)-1) == 0)) return
7684 
7685 !---------------------------------------------------------------------------------------------------
7686 ! initialize HDF5 data structures
7687  if (present(parallel)) then
7688  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7689  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7690  else
7691  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7692  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7693  endif
7694 
7695  call h5dread_f(dset_id, h5t_native_integer,dataset,totalshape, hdferr,&
7696  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7697  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_int1: h5dread_f')
7698 
7699  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7700 
7701 end subroutine hdf5_read_int1
7702 
7703 !--------------------------------------------------------------------------------------------------
7705 !--------------------------------------------------------------------------------------------------
7706 subroutine hdf5_read_int2(loc_id,dataset,datasetName,parallel)
7708  integer, intent(out), dimension(:,:) :: dataset
7709  integer(HID_T), intent(in) :: loc_id
7710  character(len=*), intent(in) :: datasetName
7711  logical, intent(in), optional :: parallel
7712 
7713  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7714  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7715  myStart, &
7716  myShape, & !< shape of the dataset (this process)
7717  totalShape
7718  integer :: hdferr
7719 
7720 !---------------------------------------------------------------------------------------------------
7721 ! determine shape of dataset
7722  myshape = int(shape(dataset),hsize_t)
7723  if (any(myshape(1:size(myshape)-1) == 0)) return
7724 
7725 !---------------------------------------------------------------------------------------------------
7726 ! initialize HDF5 data structures
7727  if (present(parallel)) then
7728  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7729  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7730  else
7731  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7732  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7733  endif
7734 
7735  call h5dread_f(dset_id, h5t_native_integer,dataset,totalshape, hdferr,&
7736  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7737  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_int2: h5dread_f')
7738 
7739  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7740 
7741 end subroutine hdf5_read_int2
7742 
7743 !--------------------------------------------------------------------------------------------------
7745 !--------------------------------------------------------------------------------------------------
7746 subroutine hdf5_read_int3(loc_id,dataset,datasetName,parallel)
7748  integer, intent(out), dimension(:,:,:) :: dataset
7749  integer(HID_T), intent(in) :: loc_id
7750  character(len=*), intent(in) :: datasetName
7751  logical, intent(in), optional :: parallel
7752 
7753  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7754  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7755  myStart, &
7756  myShape, & !< shape of the dataset (this process)
7757  totalShape
7758  integer :: hdferr
7759 
7760 !---------------------------------------------------------------------------------------------------
7761 ! determine shape of dataset
7762  myshape = int(shape(dataset),hsize_t)
7763  if (any(myshape(1:size(myshape)-1) == 0)) return
7764 
7765 !---------------------------------------------------------------------------------------------------
7766 ! initialize HDF5 data structures
7767  if (present(parallel)) then
7768  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7769  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7770  else
7771  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7772  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7773  endif
7774 
7775  call h5dread_f(dset_id, h5t_native_integer,dataset,totalshape, hdferr,&
7776  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7777  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_int3: h5dread_f')
7778 
7779  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7780 
7781 end subroutine hdf5_read_int3
7782 
7783 !--------------------------------------------------------------------------------------------------
7785 !--------------------------------------------------------------------------------------------------
7786 subroutine hdf5_read_int4(loc_id,dataset,datasetName,parallel)
7788  integer, intent(out), dimension(:,:,:,:) :: dataset
7789  integer(HID_T), intent(in) :: loc_id
7790  character(len=*), intent(in) :: datasetName
7791  logical, intent(in), optional :: parallel
7792 
7793  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7794  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7795  myStart, &
7796  myShape, & !< shape of the dataset (this process)
7797  totalShape
7798  integer :: hdferr
7799 
7800 !---------------------------------------------------------------------------------------------------
7801 ! determine shape of dataset
7802  myshape = int(shape(dataset),hsize_t)
7803  if (any(myshape(1:size(myshape)-1) == 0)) return
7804 
7805 !---------------------------------------------------------------------------------------------------
7806 ! initialize HDF5 data structures
7807  if (present(parallel)) then
7808  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7809  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7810  else
7811  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7812  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7813  endif
7814 
7815  call h5dread_f(dset_id, h5t_native_integer,dataset,totalshape, hdferr,&
7816  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7817  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_int4: h5dread_f')
7818 
7819  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7820 
7821 end subroutine hdf5_read_int4
7822 
7823 !--------------------------------------------------------------------------------------------------
7825 !--------------------------------------------------------------------------------------------------
7826 subroutine hdf5_read_int5(loc_id,dataset,datasetName,parallel)
7828  integer, intent(out), dimension(:,:,:,:,:) :: dataset
7829  integer(HID_T), intent(in) :: loc_id
7830  character(len=*), intent(in) :: datasetName
7831  logical, intent(in), optional :: parallel
7832 
7833  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7834  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7835  myStart, &
7836  myShape, & !< shape of the dataset (this process)
7837  totalShape
7838  integer :: hdferr
7839 
7840 !---------------------------------------------------------------------------------------------------
7841 ! determine shape of dataset
7842  myshape = int(shape(dataset),hsize_t)
7843  if (any(myshape(1:size(myshape)-1) == 0)) return
7844 
7845 !---------------------------------------------------------------------------------------------------
7846 ! initialize HDF5 data structures
7847  if (present(parallel)) then
7848  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7849  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7850  else
7851  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7852  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7853  endif
7854 
7855  call h5dread_f(dset_id, h5t_native_integer,dataset,totalshape, hdferr,&
7856  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7857  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_int5: h5dread_f')
7858 
7859  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7860 
7861 end subroutine hdf5_read_int5
7862 
7863 !--------------------------------------------------------------------------------------------------
7865 !--------------------------------------------------------------------------------------------------
7866 subroutine hdf5_read_int6(loc_id,dataset,datasetName,parallel)
7868  integer, intent(out), dimension(:,:,:,:,:,:) :: dataset
7869  integer(HID_T), intent(in) :: loc_id
7870  character(len=*), intent(in) :: datasetName
7871  logical, intent(in), optional :: parallel
7872 
7873  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7874  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7875  myStart, &
7876  myShape, & !< shape of the dataset (this process)
7877  totalShape
7878  integer :: hdferr
7879 
7880 !---------------------------------------------------------------------------------------------------
7881 ! determine shape of dataset
7882  myshape = int(shape(dataset),hsize_t)
7883  if (any(myshape(1:size(myshape)-1) == 0)) return
7884 
7885 !---------------------------------------------------------------------------------------------------
7886 ! initialize HDF5 data structures
7887  if (present(parallel)) then
7888  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7889  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7890  else
7891  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7892  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7893  endif
7894 
7895  call h5dread_f(dset_id, h5t_native_integer,dataset,totalshape, hdferr,&
7896  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7897  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_int6: h5dread_f')
7898 
7899  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7900 
7901 end subroutine hdf5_read_int6
7902 
7903 !--------------------------------------------------------------------------------------------------
7905 !--------------------------------------------------------------------------------------------------
7906 subroutine hdf5_read_int7(loc_id,dataset,datasetName,parallel)
7908  integer, intent(out), dimension(:,:,:,:,:,:,:) :: dataset
7909  integer(HID_T), intent(in) :: loc_id
7910  character(len=*), intent(in) :: datasetName
7911  logical, intent(in), optional :: parallel
7912 
7913  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
7914  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7915  myStart, &
7916  myShape, & !< shape of the dataset (this process)
7917  totalShape
7918  integer :: hdferr
7919 
7920 !---------------------------------------------------------------------------------------------------
7921 ! determine shape of dataset
7922  myshape = int(shape(dataset),hsize_t)
7923  if (any(myshape(1:size(myshape)-1) == 0)) return
7924 
7925 !---------------------------------------------------------------------------------------------------
7926 ! initialize HDF5 data structures
7927  if (present(parallel)) then
7928  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7929  mystart, totalshape, loc_id,myshape,datasetname,parallel)
7930  else
7931  call initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
7932  mystart, totalshape, loc_id,myshape,datasetname,.false.)
7933  endif
7934 
7935  call h5dread_f(dset_id, h5t_native_integer,dataset,totalshape, hdferr,&
7936  file_space_id = filespace_id, xfer_prp = plist_id, mem_space_id = memspace_id)
7937  if (hdferr < 0) call io_error(1,ext_msg='HDF5_read_int7: h5dread_f')
7938 
7939  call finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
7940 
7941 end subroutine hdf5_read_int7
7942 
7943 
7944 !--------------------------------------------------------------------------------------------------
7946 !--------------------------------------------------------------------------------------------------
7947 subroutine hdf5_write_real1(loc_id,dataset,datasetName,parallel)
7949  real(pReal), intent(inout), dimension(:) :: dataset
7950  integer(HID_T), intent(in) :: loc_id
7951  character(len=*), intent(in) :: datasetName
7952  logical, intent(in), optional :: parallel
7953 
7954 
7955  integer :: hdferr
7956  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
7957  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7958  myStart, &
7959  myShape, & !< shape of the dataset (this process)
7960  totalShape
7961 
7962 !---------------------------------------------------------------------------------------------------
7963 ! determine shape of dataset
7964  myshape = int(shape(dataset),hsize_t)
7965  if (any(myshape(1:size(myshape)-1) == 0)) return
7966 
7967  if (present(parallel)) then
7968  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
7969  mystart, totalshape,loc_id,myshape,datasetname,h5t_native_double,parallel)
7970  else
7971  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
7972  mystart, totalshape,loc_id,myshape,datasetname,h5t_native_double,.false.)
7973  endif
7974 
7975  if (product(totalshape) /= 0) then
7976  call h5dwrite_f(dset_id, h5t_native_double,dataset,int(totalshape,hsize_t), hdferr,&
7977  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
7978  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_real1: h5dwrite_f')
7979  endif
7980 
7981  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
7982 
7983 end subroutine hdf5_write_real1
7984 
7985 !--------------------------------------------------------------------------------------------------
7987 !--------------------------------------------------------------------------------------------------
7988 subroutine hdf5_write_real2(loc_id,dataset,datasetName,parallel)
7990  real(pReal), intent(inout), dimension(:,:) :: dataset
7991  integer(HID_T), intent(in) :: loc_id
7992  character(len=*), intent(in) :: datasetName
7993  logical, intent(in), optional :: parallel
7994 
7995 
7996  integer :: hdferr
7997  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
7998  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
7999  myStart, &
8000  myShape, & !< shape of the dataset (this process)
8001  totalShape
8002 
8003 !---------------------------------------------------------------------------------------------------
8004 ! determine shape of dataset
8005  myshape = int(shape(dataset),hsize_t)
8006  if (any(myshape(1:size(myshape)-1) == 0)) return
8007 
8008  if (present(parallel)) then
8009  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8010  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,parallel)
8011  else
8012  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8013  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,.false.)
8014  endif
8015 
8016  if (product(totalshape) /= 0) then
8017  call h5dwrite_f(dset_id, h5t_native_double,dataset,int(totalshape,hsize_t), hdferr,&
8018  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8019  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_real2: h5dwrite_f')
8020  endif
8021 
8022  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8023 
8024 end subroutine hdf5_write_real2
8025 
8026 !--------------------------------------------------------------------------------------------------
8028 !--------------------------------------------------------------------------------------------------
8029 subroutine hdf5_write_real3(loc_id,dataset,datasetName,parallel)
8031  real(pReal), intent(inout), dimension(:,:,:) :: dataset
8032  integer(HID_T), intent(in) :: loc_id
8033  character(len=*), intent(in) :: datasetName
8034  logical, intent(in), optional :: parallel
8035 
8036 
8037  integer :: hdferr
8038  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8039  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8040  myStart, &
8041  myShape, & !< shape of the dataset (this process)
8042  totalShape
8043 
8044 !---------------------------------------------------------------------------------------------------
8045 ! determine shape of dataset
8046  myshape = int(shape(dataset),hsize_t)
8047  if (any(myshape(1:size(myshape)-1) == 0)) return
8048 
8049  if (present(parallel)) then
8050  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8051  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,parallel)
8052  else
8053  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8054  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,.false.)
8055  endif
8056 
8057  if (product(totalshape) /= 0) then
8058  call h5dwrite_f(dset_id, h5t_native_double,dataset,int(totalshape,hsize_t), hdferr,&
8059  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8060  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_real3: h5dwrite_f')
8061  endif
8062 
8063  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8064 
8065 end subroutine hdf5_write_real3
8066 
8067 !--------------------------------------------------------------------------------------------------
8069 !--------------------------------------------------------------------------------------------------
8070 subroutine hdf5_write_real4(loc_id,dataset,datasetName,parallel)
8072  real(pReal), intent(inout), dimension(:,:,:,:) :: dataset
8073  integer(HID_T), intent(in) :: loc_id
8074  character(len=*), intent(in) :: datasetName
8075  logical, intent(in), optional :: parallel
8076 
8077 
8078  integer :: hdferr
8079  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8080  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8081  myStart, &
8082  myShape, & !< shape of the dataset (this process)
8083  totalShape
8084 
8085 !---------------------------------------------------------------------------------------------------
8086 ! determine shape of dataset
8087  myshape = int(shape(dataset),hsize_t)
8088  if (any(myshape(1:size(myshape)-1) == 0)) return
8089 
8090  if (present(parallel)) then
8091  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8092  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,parallel)
8093  else
8094  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8095  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,.false.)
8096  endif
8097 
8098  if (product(totalshape) /= 0) then
8099  call h5dwrite_f(dset_id, h5t_native_double,dataset,int(totalshape,hsize_t), hdferr,&
8100  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8101  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_real4: h5dwrite_f')
8102  endif
8103 
8104  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8105 
8106 end subroutine hdf5_write_real4
8107 
8108 
8109 !--------------------------------------------------------------------------------------------------
8111 !--------------------------------------------------------------------------------------------------
8112 subroutine hdf5_write_real5(loc_id,dataset,datasetName,parallel)
8114  real(pReal), intent(inout), dimension(:,:,:,:,:) :: dataset
8115  integer(HID_T), intent(in) :: loc_id
8116  character(len=*), intent(in) :: datasetName
8117  logical, intent(in), optional :: parallel
8118 
8119 
8120  integer :: hdferr
8121  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8122  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8123  myStart, &
8124  myShape, & !< shape of the dataset (this process)
8125  totalShape
8126 
8127 !---------------------------------------------------------------------------------------------------
8128 ! determine shape of dataset
8129  myshape = int(shape(dataset),hsize_t)
8130  if (any(myshape(1:size(myshape)-1) == 0)) return
8131 
8132  if (present(parallel)) then
8133  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8134  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,parallel)
8135  else
8136  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8137  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,.false.)
8138  endif
8139 
8140  if (product(totalshape) /= 0) then
8141  call h5dwrite_f(dset_id, h5t_native_double,dataset,int(totalshape,hsize_t), hdferr,&
8142  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8143  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_real5: h5dwrite_f')
8144  endif
8145 
8146  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8147 
8148 end subroutine hdf5_write_real5
8149 
8150 !--------------------------------------------------------------------------------------------------
8152 !--------------------------------------------------------------------------------------------------
8153 subroutine hdf5_write_real6(loc_id,dataset,datasetName,parallel)
8155  real(pReal), intent(inout), dimension(:,:,:,:,:,:) :: dataset
8156  integer(HID_T), intent(in) :: loc_id
8157  character(len=*), intent(in) :: datasetName
8158  logical, intent(in), optional :: parallel
8159 
8160 
8161  integer :: hdferr
8162  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8163  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8164  myStart, &
8165  myShape, & !< shape of the dataset (this process)
8166  totalShape
8167 
8168 !---------------------------------------------------------------------------------------------------
8169 ! determine shape of dataset
8170  myshape = int(shape(dataset),hsize_t)
8171  if (any(myshape(1:size(myshape)-1) == 0)) return
8172 
8173  if (present(parallel)) then
8174  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8175  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,parallel)
8176  else
8177  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8178  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,.false.)
8179  endif
8180 
8181  if (product(totalshape) /= 0) then
8182  call h5dwrite_f(dset_id, h5t_native_double,dataset,int(totalshape,hsize_t), hdferr,&
8183  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8184  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_real6: h5dwrite_f')
8185  endif
8186 
8187  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8188 
8189 end subroutine hdf5_write_real6
8190 
8191 !--------------------------------------------------------------------------------------------------
8193 !--------------------------------------------------------------------------------------------------
8194 subroutine hdf5_write_real7(loc_id,dataset,datasetName,parallel)
8196  real(pReal), intent(inout), dimension(:,:,:,:,:,:,:) :: dataset
8197  integer(HID_T), intent(in) :: loc_id
8198  character(len=*), intent(in) :: datasetName
8199  logical, intent(in), optional :: parallel
8200 
8201 
8202  integer :: hdferr
8203  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8204  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8205  myStart, &
8206  myShape, & !< shape of the dataset (this process)
8207  totalShape
8208 
8209 !---------------------------------------------------------------------------------------------------
8210 ! determine shape of dataset
8211  myshape = int(shape(dataset),hsize_t)
8212  if (any(myshape(1:size(myshape)-1) == 0)) return
8213 
8214  if (present(parallel)) then
8215  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8216  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,parallel)
8217  else
8218  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8219  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_double,.false.)
8220  endif
8221 
8222  if (product(totalshape) /= 0) then
8223  call h5dwrite_f(dset_id, h5t_native_double,dataset,int(totalshape,hsize_t), hdferr,&
8224  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8225  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_real7: h5dwrite_f')
8226  endif
8227 
8228  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8229 
8230 end subroutine hdf5_write_real7
8231 
8232 
8233 !--------------------------------------------------------------------------------------------------
8235 !--------------------------------------------------------------------------------------------------
8236 subroutine hdf5_write_int1(loc_id,dataset,datasetName,parallel)
8238  integer, intent(inout), dimension(:) :: dataset
8239  integer(HID_T), intent(in) :: loc_id
8240  character(len=*), intent(in) :: datasetName
8241  logical, intent(in), optional :: parallel
8242 
8243 
8244  integer :: hdferr
8245  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8246  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8247  myStart, &
8248  myShape, & !< shape of the dataset (this process)
8249  totalShape
8250 
8251 !---------------------------------------------------------------------------------------------------
8252 ! determine shape of dataset
8253  myshape = int(shape(dataset),hsize_t)
8254  if (any(myshape(1:size(myshape)-1) == 0)) return
8255 
8256  if (present(parallel)) then
8257  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8258  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,parallel)
8259  else
8260  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8261  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,.false.)
8262  endif
8263 
8264  if (product(totalshape) /= 0) then
8265  call h5dwrite_f(dset_id, h5t_native_integer,dataset,int(totalshape,hsize_t), hdferr,&
8266  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8267  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_int1: h5dwrite_f')
8268  endif
8269 
8270  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8271 
8272 end subroutine hdf5_write_int1
8273 
8274 !--------------------------------------------------------------------------------------------------
8276 !--------------------------------------------------------------------------------------------------
8277 subroutine hdf5_write_int2(loc_id,dataset,datasetName,parallel)
8279  integer, intent(inout), dimension(:,:) :: dataset
8280  integer(HID_T), intent(in) :: loc_id
8281  character(len=*), intent(in) :: datasetName
8282  logical, intent(in), optional :: parallel
8283 
8284 
8285  integer :: hdferr
8286  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8287  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8288  myStart, &
8289  myShape, & !< shape of the dataset (this process)
8290  totalShape
8291 
8292 !---------------------------------------------------------------------------------------------------
8293 ! determine shape of dataset
8294  myshape = int(shape(dataset),hsize_t)
8295  if (any(myshape(1:size(myshape)-1) == 0)) return
8296 
8297  if (present(parallel)) then
8298  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8299  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,parallel)
8300  else
8301  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8302  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,.false.)
8303  endif
8304 
8305  if (product(totalshape) /= 0) then
8306  call h5dwrite_f(dset_id, h5t_native_integer,dataset,int(totalshape,hsize_t), hdferr,&
8307  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8308  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_int2: h5dwrite_f')
8309  endif
8310 
8311  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8312 
8313 end subroutine hdf5_write_int2
8314 
8315 !--------------------------------------------------------------------------------------------------
8317 !--------------------------------------------------------------------------------------------------
8318 subroutine hdf5_write_int3(loc_id,dataset,datasetName,parallel)
8320  integer, intent(inout), dimension(:,:,:) :: dataset
8321  integer(HID_T), intent(in) :: loc_id
8322  character(len=*), intent(in) :: datasetName
8323  logical, intent(in), optional :: parallel
8324 
8325 
8326  integer :: hdferr
8327  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8328  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8329  myStart, &
8330  myShape, & !< shape of the dataset (this process)
8331  totalShape
8332 
8333 !---------------------------------------------------------------------------------------------------
8334 ! determine shape of dataset
8335  myshape = int(shape(dataset),hsize_t)
8336  if (any(myshape(1:size(myshape)-1) == 0)) return
8337 
8338  if (present(parallel)) then
8339  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8340  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,parallel)
8341  else
8342  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8343  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,.false.)
8344  endif
8345 
8346  if (product(totalshape) /= 0) then
8347  call h5dwrite_f(dset_id, h5t_native_integer,dataset,int(totalshape,hsize_t), hdferr,&
8348  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8349  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_int3: h5dwrite_f')
8350  endif
8351 
8352  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8353 
8354 end subroutine hdf5_write_int3
8355 
8356 !--------------------------------------------------------------------------------------------------
8358 !--------------------------------------------------------------------------------------------------
8359 subroutine hdf5_write_int4(loc_id,dataset,datasetName,parallel)
8361  integer, intent(inout), dimension(:,:,:,:) :: dataset
8362  integer(HID_T), intent(in) :: loc_id
8363  character(len=*), intent(in) :: datasetName
8364  logical, intent(in), optional :: parallel
8365 
8366 
8367  integer :: hdferr
8368  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8369  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8370  myStart, &
8371  myShape, & !< shape of the dataset (this process)
8372  totalShape
8373 
8374 !---------------------------------------------------------------------------------------------------
8375 ! determine shape of dataset
8376  myshape = int(shape(dataset),hsize_t)
8377  if (any(myshape(1:size(myshape)-1) == 0)) return
8378 
8379  if (present(parallel)) then
8380  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8381  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,parallel)
8382  else
8383  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8384  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,.false.)
8385  endif
8386 
8387  if (product(totalshape) /= 0) then
8388  call h5dwrite_f(dset_id, h5t_native_integer,dataset,int(totalshape,hsize_t), hdferr,&
8389  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8390  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_int4: h5dwrite_f')
8391  endif
8392 
8393  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8394 
8395 end subroutine hdf5_write_int4
8396 
8397 !--------------------------------------------------------------------------------------------------
8399 !--------------------------------------------------------------------------------------------------
8400 subroutine hdf5_write_int5(loc_id,dataset,datasetName,parallel)
8402  integer, intent(inout), dimension(:,:,:,:,:) :: dataset
8403  integer(HID_T), intent(in) :: loc_id
8404  character(len=*), intent(in) :: datasetName
8405  logical, intent(in), optional :: parallel
8406 
8407 
8408  integer :: hdferr
8409  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8410  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8411  myStart, &
8412  myShape, & !< shape of the dataset (this process)
8413  totalShape
8414 
8415 !---------------------------------------------------------------------------------------------------
8416 ! determine shape of dataset
8417  myshape = int(shape(dataset),hsize_t)
8418  if (any(myshape(1:size(myshape)-1) == 0)) return
8419 
8420  if (present(parallel)) then
8421  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8422  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,parallel)
8423  else
8424  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8425  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,.false.)
8426  endif
8427 
8428  if (product(totalshape) /= 0) then
8429  call h5dwrite_f(dset_id, h5t_native_integer,dataset,int(totalshape,hsize_t), hdferr,&
8430  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8431  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_int5: h5dwrite_f')
8432  endif
8433 
8434  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8435 
8436 end subroutine hdf5_write_int5
8437 
8438 !--------------------------------------------------------------------------------------------------
8440 !--------------------------------------------------------------------------------------------------
8441 subroutine hdf5_write_int6(loc_id,dataset,datasetName,parallel)
8443  integer, intent(inout), dimension(:,:,:,:,:,:) :: dataset
8444  integer(HID_T), intent(in) :: loc_id
8445  character(len=*), intent(in) :: datasetName
8446  logical, intent(in), optional :: parallel
8447 
8448 
8449  integer :: hdferr
8450  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8451  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8452  myStart, &
8453  myShape, & !< shape of the dataset (this process)
8454  totalShape
8455 
8456 !---------------------------------------------------------------------------------------------------
8457 ! determine shape of dataset
8458  myshape = int(shape(dataset),hsize_t)
8459  if (any(myshape(1:size(myshape)-1) == 0)) return
8460 
8461  if (present(parallel)) then
8462  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8463  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,parallel)
8464  else
8465  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8466  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,.false.)
8467  endif
8468 
8469  if (product(totalshape) /= 0) then
8470  call h5dwrite_f(dset_id, h5t_native_integer,dataset,int(totalshape,hsize_t), hdferr,&
8471  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8472  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_int6: h5dwrite_f')
8473  endif
8474 
8475  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8476 
8477 end subroutine hdf5_write_int6
8478 
8479 !--------------------------------------------------------------------------------------------------
8481 !--------------------------------------------------------------------------------------------------
8482 subroutine hdf5_write_int7(loc_id,dataset,datasetName,parallel)
8484  integer, intent(inout), dimension(:,:,:,:,:,:,:) :: dataset
8485  integer(HID_T), intent(in) :: loc_id
8486  character(len=*), intent(in) :: datasetName
8487  logical, intent(in), optional :: parallel
8488 
8489 
8490  integer :: hdferr
8491  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id
8492  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8493  myStart, &
8494  myShape, & !< shape of the dataset (this process)
8495  totalShape
8496 
8497 !---------------------------------------------------------------------------------------------------
8498 ! determine shape of dataset
8499  myshape = int(shape(dataset),hsize_t)
8500  if (any(myshape(1:size(myshape)-1) == 0)) return
8501 
8502  if (present(parallel)) then
8503  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8504  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,parallel)
8505  else
8506  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8507  mystart, totalshape, loc_id,myshape,datasetname,h5t_native_integer,.false.)
8508  endif
8509 
8510  if (product(totalshape) /= 0) then
8511  call h5dwrite_f(dset_id, h5t_native_integer,dataset,int(totalshape,hsize_t), hdferr,&
8512  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8513  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_int7: h5dwrite_f')
8514  endif
8515 
8516  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8517 
8518 end subroutine hdf5_write_int7
8519 
8520 
8521 !--------------------------------------------------------------------------------------------------
8523 ! ToDo: It might be possible to write the dataset as a whole
8524 ! ToDo: We could optionally write out other representations (axis angle, euler, ...)
8525 !--------------------------------------------------------------------------------------------------
8526 subroutine hdf5_write_rotation(loc_id,dataset,datasetName,parallel)
8528  type(rotation), intent(in), dimension(:) :: dataset
8529  integer(HID_T), intent(in) :: loc_id
8530  character(len=*), intent(in) :: datasetName
8531  logical, intent(in), optional :: parallel
8532 
8533  integer :: hdferr
8534  real(pReal), dimension(4,size(dataset)) :: dataset_asArray
8535  integer(HID_T) :: dset_id, filespace_id, memspace_id, plist_id,dtype_id,w_id,x_id,y_id,z_id
8536  integer(HSIZE_T), dimension(size(shape(dataset))) :: &
8537  myStart, &
8538  myShape, & !< shape of the dataset (this process)
8539  totalShape
8540  integer(SIZE_T) :: type_size_real
8541  integer :: i
8542 
8543  do i = 1, size(dataset)
8544  dataset_asarray(1:4,i) = dataset(i)%asQuaternion()
8545  enddo
8546 
8547 !---------------------------------------------------------------------------------------------------
8548 ! determine shape of dataset
8549  myshape = int(shape(dataset),hsize_t)
8550 
8551 !---------------------------------------------------------------------------------------------------
8552 ! compound type: name of each quaternion component
8553  call h5tget_size_f(h5t_native_double, type_size_real, hdferr)
8554 
8555  call h5tcreate_f(h5t_compound_f, type_size_real*4_size_t, dtype_id, hdferr)
8556  call h5tinsert_f(dtype_id, "w", type_size_real*0_size_t, h5t_native_double, hdferr)
8557  call h5tinsert_f(dtype_id, "x", type_size_real*1_size_t, h5t_native_double, hdferr)
8558  call h5tinsert_f(dtype_id, "y", type_size_real*2_size_t, h5t_native_double, hdferr)
8559  call h5tinsert_f(dtype_id, "z", type_size_real*3_size_t, h5t_native_double, hdferr)
8560 
8561  if (present(parallel)) then
8562  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8563  mystart, totalshape, loc_id,myshape,datasetname,dtype_id,parallel)
8564  else
8565  call initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8566  mystart, totalshape, loc_id,myshape,datasetname,dtype_id,.false.)
8567  endif
8568 
8569  call h5pset_preserve_f(plist_id, .true., hdferr)
8570 
8571  if (product(totalshape) /= 0) then
8572  call h5tcreate_f(h5t_compound_f, type_size_real, x_id, hdferr)
8573  call h5tinsert_f(x_id, "x", 0_size_t, h5t_native_double, hdferr)
8574  call h5tcreate_f(h5t_compound_f, type_size_real, w_id, hdferr)
8575  call h5tinsert_f(w_id, "w", 0_size_t, h5t_native_double, hdferr)
8576  call h5tcreate_f(h5t_compound_f, type_size_real, y_id, hdferr)
8577  call h5tinsert_f(y_id, "y", 0_size_t, h5t_native_double, hdferr)
8578  call h5tcreate_f(h5t_compound_f, type_size_real, z_id, hdferr)
8579  call h5tinsert_f(z_id, "z", 0_size_t, h5t_native_double, hdferr)
8580 
8581  call h5dwrite_f(dset_id, w_id,dataset_asarray(1,:),int(totalshape,hsize_t), hdferr,&
8582  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8583  call h5dwrite_f(dset_id, x_id,dataset_asarray(2,:),int(totalshape,hsize_t), hdferr,&
8584  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8585  call h5dwrite_f(dset_id, y_id,dataset_asarray(3,:),int(totalshape,hsize_t), hdferr,&
8586  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8587  call h5dwrite_f(dset_id, z_id,dataset_asarray(4,:),int(totalshape,hsize_t), hdferr,&
8588  file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
8589  if (hdferr < 0) call io_error(1,ext_msg='HDF5_write_rotation: h5dwrite_f')
8590  endif
8591 
8592  call finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8593 
8594 end subroutine hdf5_write_rotation
8595 
8596 
8597 !--------------------------------------------------------------------------------------------------
8599 !--------------------------------------------------------------------------------------------------
8600 subroutine initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, &
8601  myStart, globalShape, &
8602  loc_id,localShape,datasetName,parallel)
8604  integer(HID_T), intent(in) :: loc_id
8605  character(len=*), intent(in) :: datasetName
8606  logical, intent(in) :: parallel
8607  integer(HSIZE_T), intent(in), dimension(:) :: &
8608  localShape
8609  integer(HSIZE_T), intent(out), dimension(size(localShape,1)):: &
8610  myStart, &
8611  globalShape
8612  integer(HID_T), intent(out) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
8613 
8614  integer, dimension(worldsize) :: &
8615  readSize
8616  integer :: ierr
8617  integer :: hdferr
8618 
8619 !-------------------------------------------------------------------------------------------------
8620 ! creating a property list for transfer properties (is collective for MPI)
8621  call h5pcreate_f(h5p_dataset_xfer_f, plist_id, hdferr)
8622  if (hdferr < 0) call io_error(1,ext_msg='initialize_read: h5pcreate_f')
8623 
8624 !--------------------------------------------------------------------------------------------------
8625  readsize = 0
8626  readsize(worldrank+1) = int(localshape(ubound(localshape,1)))
8627 # 1777 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/HDF5_utilities.f90"
8628  mystart = int(0,hsize_t)
8629  mystart(ubound(mystart)) = int(sum(readsize(1:worldrank)),hsize_t)
8630  globalshape = [localshape(1:ubound(localshape,1)-1),int(sum(readsize),hsize_t)]
8631 
8632 !--------------------------------------------------------------------------------------------------
8633 ! create dataspace in memory (local shape)
8634  call h5screate_simple_f(size(localshape), localshape, memspace_id, hdferr, localshape)
8635  if (hdferr < 0) call io_error(1,ext_msg='initialize_read: h5screate_simple_f/memspace_id')
8636 
8637 !--------------------------------------------------------------------------------------------------
8638 ! creating a property list for IO and set it to collective
8639  call h5pcreate_f(h5p_dataset_access_f, aplist_id, hdferr)
8640  if (hdferr < 0) call io_error(1,ext_msg='initialize_read: h5pcreate_f')
8641 
8642 
8643 
8644 
8645 
8646 !--------------------------------------------------------------------------------------------------
8647 ! open the dataset in the file and get the space ID
8648  call h5dopen_f(loc_id,datasetname,dset_id,hdferr, dapl_id = aplist_id)
8649  if (hdferr < 0) call io_error(1,ext_msg='initialize_read: h5dopen_f')
8650  call h5dget_space_f(dset_id, filespace_id, hdferr)
8651  if (hdferr < 0) call io_error(1,ext_msg='initialize_read: h5dget_space_f')
8652 
8653 !--------------------------------------------------------------------------------------------------
8654 ! select a hyperslab (the portion of the current process) in the file
8655  call h5sselect_hyperslab_f(filespace_id, h5s_select_set_f, mystart, localshape, hdferr)
8656  if (hdferr < 0) call io_error(1,ext_msg='initialize_read: h5sselect_hyperslab_f')
8657 
8658 end subroutine initialize_read
8659 
8660 
8661 !--------------------------------------------------------------------------------------------------
8663 !--------------------------------------------------------------------------------------------------
8664 subroutine finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
8666  integer(HID_T), intent(in) :: dset_id, filespace_id, memspace_id, plist_id, aplist_id
8667  integer :: hdferr
8668 
8669  call h5pclose_f(plist_id, hdferr)
8670  if (hdferr < 0) call io_error(1,ext_msg='finalize_read: plist_id')
8671  call h5pclose_f(aplist_id, hdferr)
8672  if (hdferr < 0) call io_error(1,ext_msg='finalize_read: aplist_id')
8673  call h5dclose_f(dset_id, hdferr)
8674  if (hdferr < 0) call io_error(1,ext_msg='finalize_read: h5dclose_f')
8675  call h5sclose_f(filespace_id, hdferr)
8676  if (hdferr < 0) call io_error(1,ext_msg='finalize_read: h5sclose_f/filespace_id')
8677  call h5sclose_f(memspace_id, hdferr)
8678  if (hdferr < 0) call io_error(1,ext_msg='finalize_read: h5sclose_f/memspace_id')
8679 
8680 end subroutine finalize_read
8681 
8682 
8683 !--------------------------------------------------------------------------------------------------
8685 !--------------------------------------------------------------------------------------------------
8686 subroutine initialize_write(dset_id, filespace_id, memspace_id, plist_id, &
8687  myStart, totalShape, &
8688  loc_id,myShape,datasetName,datatype,parallel)
8690  integer(HID_T), intent(in) :: loc_id
8691  character(len=*), intent(in) :: datasetName
8692  logical, intent(in) :: parallel
8693  integer(HID_T), intent(in) :: datatype
8694  integer(HSIZE_T), intent(in), dimension(:) :: &
8695  myShape
8696  integer(HSIZE_T), intent(out), dimension(size(myShape,1)):: &
8697  myStart, &
8698  totalShape
8699  integer(HID_T), intent(out) :: dset_id, filespace_id, memspace_id, plist_id
8700 
8701  integer, dimension(worldsize) :: &
8702  writeSize
8703  integer :: ierr
8704  integer :: hdferr
8705 
8706 !-------------------------------------------------------------------------------------------------
8707 ! creating a property list for transfer properties (is collective when reading in parallel)
8708  call h5pcreate_f(h5p_dataset_xfer_f, plist_id, hdferr)
8709  if (hdferr < 0) call io_error(1,ext_msg='initialize_write: h5pcreate_f')
8710 
8711 
8712 
8713 
8714 
8715 
8716 
8717 !--------------------------------------------------------------------------------------------------
8718 ! determine the global data layout among all processes
8719  writesize = 0
8720  writesize(worldrank+1) = int(myshape(ubound(myshape,1)))
8721 
8722 
8723 
8724 
8725 
8726 
8727  mystart = int(0,hsize_t)
8728  mystart(ubound(mystart)) = int(sum(writesize(1:worldrank)),hsize_t)
8729  totalshape = [myshape(1:ubound(myshape,1)-1),int(sum(writesize),hsize_t)]
8730 
8731 !--------------------------------------------------------------------------------------------------
8732 ! create dataspace in memory (local shape) and in file (global shape)
8733  call h5screate_simple_f(size(myshape), myshape, memspace_id, hdferr, myshape)
8734  if (hdferr < 0) call io_error(1,ext_msg='initialize_write: h5dopen_f')
8735  call h5screate_simple_f(size(totalshape), totalshape, filespace_id, hdferr, totalshape)
8736  if (hdferr < 0) call io_error(1,ext_msg='initialize_write: h5dget_space_f')
8737 
8738 !--------------------------------------------------------------------------------------------------
8739 ! create dataset in the file and select a hyperslab from it (the portion of the current process)
8740  call h5dcreate_f(loc_id, trim(datasetname), datatype, filespace_id, dset_id, hdferr)
8741  if (hdferr < 0) call io_error(1,ext_msg='initialize_write: h5dcreate_f')
8742  call h5sselect_hyperslab_f(filespace_id, h5s_select_set_f, mystart, myshape, hdferr)
8743  if (hdferr < 0) call io_error(1,ext_msg='initialize_write: h5sselect_hyperslab_f')
8744 
8745 end subroutine initialize_write
8746 
8747 
8748 !--------------------------------------------------------------------------------------------------
8750 !--------------------------------------------------------------------------------------------------
8751 subroutine finalize_write(plist_id, dset_id, filespace_id, memspace_id)
8753  integer(HID_T), intent(in) :: dset_id, filespace_id, memspace_id, plist_id
8754  integer :: hdferr
8755 
8756  call h5pclose_f(plist_id, hdferr)
8757  if (hdferr < 0) call io_error(1,ext_msg='finalize_write: plist_id')
8758  call h5dclose_f(dset_id, hdferr)
8759  if (hdferr < 0) call io_error(1,ext_msg='finalize_write: h5dclose_f')
8760  call h5sclose_f(filespace_id, hdferr)
8761  if (hdferr < 0) call io_error(1,ext_msg='finalize_write: h5sclose_f/filespace_id')
8762  call h5sclose_f(memspace_id, hdferr)
8763  if (hdferr < 0) call io_error(1,ext_msg='finalize_write: h5sclose_f/memspace_id')
8764 
8765 end subroutine finalize_write
8766 
8767 end module hdf5_utilities
8768 # 19 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
8769 
8770 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/results.f90" 1
8771 !--------------------------------------------------------------------------------------------------
8776 !--------------------------------------------------------------------------------------------------
8777 module results
8778  use damask_interface
8779  use rotations
8780  use numerics
8781  use hdf5_utilities
8782 
8783 
8784 
8785 
8786  implicit none
8787  private
8788 
8789  integer(HID_T) :: resultsfile
8790 
8792 
8793  module procedure results_writetensordataset_real
8794  module procedure results_writevectordataset_real
8795  module procedure results_writescalardataset_real
8796 
8797  module procedure results_writetensordataset_int
8798  module procedure results_writevectordataset_int
8799 
8800  module procedure results_writescalardataset_rotation
8801 
8802  end interface results_writedataset
8803 
8805 
8806  module procedure results_addattribute_real
8807  module procedure results_addattribute_int
8808  module procedure results_addattribute_str
8809 
8810  module procedure results_addattribute_int_array
8811  module procedure results_addattribute_real_array
8812 
8813  end interface results_addattribute
8814 
8815  public :: &
8816  results_init, &
8821  results_addgroup, &
8825  results_setlink, &
8830 contains
8831 
8832 subroutine results_init
8834  character(len=pStringLen) :: commandline
8835 
8836  write(6,'(/,a)') ' <<<+- results init -+>>>'
8837 
8838  write(6,'(/,a)') ' Diehl et al., Integrating Materials and Manufacturing Innovation 6(1):83–91, 2017'
8839  write(6,'(a)') ' https://doi.org/10.1007/s40192-017-0084-5'
8840 
8841  resultsfile = hdf5_openfile(trim(getsolverjobname())//'.hdf5','w',.true.)
8842  call results_addattribute('DADF5_version_major',0)
8843  call results_addattribute('DADF5_version_minor',6)
8844  call results_addattribute('DAMASK_version',damaskversion)
8845  call get_command(commandline)
8846  call results_addattribute('call',trim(commandline))
8847  call results_closegroup(results_addgroup('mapping'))
8848  call results_closegroup(results_addgroup('mapping/cellResults'))
8850 
8851 end subroutine results_init
8852 
8853 
8854 !--------------------------------------------------------------------------------------------------
8856 !--------------------------------------------------------------------------------------------------
8857 subroutine results_openjobfile
8859  resultsfile = hdf5_openfile(trim(getsolverjobname())//'.hdf5','a',.true.)
8860 
8861 end subroutine results_openjobfile
8862 
8863 
8864 !--------------------------------------------------------------------------------------------------
8866 !--------------------------------------------------------------------------------------------------
8867 subroutine results_closejobfile
8870 
8871 end subroutine results_closejobfile
8872 
8873 
8874 !--------------------------------------------------------------------------------------------------
8876 !--------------------------------------------------------------------------------------------------
8877 subroutine results_addincrement(inc,time)
8879  integer, intent(in) :: inc
8880  real(preal), intent(in) :: time
8881  character(len=pStringLen) :: incchar
8882 
8883  write(incchar,'(i10)') inc
8884  call results_closegroup(results_addgroup(trim('inc'//trim(adjustl(incchar)))))
8885  call results_setlink(trim('inc'//trim(adjustl(incchar))),'current')
8886  call results_addattribute('time/s',time,trim('inc'//trim(adjustl(incchar))))
8887  call results_closegroup(results_addgroup('current/constituent'))
8888  call results_closegroup(results_addgroup('current/materialpoint'))
8889 
8890 end subroutine results_addincrement
8891 
8892 
8893 !--------------------------------------------------------------------------------------------------
8896 !--------------------------------------------------------------------------------------------------
8897 subroutine results_finalizeincrement
8899  call results_removelink('current')
8900 
8901 end subroutine results_finalizeincrement
8902 
8903 
8904 !--------------------------------------------------------------------------------------------------
8906 !--------------------------------------------------------------------------------------------------
8907 integer(HID_T) function results_opengroup(groupName)
8909  character(len=*), intent(in) :: groupname
8910 
8912 
8913 end function results_opengroup
8914 
8915 
8916 !--------------------------------------------------------------------------------------------------
8918 !--------------------------------------------------------------------------------------------------
8919 integer(HID_T) function results_addgroup(groupName)
8921  character(len=*), intent(in) :: groupname
8922 
8924 
8925 end function results_addgroup
8926 
8927 
8928 !--------------------------------------------------------------------------------------------------
8930 !--------------------------------------------------------------------------------------------------
8931 subroutine results_closegroup(group_id)
8933  integer(HID_T), intent(in) :: group_id
8934 
8935  call hdf5_closegroup(group_id)
8936 
8937 end subroutine results_closegroup
8938 
8939 
8940 !--------------------------------------------------------------------------------------------------
8942 !--------------------------------------------------------------------------------------------------
8943 subroutine results_setlink(path,link)
8945  character(len=*), intent(in) :: path, link
8946 
8947  call hdf5_setlink(resultsfile,path,link)
8948 
8949 end subroutine results_setlink
8950 
8951 
8952 !--------------------------------------------------------------------------------------------------
8954 !--------------------------------------------------------------------------------------------------
8955 subroutine results_addattribute_str(attrLabel,attrValue,path)
8957  character(len=*), intent(in) :: attrLabel, attrValue
8958  character(len=*), intent(in), optional :: path
8959 
8960  if (present(path)) then
8961  call hdf5_addattribute(resultsfile,attrlabel, attrvalue, path)
8962  else
8963  call hdf5_addattribute(resultsfile,attrlabel, attrvalue)
8964  endif
8965 
8966 end subroutine results_addattribute_str
8967 
8968 
8969 !--------------------------------------------------------------------------------------------------
8971 !--------------------------------------------------------------------------------------------------
8972 subroutine results_addattribute_int(attrLabel,attrValue,path)
8974  character(len=*), intent(in) :: attrLabel
8975  integer, intent(in) :: attrValue
8976  character(len=*), intent(in), optional :: path
8977 
8978  if (present(path)) then
8979  call hdf5_addattribute(resultsfile,attrlabel, attrvalue, path)
8980  else
8981  call hdf5_addattribute(resultsfile,attrlabel, attrvalue)
8982  endif
8983 
8984 end subroutine results_addattribute_int
8985 
8986 
8987 !--------------------------------------------------------------------------------------------------
8989 !--------------------------------------------------------------------------------------------------
8990 subroutine results_addattribute_real(attrLabel,attrValue,path)
8992  character(len=*), intent(in) :: attrLabel
8993  real(pReal), intent(in) :: attrValue
8994  character(len=*), intent(in), optional :: path
8995 
8996  if (present(path)) then
8997  call hdf5_addattribute(resultsfile,attrlabel, attrvalue, path)
8998  else
8999  call hdf5_addattribute(resultsfile,attrlabel, attrvalue)
9000  endif
9001 
9002 end subroutine results_addattribute_real
9003 
9004 
9005 !--------------------------------------------------------------------------------------------------
9007 !--------------------------------------------------------------------------------------------------
9008 subroutine results_addattribute_int_array(attrLabel,attrValue,path)
9010  character(len=*), intent(in) :: attrLabel
9011  integer, intent(in), dimension(:) :: attrValue
9012  character(len=*), intent(in), optional :: path
9013 
9014  if (present(path)) then
9015  call hdf5_addattribute(resultsfile,attrlabel, attrvalue, path)
9016  else
9017  call hdf5_addattribute(resultsfile,attrlabel, attrvalue)
9018  endif
9019 
9020 end subroutine results_addattribute_int_array
9021 
9022 
9023 !--------------------------------------------------------------------------------------------------
9025 !--------------------------------------------------------------------------------------------------
9026 subroutine results_addattribute_real_array(attrLabel,attrValue,path)
9028  character(len=*), intent(in) :: attrLabel
9029  real(pReal), intent(in), dimension(:) :: attrValue
9030  character(len=*), intent(in), optional :: path
9031 
9032  if (present(path)) then
9033  call hdf5_addattribute(resultsfile,attrlabel, attrvalue, path)
9034  else
9035  call hdf5_addattribute(resultsfile,attrlabel, attrvalue)
9036  endif
9037 
9038 end subroutine results_addattribute_real_array
9039 
9040 
9041 !--------------------------------------------------------------------------------------------------
9043 !--------------------------------------------------------------------------------------------------
9044 subroutine results_removelink(link)
9046  character(len=*), intent(in) :: link
9047  integer :: hdferr
9048 
9049  call h5ldelete_f(resultsfile,link, hdferr)
9050  if (hdferr < 0) call io_error(1,ext_msg = 'results_removeLink: h5ldelete_soft_f ('//trim(link)//')')
9051 
9052 end subroutine results_removelink
9053 
9054 
9055 !--------------------------------------------------------------------------------------------------
9057 !--------------------------------------------------------------------------------------------------
9058 subroutine results_writescalardataset_real(group,dataset,label,description,SIunit)
9060  character(len=*), intent(in) :: label,group,description
9061  character(len=*), intent(in), optional :: SIunit
9062  real(pReal), intent(inout), dimension(:) :: dataset
9063 
9064  integer(HID_T) :: groupHandle
9065 
9066  grouphandle = results_opengroup(group)
9067 
9068 
9069 
9070 
9071  call hdf5_write(grouphandle,dataset,label,.false.)
9072 
9073 
9074  if (hdf5_objectexists(grouphandle,label)) &
9075  call hdf5_addattribute(grouphandle,'Description',description,label)
9076  if (hdf5_objectexists(grouphandle,label) .and. present(siunit)) &
9077  call hdf5_addattribute(grouphandle,'Unit',siunit,label)
9078  if (hdf5_objectexists(grouphandle,label)) &
9079  call hdf5_addattribute(grouphandle,'Creator','DAMASK '//damaskversion,label)
9080  call hdf5_closegroup(grouphandle)
9081 
9082 end subroutine results_writescalardataset_real
9083 
9084 !--------------------------------------------------------------------------------------------------
9086 !--------------------------------------------------------------------------------------------------
9087 subroutine results_writevectordataset_real(group,dataset,label,description,SIunit)
9089  character(len=*), intent(in) :: label,group,description
9090  character(len=*), intent(in), optional :: SIunit
9091  real(pReal), intent(inout), dimension(:,:) :: dataset
9092 
9093  integer(HID_T) :: groupHandle
9094 
9095  grouphandle = results_opengroup(group)
9096 
9097 
9098 
9099 
9100  call hdf5_write(grouphandle,dataset,label,.false.)
9101 
9102 
9103  if (hdf5_objectexists(grouphandle,label)) &
9104  call hdf5_addattribute(grouphandle,'Description',description,label)
9105  if (hdf5_objectexists(grouphandle,label) .and. present(siunit)) &
9106  call hdf5_addattribute(grouphandle,'Unit',siunit,label)
9107  if (hdf5_objectexists(grouphandle,label)) &
9108  call hdf5_addattribute(grouphandle,'Creator','DAMASK '//damaskversion,label)
9109  call hdf5_closegroup(grouphandle)
9110 
9111 end subroutine results_writevectordataset_real
9112 
9113 
9114 !--------------------------------------------------------------------------------------------------
9116 !--------------------------------------------------------------------------------------------------
9117 subroutine results_writetensordataset_real(group,dataset,label,description,SIunit,transposed)
9119  character(len=*), intent(in) :: label,group,description
9120  character(len=*), intent(in), optional :: SIunit
9121  logical, intent(in), optional :: transposed
9122  real(pReal), intent(in), dimension(:,:,:) :: dataset
9123 
9124  integer :: i
9125  logical :: transposed_
9126  integer(HID_T) :: groupHandle
9127  real(pReal), dimension(:,:,:), allocatable :: dataset_transposed
9128 
9129 
9130  if(present(transposed)) then
9131  transposed_ = transposed
9132  else
9133  transposed_ = .true.
9134  endif
9135 
9136  if(transposed_) then
9137  if(size(dataset,1) /= size(dataset,2)) call io_error(0,ext_msg='transpose non-symmetric tensor')
9138  allocate(dataset_transposed,mold=dataset)
9139  do i=1,size(dataset_transposed,3)
9140  dataset_transposed(:,:,i) = transpose(dataset(:,:,i))
9141  enddo
9142  else
9143  allocate(dataset_transposed,source=dataset)
9144  endif
9145 
9146  grouphandle = results_opengroup(group)
9147 
9148 
9149 
9150 
9151  call hdf5_write(grouphandle,dataset_transposed,label,.false.)
9152 
9153 
9154  if (hdf5_objectexists(grouphandle,label)) &
9155  call hdf5_addattribute(grouphandle,'Description',description,label)
9156  if (hdf5_objectexists(grouphandle,label) .and. present(siunit)) &
9157  call hdf5_addattribute(grouphandle,'Unit',siunit,label)
9158  if (hdf5_objectexists(grouphandle,label)) &
9159  call hdf5_addattribute(grouphandle,'Creator','DAMASK '//damaskversion,label)
9160  call hdf5_closegroup(grouphandle)
9161 
9162 end subroutine results_writetensordataset_real
9163 
9164 
9165 !--------------------------------------------------------------------------------------------------
9167 !--------------------------------------------------------------------------------------------------
9168 subroutine results_writevectordataset_int(group,dataset,label,description,SIunit)
9170  character(len=*), intent(in) :: label,group,description
9171  character(len=*), intent(in), optional :: SIunit
9172  integer, intent(inout), dimension(:,:) :: dataset
9173 
9174  integer(HID_T) :: groupHandle
9175 
9176  grouphandle = results_opengroup(group)
9177 
9178 
9179 
9180 
9181  call hdf5_write(grouphandle,dataset,label,.false.)
9182 
9183 
9184  if (hdf5_objectexists(grouphandle,label)) &
9185  call hdf5_addattribute(grouphandle,'Description',description,label)
9186  if (hdf5_objectexists(grouphandle,label) .and. present(siunit)) &
9187  call hdf5_addattribute(grouphandle,'Unit',siunit,label)
9188  if (hdf5_objectexists(grouphandle,label)) &
9189  call hdf5_addattribute(grouphandle,'Creator','DAMASK '//damaskversion,label)
9190  call hdf5_closegroup(grouphandle)
9191 
9192 end subroutine results_writevectordataset_int
9193 
9194 
9195 !--------------------------------------------------------------------------------------------------
9197 !--------------------------------------------------------------------------------------------------
9198 subroutine results_writetensordataset_int(group,dataset,label,description,SIunit)
9200  character(len=*), intent(in) :: label,group,description
9201  character(len=*), intent(in), optional :: SIunit
9202  integer, intent(inout), dimension(:,:,:) :: dataset
9203 
9204  integer(HID_T) :: groupHandle
9205 
9206  grouphandle = results_opengroup(group)
9207 
9208 
9209 
9210 
9211  call hdf5_write(grouphandle,dataset,label,.false.)
9212 
9213 
9214  if (hdf5_objectexists(grouphandle,label)) &
9215  call hdf5_addattribute(grouphandle,'Description',description,label)
9216  if (hdf5_objectexists(grouphandle,label) .and. present(siunit)) &
9217  call hdf5_addattribute(grouphandle,'Unit',siunit,label)
9218  if (hdf5_objectexists(grouphandle,label)) &
9219  call hdf5_addattribute(grouphandle,'Creator','DAMASK '//damaskversion,label)
9220  call hdf5_closegroup(grouphandle)
9221 
9222 end subroutine results_writetensordataset_int
9223 
9224 
9225 !--------------------------------------------------------------------------------------------------
9227 !--------------------------------------------------------------------------------------------------
9228 subroutine results_writescalardataset_rotation(group,dataset,label,description,lattice_structure)
9230  character(len=*), intent(in) :: label,group,description
9231  character(len=*), intent(in), optional :: lattice_structure
9232  type(rotation), intent(inout), dimension(:) :: dataset
9233 
9234  integer(HID_T) :: groupHandle
9235 
9236  grouphandle = results_opengroup(group)
9237 
9238 
9239 
9240 
9241  call hdf5_write(grouphandle,dataset,label,.false.)
9242 
9243 
9244  if (hdf5_objectexists(grouphandle,label)) &
9245  call hdf5_addattribute(grouphandle,'Description',description,label)
9246  if (hdf5_objectexists(grouphandle,label) .and. present(lattice_structure)) &
9247  call hdf5_addattribute(grouphandle,'Lattice',lattice_structure,label)
9248  if (hdf5_objectexists(grouphandle,label)) &
9249  call hdf5_addattribute(grouphandle,'Creator','DAMASK '//damaskversion,label)
9250  call hdf5_closegroup(grouphandle)
9251 
9253 
9254 
9255 !--------------------------------------------------------------------------------------------------
9257 !--------------------------------------------------------------------------------------------------
9258 subroutine results_mapping_constituent(phaseAt,memberAtLocal,label)
9260  integer, dimension(:,:), intent(in) :: phaseat
9261  integer, dimension(:,:,:), intent(in) :: memberatlocal
9262  character(len=pStringLen), dimension(:), intent(in) :: label
9263 
9264  integer, dimension(size(memberAtLocal,1),size(memberAtLocal,2),size(memberAtLocal,3)) :: &
9265  phaseatmaterialpoint, &
9266  memberatglobal
9267  integer, dimension(size(label),0:worldsize-1) :: memberoffset
9268  integer, dimension(0:worldsize-1) :: writesize
9269  integer(HSIZE_T), dimension(2) :: &
9270  myshape, & !< shape of the dataset (this process)
9271  myoffset, &
9272  totalshape
9273 
9274  integer(HID_T) :: &
9275  loc_id, & !< identifier of group in file
9276  dtype_id, & !< identifier of compound data type
9277  name_id, & !< identifier of name (string) in compound data type
9278  position_id, & !< identifier of position/index (integer) in compound data type
9279  dset_id, &
9280  memspace_id, &
9281  filespace_id, &
9282  plist_id, &
9283  dt_id
9284 
9285 
9286  integer(SIZE_T) :: type_size_string, type_size_int
9287  integer :: ierr, i
9288 
9289 !---------------------------------------------------------------------------------------------------
9290 ! compound type: name of phase section + position/index within results array
9291  call h5tcopy_f(h5t_native_character, dt_id, ierr)
9292  call h5tset_size_f(dt_id, int(len(label(1)),size_t), ierr)
9293  call h5tget_size_f(dt_id, type_size_string, ierr)
9294 
9295  call h5tget_size_f(h5t_native_integer, type_size_int, ierr)
9296 
9297  call h5tcreate_f(h5t_compound_f, type_size_string + type_size_int, dtype_id, ierr)
9298  call h5tinsert_f(dtype_id, "Name", 0_size_t, dt_id,ierr)
9299  call h5tinsert_f(dtype_id, "Position", type_size_string, h5t_native_integer, ierr)
9300 
9301 !--------------------------------------------------------------------------------------------------
9302 ! create memory types for each component of the compound type
9303  call h5tcreate_f(h5t_compound_f, type_size_string, name_id, ierr)
9304  call h5tinsert_f(name_id, "Name", 0_size_t, dt_id, ierr)
9305 
9306  call h5tcreate_f(h5t_compound_f, type_size_int, position_id, ierr)
9307  call h5tinsert_f(position_id, "Position", 0_size_t, h5t_native_integer, ierr)
9308 
9309  call h5tclose_f(dt_id, ierr)
9310 
9311 !--------------------------------------------------------------------------------------------------
9312 ! prepare MPI communication (transparent for non-MPI runs)
9313  call h5pcreate_f(h5p_dataset_xfer_f, plist_id, ierr)
9314  memberoffset = 0
9315  do i=1, size(label)
9316  memberoffset(i,worldrank) = count(phaseat == i)*size(memberatlocal,2) ! number of points/instance of this process
9317  enddo
9318  writesize = 0
9319  writesize(worldrank) = size(memberatlocal(1,:,:)) ! total number of points by this process
9320 
9321 !--------------------------------------------------------------------------------------------------
9322 ! MPI settings and communication
9323 # 563 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/results.f90"
9324 
9325  myshape = int([size(phaseat,1),writesize(worldrank)], hsize_t)
9326  myoffset = int([0,sum(writesize(0:worldrank-1))], hsize_t)
9327  totalshape = int([size(phaseat,1),sum(writesize)], hsize_t)
9328 
9329 !--------------------------------------------------------------------------------------------------
9330 ! create dataspace in memory (local shape = hyperslab) and in file (global shape)
9331  call h5screate_simple_f(2,myshape,memspace_id,ierr,myshape)
9332  if (ierr < 0) call io_error(1,ext_msg='results_mapping_constituent: h5screate_simple_f/memspace_id')
9333 
9334  call h5screate_simple_f(2,totalshape,filespace_id,ierr,totalshape)
9335  if (ierr < 0) call io_error(1,ext_msg='results_mapping_constituent: h5screate_simple_f/filespace_id')
9336 
9337  call h5sselect_hyperslab_f(filespace_id, h5s_select_set_f, myoffset, myshape, ierr)
9338  if (ierr < 0) call io_error(1,ext_msg='results_mapping_constituent: h5sselect_hyperslab_f')
9339 
9340 !---------------------------------------------------------------------------------------------------
9341 ! expand phaseAt to consider IPs (is not stored per IP)
9342  do i = 1, size(phaseatmaterialpoint,2)
9343  phaseatmaterialpoint(:,i,:) = phaseat
9344  enddo
9345 
9346 !---------------------------------------------------------------------------------------------------
9347 ! renumber member from my process to all processes
9348  do i = 1, size(label)
9349  where(phaseatmaterialpoint == i) memberatglobal = memberatlocal + sum(memberoffset(i,0:worldrank-1)) -1 ! convert to 0-based
9350  enddo
9351 
9352 !--------------------------------------------------------------------------------------------------
9353 ! write the components of the compound type individually
9354  call h5pset_preserve_f(plist_id, .true., ierr)
9355 
9356  loc_id = results_opengroup('/mapping/cellResults')
9357  call h5dcreate_f(loc_id, 'constituent', dtype_id, filespace_id, dset_id, ierr)
9358  if (ierr < 0) call io_error(1,ext_msg='results_mapping_constituent: h5dcreate_f')
9359 
9360  call h5dwrite_f(dset_id, name_id, reshape(label(pack(phaseatmaterialpoint,.true.)),myshape), &
9361  myshape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
9362  if (ierr < 0) call io_error(1,ext_msg='results_mapping_constituent: h5dwrite_f/name_id')
9363  call h5dwrite_f(dset_id, position_id, reshape(pack(memberatglobal,.true.),myshape), &
9364  myshape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
9365  if (ierr < 0) call io_error(1,ext_msg='results_mapping_constituent: h5dwrite_f/position_id')
9366 
9367 !--------------------------------------------------------------------------------------------------
9368 ! close all
9369  call hdf5_closegroup(loc_id)
9370  call h5pclose_f(plist_id, ierr)
9371  call h5sclose_f(filespace_id, ierr)
9372  call h5sclose_f(memspace_id, ierr)
9373  call h5dclose_f(dset_id, ierr)
9374  call h5tclose_f(dtype_id, ierr)
9375  call h5tclose_f(name_id, ierr)
9376  call h5tclose_f(position_id, ierr)
9377 
9378 end subroutine results_mapping_constituent
9379 
9380 
9381 !--------------------------------------------------------------------------------------------------
9383 !--------------------------------------------------------------------------------------------------
9384 subroutine results_mapping_materialpoint(homogenizationAt,memberAtLocal,label)
9386  integer, dimension(:), intent(in) :: homogenizationat
9387  integer, dimension(:,:), intent(in) :: memberatlocal
9388  character(len=pStringLen), dimension(:), intent(in) :: label
9389 
9390  integer, dimension(size(memberAtLocal,1),size(memberAtLocal,2)) :: &
9391  homogenizationatmaterialpoint, &
9392  memberatglobal
9393  integer, dimension(size(label),0:worldsize-1) :: memberoffset
9394  integer, dimension(0:worldsize-1) :: writesize
9395  integer(HSIZE_T), dimension(1) :: &
9396  myshape, & !< shape of the dataset (this process)
9397  myoffset, &
9398  totalshape
9399 
9400  integer(HID_T) :: &
9401  loc_id, & !< identifier of group in file
9402  dtype_id, & !< identifier of compound data type
9403  name_id, & !< identifier of name (string) in compound data type
9404  position_id, & !< identifier of position/index (integer) in compound data type
9405  dset_id, &
9406  memspace_id, &
9407  filespace_id, &
9408  plist_id, &
9409  dt_id
9410 
9411 
9412  integer(SIZE_T) :: type_size_string, type_size_int
9413  integer :: ierr, i
9414 
9415 !---------------------------------------------------------------------------------------------------
9416 ! compound type: name of phase section + position/index within results array
9417  call h5tcopy_f(h5t_native_character, dt_id, ierr)
9418  call h5tset_size_f(dt_id, int(len(label(1)),size_t), ierr)
9419  call h5tget_size_f(dt_id, type_size_string, ierr)
9420 
9421  call h5tget_size_f(h5t_native_integer, type_size_int, ierr)
9422 
9423  call h5tcreate_f(h5t_compound_f, type_size_string + type_size_int, dtype_id, ierr)
9424  call h5tinsert_f(dtype_id, "Name", 0_size_t, dt_id,ierr)
9425  call h5tinsert_f(dtype_id, "Position", type_size_string, h5t_native_integer, ierr)
9426 
9427 !--------------------------------------------------------------------------------------------------
9428 ! create memory types for each component of the compound type
9429  call h5tcreate_f(h5t_compound_f, type_size_string, name_id, ierr)
9430  call h5tinsert_f(name_id, "Name", 0_size_t, dt_id, ierr)
9431 
9432  call h5tcreate_f(h5t_compound_f, type_size_int, position_id, ierr)
9433  call h5tinsert_f(position_id, "Position", 0_size_t, h5t_native_integer, ierr)
9434 
9435  call h5tclose_f(dt_id, ierr)
9436 
9437 !--------------------------------------------------------------------------------------------------
9438 ! prepare MPI communication (transparent for non-MPI runs)
9439  call h5pcreate_f(h5p_dataset_xfer_f, plist_id, ierr)
9440  memberoffset = 0
9441  do i=1, size(label)
9442  memberoffset(i,worldrank) = count(homogenizationat == i)*size(memberatlocal,1) ! number of points/instance of this process
9443  enddo
9444  writesize = 0
9445  writesize(worldrank) = size(memberatlocal) ! total number of points by this process
9446 
9447 !--------------------------------------------------------------------------------------------------
9448 ! MPI settings and communication
9449 # 698 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/results.f90"
9450 
9451  myshape = int([writesize(worldrank)], hsize_t)
9452  myoffset = int([sum(writesize(0:worldrank-1))], hsize_t)
9453  totalshape = int([sum(writesize)], hsize_t)
9454 
9455 !--------------------------------------------------------------------------------------------------
9456 ! create dataspace in memory (local shape = hyperslab) and in file (global shape)
9457  call h5screate_simple_f(1,myshape,memspace_id,ierr,myshape)
9458  if (ierr < 0) call io_error(1,ext_msg='results_mapping_materialpoint: h5screate_simple_f/memspace_id')
9459 
9460  call h5screate_simple_f(1,totalshape,filespace_id,ierr,totalshape)
9461  if (ierr < 0) call io_error(1,ext_msg='results_mapping_materialpoint: h5screate_simple_f/filespace_id')
9462 
9463  call h5sselect_hyperslab_f(filespace_id, h5s_select_set_f, myoffset, myshape, ierr)
9464  if (ierr < 0) call io_error(1,ext_msg='results_mapping_materialpoint: h5sselect_hyperslab_f')
9465 
9466 !---------------------------------------------------------------------------------------------------
9467 ! expand phaseAt to consider IPs (is not stored per IP)
9468  do i = 1, size(homogenizationatmaterialpoint,1)
9469  homogenizationatmaterialpoint(i,:) = homogenizationat
9470  enddo
9471 
9472 !---------------------------------------------------------------------------------------------------
9473 ! renumber member from my process to all processes
9474  do i = 1, size(label)
9475  where(homogenizationatmaterialpoint == i) memberatglobal = memberatlocal + sum(memberoffset(i,0:worldrank-1)) - 1 ! convert to 0-based
9476  enddo
9477 
9478 !--------------------------------------------------------------------------------------------------
9479 ! write the components of the compound type individually
9480  call h5pset_preserve_f(plist_id, .true., ierr)
9481 
9482  loc_id = results_opengroup('/mapping/cellResults')
9483  call h5dcreate_f(loc_id, 'materialpoint', dtype_id, filespace_id, dset_id, ierr)
9484  if (ierr < 0) call io_error(1,ext_msg='results_mapping_materialpoint: h5dcreate_f')
9485 
9486  call h5dwrite_f(dset_id, name_id, reshape(label(pack(homogenizationatmaterialpoint,.true.)),myshape), &
9487  myshape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
9488  if (ierr < 0) call io_error(1,ext_msg='results_mapping_materialpoint: h5dwrite_f/name_id')
9489  call h5dwrite_f(dset_id, position_id, reshape(pack(memberatglobal,.true.),myshape), &
9490  myshape, ierr, file_space_id = filespace_id, mem_space_id = memspace_id, xfer_prp = plist_id)
9491  if (ierr < 0) call io_error(1,ext_msg='results_mapping_materialpoint: h5dwrite_f/position_id')
9492 
9493 !--------------------------------------------------------------------------------------------------
9494 ! close all
9495  call hdf5_closegroup(loc_id)
9496  call h5pclose_f(plist_id, ierr)
9497  call h5sclose_f(filespace_id, ierr)
9498  call h5sclose_f(memspace_id, ierr)
9499  call h5dclose_f(dset_id, ierr)
9500  call h5tclose_f(dtype_id, ierr)
9501  call h5tclose_f(name_id, ierr)
9502  call h5tclose_f(position_id, ierr)
9503 
9504 end subroutine results_mapping_materialpoint
9505 
9506 
9507 !!--------------------------------------------------------------------------------------------------
9508 !!> @brief adds the backward mapping from spatial position and constituent ID to results
9509 !!--------------------------------------------------------------------------------------------------
9510 !subroutine HDF5_backwardMappingPhase(material_phase,phasememberat,phase_name,dataspace_size,mpiOffset,mpiOffset_phase)
9511 
9512 ! integer(pInt), intent(in), dimension(:,:,:) :: material_phase, phasememberat
9513 ! character(len=*), intent(in), dimension(:) :: phase_name
9514 ! integer(pInt), intent(in), dimension(:) :: dataspace_size, mpiOffset_phase
9515 ! integer(pInt), intent(in) :: mpiOffset
9516 
9517 ! integer(pInt) :: hdferr, NmatPoints, Nconstituents, i, j
9518 ! integer(HID_T) :: mapping_id, dtype_id, dset_id, space_id, position_id, plist_id, memspace
9519 ! integer(SIZE_T) :: type_size
9520 
9521 ! integer(pInt), dimension(:,:), allocatable :: arr
9522 
9523 ! integer(HSIZE_T), dimension(1) :: counter
9524 ! integer(HSSIZE_T), dimension(1) :: fileOffset
9525 
9526 ! character(len=64) :: phaseID
9527 
9528 ! Nconstituents = size(phasememberat,1)
9529 ! NmatPoints = count(material_phase /=0)/Nconstituents
9530 
9531 ! allocate(arr(2,NmatPoints*Nconstituents))
9532 
9533 ! do i=1, NmatPoints
9534 ! do j=Nconstituents-1, 0, -1
9535 ! arr(1,Nconstituents*i-j) = i-1
9536 ! enddo
9537 ! enddo
9538 ! arr(2,:) = pack(material_phase,material_phase/=0)
9539 
9540 ! do i=1, size(phase_name)
9541 ! write(phaseID, '(i0)') i
9542 ! mapping_ID = results_openGroup('/current/constitutive/'//trim(phaseID)//'_'//phase_name(i))
9543 ! NmatPoints = count(material_phase == i)
9544 
9545 !!--------------------------------------------------------------------------------------------------
9546 ! ! create dataspace
9547 ! call h5screate_simple_f(1, int([dataspace_size(i)],HSIZE_T), space_id, hdferr, &
9548 ! int([dataspace_size(i)],HSIZE_T))
9549 ! if (hdferr < 0) call IO_error(1,ext_msg='HDF5_writeBackwardMapping')
9550 
9551 !!--------------------------------------------------------------------------------------------------
9552 ! ! compound type
9553 ! call h5tget_size_f(H5T_STD_I32LE, type_size, hdferr)
9554 ! call h5tcreate_f(H5T_COMPOUND_F, type_size, dtype_id, hdferr)
9555 ! if (hdferr < 0) call IO_error(1,ext_msg='HDF5_writeBackwardMapping: h5tcreate_f dtype_id')
9556 
9557 ! call h5tinsert_f(dtype_id, "Position", 0_SIZE_T, H5T_STD_I32LE, hdferr)
9558 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5tinsert_f 0')
9559 
9560 !!--------------------------------------------------------------------------------------------------
9561 ! ! create Dataset
9562 ! call h5dcreate_f(mapping_id, 'mapGeometry', dtype_id, space_id, dset_id, hdferr)
9563 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase')
9564 
9565 !!--------------------------------------------------------------------------------------------------
9566 ! ! Create memory types (one compound datatype for each member)
9567 ! call h5tcreate_f(H5T_COMPOUND_F, int(pInt,SIZE_T), position_id, hdferr)
9568 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5tcreate_f position_id')
9569 ! call h5tinsert_f(position_id, "Position", 0_SIZE_T, H5T_STD_I32LE, hdferr)
9570 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5tinsert_f position_id')
9571 
9572 !!--------------------------------------------------------------------------------------------------
9573 ! ! Define and select hyperslabs
9574 ! counter = NmatPoints ! how big i am
9575 ! fileOffset = mpiOffset_phase(i) ! where i start to write my data
9576 
9577 ! call h5screate_simple_f(1, counter, memspace, hdferr)
9578 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5screate_simple_f')
9579 ! call h5dget_space_f(dset_id, space_id, hdferr)
9580 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5dget_space_f')
9581 ! call h5sselect_hyperslab_f(space_id, H5S_SELECT_SET_F, fileOffset, counter, hdferr)
9582 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5sselect_hyperslab_f')
9583 
9584 !!--------------------------------------------------------------------------------------------------
9585 ! ! Create property list for collective dataset write
9586 !#ifdef PETSc
9587 ! call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr)
9588 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5pcreate_f')
9589 ! call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr)
9590 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5pset_dxpl_mpio_f')
9591 !#endif
9592 
9593 !!--------------------------------------------------------------------------------------------------
9594 ! ! write data by fields in the datatype. Fields order is not important.
9595 ! call h5dwrite_f(dset_id, position_id, pack(arr(1,:),arr(2,:)==i)+mpiOffset, int([dataspace_size(i)],HSIZE_T),&
9596 ! hdferr, file_space_id = space_id, mem_space_id = memspace, xfer_prp = plist_id)
9597 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5dwrite_f instance_id')
9598 
9599 !!--------------------------------------------------------------------------------------------------
9600 ! !close types, dataspaces
9601 ! call h5tclose_f(dtype_id, hdferr)
9602 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5tclose_f dtype_id')
9603 ! call h5tclose_f(position_id, hdferr)
9604 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5tclose_f position_id')
9605 ! call h5dclose_f(dset_id, hdferr)
9606 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5dclose_f')
9607 ! call h5sclose_f(space_id, hdferr)
9608 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5sclose_f space_id')
9609 ! call h5sclose_f(memspace, hdferr)
9610 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5sclose_f memspace')
9611 ! call h5pclose_f(plist_id, hdferr)
9612 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingPhase: h5pclose_f')
9613 ! call HDF5_closeGroup(mapping_ID)
9614 
9615 ! enddo
9616 
9617 !end subroutine HDF5_backwardMappingPhase
9618 
9619 
9620 !!--------------------------------------------------------------------------------------------------
9621 !!> @brief adds the backward mapping from spatial position and constituent ID to results
9622 !!--------------------------------------------------------------------------------------------------
9623 !subroutine HDF5_backwardMappingHomog(material_homog,homogmemberat,homogenization_name,dataspace_size,mpiOffset,mpiOffset_homog)
9624 
9625 ! integer(pInt), intent(in), dimension(:,:) :: material_homog, homogmemberat
9626 ! character(len=*), intent(in), dimension(:) :: homogenization_name
9627 ! integer(pInt), intent(in), dimension(:) :: dataspace_size, mpiOffset_homog
9628 ! integer(pInt), intent(in) :: mpiOffset
9629 
9630 ! integer(pInt) :: hdferr, NmatPoints, i
9631 ! integer(HID_T) :: mapping_id, dtype_id, dset_id, space_id, position_id, plist_id, memspace
9632 ! integer(SIZE_T) :: type_size
9633 
9634 ! integer(pInt), dimension(:,:), allocatable :: arr
9635 
9636 ! integer(HSIZE_T), dimension(1) :: counter
9637 ! integer(HSSIZE_T), dimension(1) :: fileOffset
9638 
9639 ! character(len=64) :: homogID
9640 
9641 ! NmatPoints = count(material_homog /=0)
9642 ! allocate(arr(2,NmatPoints))
9643 
9644 ! arr(1,:) = (/(i, i=0,NmatPoints-1)/)
9645 ! arr(2,:) = pack(material_homog,material_homog/=0)
9646 
9647 ! do i=1, size(homogenization_name)
9648 ! write(homogID, '(i0)') i
9649 ! mapping_ID = results_openGroup('/current/homogenization/'//trim(homogID)//'_'//homogenization_name(i))
9650 
9651 !!--------------------------------------------------------------------------------------------------
9652 ! ! create dataspace
9653 ! call h5screate_simple_f(1, int([dataspace_size(i)],HSIZE_T), space_id, hdferr, &
9654 ! int([dataspace_size(i)],HSIZE_T))
9655 ! if (hdferr < 0) call IO_error(1,ext_msg='HDF5_writeBackwardMapping')
9656 
9657 !!--------------------------------------------------------------------------------------------------
9658 ! ! compound type
9659 ! call h5tget_size_f(H5T_STD_I32LE, type_size, hdferr)
9660 ! call h5tcreate_f(H5T_COMPOUND_F, type_size, dtype_id, hdferr)
9661 ! if (hdferr < 0) call IO_error(1,ext_msg='HDF5_writeBackwardMapping: h5tcreate_f dtype_id')
9662 
9663 ! call h5tinsert_f(dtype_id, "Position", 0_SIZE_T, H5T_STD_I32LE, hdferr)
9664 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5tinsert_f 0')
9665 
9666 !!--------------------------------------------------------------------------------------------------
9667 ! ! create Dataset
9668 ! call h5dcreate_f(mapping_id, 'mapGeometry', dtype_id, space_id, dset_id, hdferr)
9669 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog')
9670 
9671 !!--------------------------------------------------------------------------------------------------
9672 ! ! Create memory types (one compound datatype for each member)
9673 ! call h5tcreate_f(H5T_COMPOUND_F, int(pInt,SIZE_T), position_id, hdferr)
9674 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5tcreate_f position_id')
9675 ! call h5tinsert_f(position_id, "Position", 0_SIZE_T, H5T_STD_I32LE, hdferr)
9676 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5tinsert_f position_id')
9677 
9678 !!--------------------------------------------------------------------------------------------------
9679 ! ! Define and select hyperslabs
9680 ! counter = NmatPoints ! how big i am
9681 ! fileOffset = mpiOffset_homog(i) ! where i start to write my data
9682 
9683 ! call h5screate_simple_f(1, counter, memspace, hdferr)
9684 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5screate_simple_f')
9685 ! call h5dget_space_f(dset_id, space_id, hdferr)
9686 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5dget_space_f')
9687 ! call h5sselect_hyperslab_f(space_id, H5S_SELECT_SET_F, fileOffset, counter, hdferr)
9688 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5sselect_hyperslab_f')
9689 
9690 !!--------------------------------------------------------------------------------------------------
9691 ! ! Create property list for collective dataset write
9692 !#ifdef PETSc
9693 ! call h5pcreate_f(H5P_DATASET_XFER_F, plist_id, hdferr)
9694 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5pcreate_f')
9695 ! call h5pset_dxpl_mpio_f(plist_id, H5FD_MPIO_COLLECTIVE_F, hdferr)
9696 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5pset_dxpl_mpio_f')
9697 !#endif
9698 
9699 !!--------------------------------------------------------------------------------------------------
9700 ! ! write data by fields in the datatype. Fields order is not important.
9701 ! call h5dwrite_f(dset_id, position_id, pack(arr(1,:),arr(2,:)==i)+mpiOffset,int([dataspace_size(i)],HSIZE_T),&
9702 ! hdferr, file_space_id = space_id, mem_space_id = memspace, xfer_prp = plist_id)
9703 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5dwrite_f instance_id')
9704 
9705 !!--------------------------------------------------------------------------------------------------
9706 ! !close types, dataspaces
9707 ! call h5tclose_f(dtype_id, hdferr)
9708 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5tclose_f dtype_id')
9709 ! call h5tclose_f(position_id, hdferr)
9710 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5tclose_f position_id')
9711 ! call h5dclose_f(dset_id, hdferr)
9712 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5dclose_f')
9713 ! call h5sclose_f(space_id, hdferr)
9714 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5sclose_f space_id')
9715 ! call h5sclose_f(memspace, hdferr)
9716 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5sclose_f memspace')
9717 ! call h5pclose_f(plist_id, hdferr)
9718 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_backwardMappingHomog: h5pclose_f')
9719 ! call HDF5_closeGroup(mapping_ID)
9720 
9721 ! enddo
9722 
9723 !end subroutine HDF5_backwardMappingHomog
9724 
9725 
9726 !!--------------------------------------------------------------------------------------------------
9727 !!> @brief adds the unique cell to node mapping
9728 !!--------------------------------------------------------------------------------------------------
9729 !subroutine HDF5_mappingCells(mapping)
9730 
9731 ! integer(pInt), intent(in), dimension(:) :: mapping
9732 
9733 ! integer :: hdferr, Nnodes
9734 ! integer(HID_T) :: mapping_id, dset_id, space_id
9735 
9736 ! Nnodes=size(mapping)
9737 ! mapping_ID = results_openGroup("mapping")
9738 
9739 !!--------------------------------------------------------------------------------------------------
9740 !! create dataspace
9741 ! call h5screate_simple_f(1, int([Nnodes],HSIZE_T), space_id, hdferr, &
9742 ! int([Nnodes],HSIZE_T))
9743 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_mappingCells: h5screate_simple_f')
9744 
9745 !!--------------------------------------------------------------------------------------------------
9746 !! create Dataset
9747 ! call h5dcreate_f(mapping_id, "Cell",H5T_NATIVE_INTEGER, space_id, dset_id, hdferr)
9748 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_mappingCells')
9749 
9750 !!--------------------------------------------------------------------------------------------------
9751 !! write data by fields in the datatype. Fields order is not important.
9752 ! call h5dwrite_f(dset_id, H5T_NATIVE_INTEGER, mapping, int([Nnodes],HSIZE_T), hdferr)
9753 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_mappingCells: h5dwrite_f instance_id')
9754 
9755 !!--------------------------------------------------------------------------------------------------
9756 !!close types, dataspaces
9757 ! call h5dclose_f(dset_id, hdferr)
9758 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_mappingConstitutive: h5dclose_f')
9759 ! call h5sclose_f(space_id, hdferr)
9760 ! if (hdferr < 0) call IO_error(1,ext_msg='IO_mappingConstitutive: h5sclose_f')
9761 ! call HDF5_closeGroup(mapping_ID)
9762 
9763 !end subroutine HDF5_mappingCells
9764 
9765 end module results
9766 # 20 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
9767 
9768 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/geometry_plastic_nonlocal.f90" 1
9769 !--------------------------------------------------------------------------------------------------
9774 ! plasticity model
9775 !--------------------------------------------------------------------------------------------------
9777  use prec
9778  use results
9779 
9780  implicit none
9781  public
9782 
9783  integer, protected :: &
9785 
9786  integer, dimension(:,:,:,:), allocatable, protected :: &
9788 
9789  real(preal), dimension(:,:), allocatable, protected :: &
9791 
9792  real(preal), dimension(:,:,:), allocatable, protected :: &
9794 
9795  real(preal), dimension(:,:,:,:), allocatable, protected :: &
9797 
9798 
9799 contains
9800 
9801 !---------------------------------------------------------------------------------------------------
9804 ! face ID (second index) gives the element ID (1 @ first index), IP ID (2 @ first index)
9805 ! and face ID (3 @ first index).
9806 ! A triangle (2D) has 3 faces, a quadrilateral (2D) had 4 faces, a tetrahedron (3D) has
9807 ! 4 faces, and a hexahedron (3D) has 6 faces.
9808 !---------------------------------------------------------------------------------------------------
9809 subroutine geometry_plastic_nonlocal_setipneighborhood(IPneighborhood)
9811  integer, dimension(:,:,:,:), intent(in) :: IPneighborhood
9812 
9814  geometry_plastic_nonlocal_nipneighbors = size(ipneighborhood,2)
9815 
9816 
9818 
9819 
9820 !---------------------------------------------------------------------------------------------------
9822 !---------------------------------------------------------------------------------------------------
9823 subroutine geometry_plastic_nonlocal_setipvolume(IPvolume)
9825  real(pReal), dimension(:,:), intent(in) :: IPvolume
9826 
9828 
9830 
9831 
9832 !---------------------------------------------------------------------------------------------------
9834 ! encompassing an integration point
9835 !---------------------------------------------------------------------------------------------------
9836 subroutine geometry_plastic_nonlocal_setiparea(IParea)
9838  real(pReal), dimension(:,:,:), intent(in) :: IParea
9839 
9841 
9843 
9844 
9845 !---------------------------------------------------------------------------------------------------
9847 ! encompassing an integration point
9848 !---------------------------------------------------------------------------------------------------
9849 subroutine geometry_plastic_nonlocal_setipareanormal(IPareaNormal)
9851  real(pReal), dimension(:,:,:,:), intent(in) :: IPareaNormal
9852 
9854 
9856 
9857 
9858 !---------------------------------------------------------------------------------------------------
9860 !---------------------------------------------------------------------------------------------------
9865 
9866  if(allocated(geometry_plastic_nonlocal_ipvolume0)) &
9868 
9869  if(allocated(geometry_plastic_nonlocal_iparea0)) &
9871 
9874 
9875 end subroutine geometry_plastic_nonlocal_disable
9876 
9877 
9878 !---------------------------------------------------------------------------------------------------
9880 !---------------------------------------------------------------------------------------------------
9883  integer, dimension(:), allocatable :: shp
9884 
9885  call results_openjobfile
9886 
9887  writevolume: block
9888  real(pReal), dimension(:), allocatable :: temp
9890  temp = reshape(geometry_plastic_nonlocal_ipvolume0,[shp(1)*shp(2)])
9891  call results_writedataset('geometry',temp,'v_0',&
9892  'initial cell volume','m³')
9893  end block writevolume
9894 
9895  writeareas: block
9896  real(pReal), dimension(:,:), allocatable :: temp
9898  temp = reshape(geometry_plastic_nonlocal_iparea0,[shp(1),shp(2)*shp(3)])
9899  call results_writedataset('geometry',temp,'a_0',&
9900  'initial cell face area','m²')
9901  end block writeareas
9902 
9903  writenormals: block
9904  real(pReal), dimension(:,:,:), allocatable :: temp
9906  temp = reshape(geometry_plastic_nonlocal_ipareanormal0,[shp(1),shp(2),shp(3)*shp(4)])
9907  call results_writedataset('geometry',temp,'n_0',&
9908  'initial cell face normals','-',transposed=.false.)
9909  end block writenormals
9910 
9911 
9912  call results_closejobfile
9913 
9914 end subroutine geometry_plastic_nonlocal_results
9915 
9916 end module geometry_plastic_nonlocal
9917 # 21 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
9918 
9919 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/discretization.f90" 1
9920 !--------------------------------------------------------------------------------------------------
9923 !--------------------------------------------------------------------------------------------------
9925 
9926  use prec
9927  use results
9928 
9929  implicit none
9930  private
9931 
9932  integer, public, protected :: &
9935 
9936  integer, public, protected, dimension(:), allocatable :: &
9939 
9940  real(preal), public, protected, dimension(:,:), allocatable :: &
9945 
9946  integer :: &
9948 
9949  public :: &
9954 
9955 contains
9956 
9957 !--------------------------------------------------------------------------------------------------
9959 !--------------------------------------------------------------------------------------------------
9960 subroutine discretization_init(homogenizationAt,microstructureAt,&
9961  IPcoords0,NodeCoords0,&
9962  sharedNodesBegin)
9964  integer, dimension(:), intent(in) :: &
9965  homogenizationat, &
9966  microstructureat
9967  real(preal), dimension(:,:), intent(in) :: &
9968  ipcoords0, &
9969  nodecoords0
9970  integer, optional, intent(in) :: &
9971  sharednodesbegin
9972 
9973  write(6,'(/,a)') ' <<<+- discretization init -+>>>'; flush(6)
9974 
9975  discretization_nelem = size(microstructureat,1)
9976  discretization_nip = size(ipcoords0,2)/discretization_nelem
9977 
9978  discretization_homogenizationat = homogenizationat
9979  discretization_microstructureat = microstructureat
9980 
9981  discretization_ipcoords0 = ipcoords0
9982  discretization_ipcoords = ipcoords0
9983 
9984  discretization_nodecoords0 = nodecoords0
9985  discretization_nodecoords = nodecoords0
9986 
9987  if(present(sharednodesbegin)) then
9988  discretization_sharednodesbegin = sharednodesbegin
9989  else
9991  endif
9992 
9993 end subroutine discretization_init
9994 
9995 
9996 !--------------------------------------------------------------------------------------------------
9998 !--------------------------------------------------------------------------------------------------
9999 subroutine discretization_results
10001  real(preal), dimension(:,:), allocatable :: u
10002 
10003  call results_closegroup(results_addgroup('current/geometry'))
10004 
10007  call results_writedataset('current/geometry',u,'u_n','displacements of the nodes','m')
10008 
10011  call results_writedataset('current/geometry',u,'u_p','displacements of the materialpoints','m')
10012 
10013 end subroutine discretization_results
10014 
10015 
10016 !--------------------------------------------------------------------------------------------------
10018 !--------------------------------------------------------------------------------------------------
10019 subroutine discretization_setipcoords(IPcoords)
10021  real(preal), dimension(:,:), intent(in) :: ipcoords
10022 
10023  discretization_ipcoords = ipcoords
10024 
10025 end subroutine discretization_setipcoords
10026 
10027 
10028 !--------------------------------------------------------------------------------------------------
10030 !--------------------------------------------------------------------------------------------------
10031 subroutine discretization_setnodecoords(NodeCoords)
10033  real(preal), dimension(:,:), intent(in) :: nodecoords
10034 
10035  discretization_nodecoords = nodecoords
10036 
10037 end subroutine discretization_setnodecoords
10038 
10039 
10040 end module discretization
10041 # 22 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
10042 
10043 
10044 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/marc/discretization_marc.f90" 1
10045 !--------------------------------------------------------------------------------------------------
10051 !--------------------------------------------------------------------------------------------------
10053  use io
10054  use prec
10055  use math
10056  use damask_interface
10057  use io
10058  use debug
10059  use numerics
10060  use fesolving
10061  use element
10062  use discretization
10064  use results
10065 
10066  implicit none
10067  private
10068 
10070  integer, dimension(:,:), allocatable :: parents
10071  integer, dimension(:,:), allocatable :: weights
10072  end type tcellnodedefinition
10073 
10074  type(tcellnodedefinition), dimension(:), allocatable :: cellnodedefinition
10075 
10076  real(preal), public, protected :: &
10078 
10079  integer, dimension(:), allocatable, public :: &
10080  mesh_fem2damask_elem, & !< DAMASK element ID for Marc element ID
10082 
10083  public :: &
10085 
10086 contains
10087 
10088 !--------------------------------------------------------------------------------------------------
10091 !--------------------------------------------------------------------------------------------------
10092 subroutine discretization_marc_init(ip,el)
10094  integer, intent(in) :: el, ip
10095 
10096  real(preal), dimension(:,:), allocatable :: &
10097  node0_elem, & !< node x,y,z coordinates (initially!)
10098  node0_cell
10099  type(telement) :: elem
10100 
10101  integer, dimension(:), allocatable :: &
10102  microstructureat, &
10103  homogenizationat
10104  integer:: &
10105  nnodes, & !< total number of nodes in the mesh
10106  nelems
10107 
10108  real(preal), dimension(:,:), allocatable :: &
10109  ip_reshaped
10110  integer,dimension(:,:,:), allocatable :: &
10111  connectivity_cell
10112  integer, dimension(:,:), allocatable :: &
10113  connectivity_elem
10114  real(preal), dimension(:,:,:,:),allocatable :: &
10115  unscalednormals
10116 
10117  write(6,'(/,a)') ' <<<+- mesh init -+>>>'; flush(6)
10118 
10119  mesh_unitlength = numerics_unitlength ! set physical extent of a length unit in mesh
10120 
10121  call inputread(elem,node0_elem,connectivity_elem,microstructureat,homogenizationat)
10122  nelems = size(connectivity_elem,2)
10123 
10124  if (debug_e < 1 .or. debug_e > nelems) call io_error(602,ext_msg='element')
10125  if (debug_i < 1 .or. debug_i > elem%nIPs) call io_error(602,ext_msg='IP')
10126 
10127  fesolving_execelem = [1,nelems]
10128  fesolving_execip = [1,elem%nIPs]
10129 
10130  allocate(calcmode(elem%nIPs,nelems),source=.false.) ! pretend to have collected what first call is asking (F = I)
10131  calcmode(ip,mesh_fem2damask_elem(el)) = .true. ! first ip,el needs to be already pingponged to "calc"
10132 
10133 
10134  allocate(cellnodedefinition(elem%nNodes-1))
10135  allocate(connectivity_cell(elem%NcellNodesPerCell,elem%nIPs,nelems))
10136  call buildcells(connectivity_cell,cellnodedefinition,&
10137  elem,connectivity_elem)
10138  allocate(node0_cell(3,maxval(connectivity_cell)))
10139  call buildcellnodes(node0_cell,&
10140  cellnodedefinition,node0_elem)
10141  allocate(ip_reshaped(3,elem%nIPs*nelems),source=0.0_preal)
10142  call buildipcoordinates(ip_reshaped,reshape(connectivity_cell,[elem%NcellNodesPerCell,&
10143  elem%nIPs*nelems]),node0_cell)
10144 
10145  call discretization_init(microstructureat,homogenizationat,&
10146  ip_reshaped,&
10147  node0_cell)
10148 
10149  call writegeometry(elem,connectivity_elem,&
10150  reshape(connectivity_cell,[elem%NcellNodesPerCell,elem%nIPs*nelems]),&
10151  node0_cell,ip_reshaped)
10152 
10153 !--------------------------------------------------------------------------------------------------
10154 ! geometry information required by the nonlocal CP model
10155  call geometry_plastic_nonlocal_setipvolume(ipvolume(elem,node0_cell,connectivity_cell))
10156  unscalednormals = ipareanormal(elem,nelems,connectivity_cell,node0_cell)
10157  call geometry_plastic_nonlocal_setiparea(norm2(unscalednormals,1))
10158  call geometry_plastic_nonlocal_setipareanormal(unscalednormals/spread(norm2(unscalednormals,1),1,3))
10160 
10161 end subroutine discretization_marc_init
10162 
10163 
10164 !--------------------------------------------------------------------------------------------------
10166 !--------------------------------------------------------------------------------------------------
10167 subroutine writegeometry(elem, &
10168  connectivity_elem,connectivity_cell, &
10169  coordinates_nodes,coordinates_points)
10171  type(telement), intent(in) :: &
10172  elem
10173  integer, dimension(:,:), intent(in) :: &
10174  connectivity_elem, &
10175  connectivity_cell
10176  real(pReal), dimension(:,:), intent(in) :: &
10177  coordinates_nodes, &
10178  coordinates_points
10179 
10180  integer, dimension(:,:), allocatable :: &
10181  connectivity_temp
10182  real(pReal), dimension(:,:), allocatable :: &
10183  coordinates_temp
10184 
10185  call results_openjobfile
10186  call results_closegroup(results_addgroup('geometry'))
10187 
10188  connectivity_temp = connectivity_elem
10189  call results_writedataset('geometry',connectivity_temp,'T_e',&
10190  'connectivity of the elements','-')
10191 
10192  connectivity_temp = connectivity_cell
10193  call results_writedataset('geometry',connectivity_temp,'T_c', &
10194  'connectivity of the cells','-')
10195  call results_addattribute('VTK_TYPE',elem%vtkType,'geometry/T_c')
10196 
10197  coordinates_temp = coordinates_nodes
10198  call results_writedataset('geometry',coordinates_temp,'x_n', &
10199  'initial coordinates of the nodes','m')
10200 
10201  coordinates_temp = coordinates_points
10202  call results_writedataset('geometry',coordinates_temp,'x_p', &
10203  'initial coordinates of the materialpoints','m')
10204 
10206 
10207 end subroutine writegeometry
10208 
10209 
10210 !--------------------------------------------------------------------------------------------------
10212 !--------------------------------------------------------------------------------------------------
10213 subroutine inputread(elem,node0_elem,connectivity_elem,microstructureAt,homogenizationAt)
10215  type(telement), intent(out) :: elem
10216  real(pReal), dimension(:,:), allocatable, intent(out) :: &
10217  node0_elem
10218  integer, dimension(:,:), allocatable, intent(out) :: &
10219  connectivity_elem
10220  integer, dimension(:), allocatable, intent(out) :: &
10221  microstructureAt, &
10222  homogenizationAt
10223 
10224  integer :: &
10225  fileFormatVersion, &
10226  hypoelasticTableStyle, &
10227  initialcondTableStyle, &
10228  nNodes, &
10229  nElems
10230  integer, dimension(:), allocatable :: &
10231  matNumber
10232  character(len=pStringLen), dimension(:), allocatable :: inputFile
10233 
10234  character(len=pStringLen), dimension(:), allocatable :: &
10235  nameElemSet
10236  integer, dimension(:,:), allocatable :: &
10237  mapElemSet
10238 
10239  inputfile = io_read_ascii(trim(getsolverjobname())//trim(inputfileextension))
10240  call inputread_fileformat(fileformatversion, &
10241  inputfile)
10242  call inputread_tablestyles(initialcondtablestyle,hypoelastictablestyle, &
10243  inputfile)
10244  if (fileformatversion > 12) &
10245  call inputread_matnumber(matnumber, &
10246  hypoelastictablestyle,inputfile)
10247  call inputread_nnodesandelements(nnodes,nelems,&
10248  inputfile)
10249 
10250 
10251  call inputread_mapelemsets(nameelemset,mapelemset,&
10252  inputfile)
10253 
10254  call inputread_elemtype(elem, &
10255  nelems,inputfile)
10256 
10258  nelems,elem%nNodes,inputfile)
10259 
10261  nnodes,inputfile)
10262 
10263  call inputread_elemnodes(node0_elem, &
10264  nnodes,inputfile)
10265 
10266  connectivity_elem = inputread_connectivityelem(nelems,elem%nNodes,inputfile)
10267 
10268  call inputread_microstructureandhomogenization(microstructureat,homogenizationat, &
10269  nelems,elem%nNodes,nameelemset,mapelemset,&
10270  initialcondtablestyle,inputfile)
10271 end subroutine inputread
10272 
10273 
10274 
10275 !--------------------------------------------------------------------------------------------------
10277 !--------------------------------------------------------------------------------------------------
10278 subroutine inputread_fileformat(fileFormat,fileContent)
10280  integer, intent(out) :: fileFormat
10281  character(len=*), dimension(:), intent(in) :: fileContent
10282 
10283  integer, allocatable, dimension(:) :: chunkPos
10284  integer :: l
10285 
10286  do l = 1, size(filecontent)
10287  chunkpos = io_stringpos(filecontent(l))
10288  if(chunkpos(1) < 2) cycle
10289  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'version') then
10290  fileformat = io_intvalue(filecontent(l),chunkpos,2)
10291  exit
10292  endif
10293  enddo
10294 
10295 end subroutine inputread_fileformat
10296 
10297 
10298 !--------------------------------------------------------------------------------------------------
10300 !--------------------------------------------------------------------------------------------------
10301 subroutine inputread_tablestyles(initialcond,hypoelastic,fileContent)
10303  integer, intent(out) :: initialcond, hypoelastic
10304  character(len=*), dimension(:), intent(in) :: fileContent
10305 
10306  integer, allocatable, dimension(:) :: chunkPos
10307  integer :: l
10308 
10309  initialcond = 0
10310  hypoelastic = 0
10311 
10312  do l = 1, size(filecontent)
10313  chunkpos = io_stringpos(filecontent(l))
10314  if(chunkpos(1) < 6) cycle
10315  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'table') then
10316  initialcond = io_intvalue(filecontent(l),chunkpos,4)
10317  hypoelastic = io_intvalue(filecontent(l),chunkpos,5)
10318  exit
10319  endif
10320  enddo
10321 
10322 end subroutine inputread_tablestyles
10323 
10324 
10325 !--------------------------------------------------------------------------------------------------
10327 !--------------------------------------------------------------------------------------------------
10328 subroutine inputread_matnumber(matNumber, &
10329  tableStyle,fileContent)
10331  integer, allocatable, dimension(:), intent(out) :: matNumber
10332  integer, intent(in) :: tableStyle
10333  character(len=*), dimension(:), intent(in) :: fileContent
10334 
10335  integer, allocatable, dimension(:) :: chunkPos
10336  integer :: i, j, data_blocks, l
10337 
10338  do l = 1, size(filecontent)
10339  chunkpos = io_stringpos(filecontent(l))
10340  if(chunkpos(1) < 1) cycle
10341  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'hypoelastic') then
10342  if (len_trim(filecontent(l+1))/=0) then
10343  chunkpos = io_stringpos(filecontent(l+1))
10344  data_blocks = io_intvalue(filecontent(l+1),chunkpos,1)
10345  else
10346  data_blocks = 1
10347  endif
10348  allocate(matnumber(data_blocks), source = 0)
10349  do i = 0, data_blocks - 1
10350  j = i*(2+tablestyle) + 1
10351  chunkpos = io_stringpos(filecontent(l+1+j))
10352  matnumber(i+1) = io_intvalue(filecontent(l+1+j),chunkpos,1)
10353  enddo
10354  exit
10355  endif
10356  enddo
10357 
10358 end subroutine inputread_matnumber
10359 
10360 
10361 !--------------------------------------------------------------------------------------------------
10363 !--------------------------------------------------------------------------------------------------
10364 subroutine inputread_nnodesandelements(nNodes,nElems,&
10365  fileContent)
10367  integer, intent(out) :: nNodes, nElems
10368  character(len=*), dimension(:), intent(in) :: fileContent
10369 
10370  integer, allocatable, dimension(:) :: chunkPos
10371  integer :: l
10372 
10373  nnodes = 0
10374  nelems = 0
10375 
10376  do l = 1, size(filecontent)
10377  chunkpos = io_stringpos(filecontent(l))
10378  if(chunkpos(1) < 1) cycle
10379  if (io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'sizing') then
10380  nelems = io_intvalue(filecontent(l),chunkpos,3)
10381  elseif(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'coordinates') then
10382  chunkpos = io_stringpos(filecontent(l+1))
10383  nnodes = io_intvalue(filecontent(l+1),chunkpos,2)
10384  endif
10385  enddo
10386 
10387 end subroutine inputread_nnodesandelements
10388 
10389 
10390 !--------------------------------------------------------------------------------------------------
10392 !--------------------------------------------------------------------------------------------------
10393 subroutine inputread_nelemsets(nElemSets,maxNelemInSet,&
10394  fileContent)
10396  integer, intent(out) :: nElemSets, maxNelemInSet
10397  character(len=*), dimension(:), intent(in) :: fileContent
10398 
10399  integer, allocatable, dimension(:) :: chunkPos
10400  integer :: i,l,elemInCurrentSet
10401 
10402  nelemsets = 0
10403  maxneleminset = 0
10404 
10405  do l = 1, size(filecontent)
10406  chunkpos = io_stringpos(filecontent(l))
10407  if(chunkpos(1) < 2) cycle
10408  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'define' .and. &
10409  io_lc(io_stringvalue(filecontent(l),chunkpos,2)) == 'element') then
10410  nelemsets = nelemsets + 1
10411 
10412  chunkpos = io_stringpos(filecontent(l+1))
10413  if(containsrange(filecontent(l+1),chunkpos)) then
10414  elemincurrentset = 1 + abs( io_intvalue(filecontent(l+1),chunkpos,3) &
10415  -io_intvalue(filecontent(l+1),chunkpos,1))
10416  else
10417  elemincurrentset = 0
10418  i = 0
10419  do while (.true.)
10420  i = i + 1
10421  chunkpos = io_stringpos(filecontent(l+i))
10422  elemincurrentset = elemincurrentset + chunkpos(1) - 1 ! add line's count when assuming 'c'
10423  if(io_lc(io_stringvalue(filecontent(l+i),chunkpos,chunkpos(1))) /= 'c') then ! line finished, read last value
10424  elemincurrentset = elemincurrentset + 1 ! data ended
10425  exit
10426  endif
10427  enddo
10428  endif
10429  maxneleminset = max(maxneleminset, elemincurrentset)
10430  endif
10431  enddo
10432 
10433 end subroutine inputread_nelemsets
10434 
10435 
10436 !--------------------------------------------------------------------------------------------------
10438 !--------------------------------------------------------------------------------------------------
10439 subroutine inputread_mapelemsets(nameElemSet,mapElemSet,&
10440  fileContent)
10442  character(len=pStringLen), dimension(:), allocatable, intent(out) :: nameElemSet
10443  integer, dimension(:,:), allocatable, intent(out) :: mapElemSet
10444  character(len=*), dimension(:), intent(in) :: fileContent
10445 
10446  integer, allocatable, dimension(:) :: chunkPos
10447  integer :: elemSet, NelemSets, maxNelemInSet,l
10448 
10449 
10450  call inputread_nelemsets(nelemsets,maxneleminset,filecontent)
10451  allocate(nameelemset(nelemsets)); nameelemset = 'n/a'
10452  allocate(mapelemset(1+maxneleminset,nelemsets),source=0)
10453  elemset = 0
10454 
10455  do l = 1, size(filecontent)
10456  chunkpos = io_stringpos(filecontent(l))
10457  if(chunkpos(1) < 2) cycle
10458  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'define' .and. &
10459  io_lc(io_stringvalue(filecontent(l),chunkpos,2)) == 'element') then
10460  elemset = elemset+1
10461  nameelemset(elemset) = trim(io_stringvalue(filecontent(l),chunkpos,4))
10462  mapelemset(:,elemset) = continuousintvalues(filecontent(l+1:),size(mapelemset,1)-1,nameelemset,mapelemset,size(nameelemset))
10463  endif
10464  enddo
10465 
10466 end subroutine inputread_mapelemsets
10467 
10468 
10469 !--------------------------------------------------------------------------------------------------
10471 !--------------------------------------------------------------------------------------------------
10472 subroutine inputread_mapelems(FEM2DAMASK, &
10473  nElems,nNodesPerElem,fileContent)
10475  integer, allocatable, dimension(:), intent(out) :: FEM2DAMASK
10476 
10477  integer, intent(in) :: nElems, & !< number of elements
10478  nNodesPerElem
10479  character(len=*), dimension(:), intent(in) :: fileContent
10480 
10481  integer, dimension(2,nElems) :: map_unsorted
10482  integer, allocatable, dimension(:) :: chunkPos
10483  integer :: i,j,l,nNodesAlreadyRead
10484 
10485  do l = 1, size(filecontent)
10486  chunkpos = io_stringpos(filecontent(l))
10487  if(chunkpos(1) < 1) cycle
10488  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'connectivity') then
10489  j = 0
10490  do i = 1,nelems
10491  chunkpos = io_stringpos(filecontent(l+1+i+j))
10492  map_unsorted(:,i) = [io_intvalue(filecontent(l+1+i+j),chunkpos,1),i]
10493  nnodesalreadyread = chunkpos(1) - 2
10494  do while(nnodesalreadyread < nnodesperelem) ! read on if not all nodes in one line
10495  j = j + 1
10496  chunkpos = io_stringpos(filecontent(l+1+i+j))
10497  nnodesalreadyread = nnodesalreadyread + chunkpos(1)
10498  enddo
10499  enddo
10500  exit
10501  endif
10502  enddo
10503 
10504  call math_sort(map_unsorted)
10505  allocate(fem2damask(minval(map_unsorted(1,:)):maxval(map_unsorted(1,:))),source=-1)
10506  do i = 1, nelems
10507  fem2damask(map_unsorted(1,i)) = map_unsorted(2,i)
10508  enddo
10509 
10510 end subroutine inputread_mapelems
10511 
10512 
10513 !--------------------------------------------------------------------------------------------------
10515 !--------------------------------------------------------------------------------------------------
10516 subroutine inputread_mapnodes(FEM2DAMASK, &
10517  nNodes,fileContent)
10519  integer, allocatable, dimension(:), intent(out) :: FEM2DAMASK
10520 
10521  integer, intent(in) :: nNodes
10522  character(len=*), dimension(:), intent(in) :: fileContent
10523 
10524  integer, dimension(2,nNodes) :: map_unsorted
10525  integer, allocatable, dimension(:) :: chunkPos
10526  integer :: i, l
10527 
10528  do l = 1, size(filecontent)
10529  chunkpos = io_stringpos(filecontent(l))
10530  if(chunkpos(1) < 1) cycle
10531  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'coordinates') then
10532  do i = 1,nnodes
10533  chunkpos = io_stringpos(filecontent(l+1+i))
10534  map_unsorted(:,i) = [io_intvalue(filecontent(l+1+i),chunkpos,1),i]
10535  enddo
10536  exit
10537  endif
10538  enddo
10539 
10540  call math_sort(map_unsorted)
10541  allocate(fem2damask(minval(map_unsorted(1,:)):maxval(map_unsorted(1,:))),source=-1)
10542  do i = 1, nnodes
10543  fem2damask(map_unsorted(1,i)) = map_unsorted(2,i)
10544  enddo
10545 
10546 end subroutine inputread_mapnodes
10547 
10548 
10549 !--------------------------------------------------------------------------------------------------
10551 !--------------------------------------------------------------------------------------------------
10552 subroutine inputread_elemnodes(nodes, &
10553  nNode,fileContent)
10555  real(pReal), allocatable, dimension(:,:), intent(out) :: nodes
10556  integer, intent(in) :: nNode
10557  character(len=*), dimension(:), intent(in) :: fileContent
10558 
10559  integer, allocatable, dimension(:) :: chunkPos
10560  integer :: i,j,m,l
10561 
10562  allocate(nodes(3,nnode))
10563 
10564  do l = 1, size(filecontent)
10565  chunkpos = io_stringpos(filecontent(l))
10566  if(chunkpos(1) < 1) cycle
10567  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'coordinates') then
10568  do i=1,nnode
10569  chunkpos = io_stringpos(filecontent(l+1+i))
10570  m = mesh_fem2damask_node(io_intvalue(filecontent(l+1+i),chunkpos,1))
10571  do j = 1,3
10572  nodes(j,m) = mesh_unitlength * io_floatvalue(filecontent(l+1+i),chunkpos,j+1)
10573  enddo
10574  enddo
10575  exit
10576  endif
10577  enddo
10578 
10579 end subroutine inputread_elemnodes
10580 
10581 
10582 !--------------------------------------------------------------------------------------------------
10584 !--------------------------------------------------------------------------------------------------
10585 subroutine inputread_elemtype(elem, &
10586  nElem,fileContent)
10588  type(telement), intent(out) :: elem
10589  integer, intent(in) :: nElem
10590  character(len=*), dimension(:), intent(in) :: fileContent
10591 
10592  integer, allocatable, dimension(:) :: chunkPos
10593  integer :: i,j,t,l,remainingChunks
10594 
10595  t = -1
10596  do l = 1, size(filecontent)
10597  chunkpos = io_stringpos(filecontent(l))
10598  if(chunkpos(1) < 1) cycle
10599  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'connectivity') then
10600  j = 0
10601  do i=1,nelem ! read all elements
10602  chunkpos = io_stringpos(filecontent(l+1+i+j))
10603  if (t == -1) then
10604  t = mapelemtype(io_stringvalue(filecontent(l+1+i+j),chunkpos,2))
10605  call elem%init(t)
10606  else
10607  if (t /= mapelemtype(io_stringvalue(filecontent(l+1+i+j),chunkpos,2))) call io_error(191,el=t,ip=i)
10608  endif
10609  remainingchunks = elem%nNodes - (chunkpos(1) - 2)
10610  do while(remainingchunks > 0)
10611  j = j + 1
10612  chunkpos = io_stringpos(filecontent(l+1+i+j))
10613  remainingchunks = remainingchunks - chunkpos(1)
10614  enddo
10615  enddo
10616  exit
10617  endif
10618  enddo
10619 
10620  contains
10621 
10622  !--------------------------------------------------------------------------------------------------
10624  !--------------------------------------------------------------------------------------------------
10625  integer function mapelemtype(what)
10627  character(len=*), intent(in) :: what
10628 
10629  select case (io_lc(what))
10630  case ( '6')
10631  mapelemtype = 1 ! Two-dimensional Plane Strain Triangle
10632  case ( '125') ! 155, 128 (need test)
10633  mapelemtype = 2 ! Two-dimensional Plane Strain triangle (155: cubic shape function, 125/128: second order isoparametric)
10634  !case ( '11') ! need test
10635  ! mapElemtype = 3 ! Arbitrary Quadrilateral Plane-strain
10636  case ( '27')
10637  mapelemtype = 4 ! Plane Strain, Eight-node Distorted Quadrilateral
10638  case ( '54')
10639  mapelemtype = 5 ! Plane Strain, Eight-node Distorted Quadrilateral with reduced integration
10640  !case ( '134') ! need test
10641  ! mapElemtype = 6 ! Three-dimensional Four-node Tetrahedron
10642  !case ( '157') ! need test
10643  ! mapElemtype = 7 ! Three-dimensional, Low-order, Tetrahedron, Herrmann Formulations
10644  !case ( '127') ! need test
10645  ! mapElemtype = 8 ! Three-dimensional Ten-node Tetrahedron
10646  !case ( '136') ! need test
10647  ! mapElemtype = 9 ! Three-dimensional Arbitrarily Distorted Pentahedral
10648  case ( '117') ! 123 (need test)
10649  mapelemtype = 10 ! Three-dimensional Arbitrarily Distorted linear hexahedral with reduced integration
10650  case ( '7')
10651  mapelemtype = 11 ! Three-dimensional Arbitrarily Distorted Brick
10652  case ( '57')
10653  mapelemtype = 12 ! Three-dimensional Arbitrarily Distorted quad hexahedral with reduced integration
10654  case ( '21')
10655  mapelemtype = 13 ! Three-dimensional Arbitrarily Distorted quadratic hexahedral
10656  case default
10657  call io_error(error_id=190,ext_msg=io_lc(what))
10658  end select
10659 
10660  end function mapelemtype
10661 
10662 
10663 end subroutine inputread_elemtype
10664 
10665 
10666 !--------------------------------------------------------------------------------------------------
10668 !--------------------------------------------------------------------------------------------------
10669 function inputread_connectivityelem(nElem,nNodes,fileContent)
10671  integer, intent(in) :: &
10672  nelem, &
10673  nnodes
10674  character(len=*), dimension(:), intent(in) :: filecontent
10675 
10676  integer, dimension(nNodes,nElem) :: &
10678 
10679  integer, allocatable, dimension(:) :: chunkpos
10680 
10681  integer, dimension(1+nElem) :: contints
10682  integer :: i,k,j,t,e,l,nnodesalreadyread
10683 
10684  do l = 1, size(filecontent)
10685  chunkpos = io_stringpos(filecontent(l))
10686  if(chunkpos(1) < 1) cycle
10687  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'connectivity') then
10688  j = 0
10689  do i = 1,nelem
10690  chunkpos = io_stringpos(filecontent(l+1+i+j))
10691  e = mesh_fem2damask_elem(io_intvalue(filecontent(l+1+i+j),chunkpos,1))
10692  if (e /= 0) then ! disregard non CP elems
10693  do k = 1,chunkpos(1)-2
10695  mesh_fem2damask_node(io_intvalue(filecontent(l+1+i+j),chunkpos,k+2))
10696  enddo
10697  nnodesalreadyread = chunkpos(1) - 2
10698  do while(nnodesalreadyread < nnodes) ! read on if not all nodes in one line
10699  j = j + 1
10700  chunkpos = io_stringpos(filecontent(l+1+i+j))
10701  do k = 1,chunkpos(1)
10702  inputread_connectivityelem(nnodesalreadyread+k,e) = &
10703  mesh_fem2damask_node(io_intvalue(filecontent(l+1+i+j),chunkpos,k))
10704  enddo
10705  nnodesalreadyread = nnodesalreadyread + chunkpos(1)
10706  enddo
10707  endif
10708  enddo
10709  exit
10710  endif
10711  enddo
10712 
10713 end function inputread_connectivityelem
10714 
10715 
10716 !--------------------------------------------------------------------------------------------------
10718 !--------------------------------------------------------------------------------------------------
10719 subroutine inputread_microstructureandhomogenization(microstructureAt,homogenizationAt, &
10720  nElem,nNodes,nameElemSet,mapElemSet,initialcondTableStyle,fileContent)
10722  integer, dimension(:), allocatable, intent(out) :: &
10723  microstructureAt, &
10724  homogenizationAt
10725  integer, intent(in) :: &
10726  nElem, &
10727  nNodes, & !< number of nodes per element
10728  initialcondTableStyle
10729  character(len=*), dimension(:), intent(in) :: nameElemSet
10730  integer, dimension(:,:), intent(in) :: mapElemSet
10731  character(len=*), dimension(:), intent(in) :: fileContent
10732 
10733  integer, allocatable, dimension(:) :: chunkPos
10734 
10735  integer, dimension(1+nElem) :: contInts
10736  integer :: i,j,t,sv,myVal,e,nNodesAlreadyRead,l,k,m
10737 
10738 
10739  allocate(microstructureat(nelem),source=0)
10740  allocate(homogenizationat(nelem),source=0)
10741 
10742  do l = 1, size(filecontent)
10743  chunkpos = io_stringpos(filecontent(l))
10744  if(chunkpos(1) < 2) cycle
10745  if(io_lc(io_stringvalue(filecontent(l),chunkpos,1)) == 'initial' .and. &
10746  io_lc(io_stringvalue(filecontent(l),chunkpos,2)) == 'state') then
10747  k = merge(2,1,initialcondtablestyle == 2)
10748  chunkpos = io_stringpos(filecontent(l+k))
10749  sv = io_intvalue(filecontent(l+k),chunkpos,1) ! figure state variable index
10750  if( (sv == 2) .or. (sv == 3) ) then ! only state vars 2 and 3 of interest
10751  m = 1
10752  chunkpos = io_stringpos(filecontent(l+k+m))
10753  do while (scan(io_stringvalue(filecontent(l+k+m),chunkpos,1),'+-',back=.true.)>1) ! is noEfloat value?
10754  myval = nint(io_floatvalue(filecontent(l+k+m),chunkpos,1))
10755  if (initialcondtablestyle == 2) m = m + 2
10756  contints = continuousintvalues(filecontent(l+k+m+1:),nelem,nameelemset,mapelemset,size(nameelemset)) ! get affected elements
10757  do i = 1,contints(1)
10758  e = mesh_fem2damask_elem(contints(1+i))
10759  if (sv == 2) microstructureat(e) = myval
10760  if (sv == 3) homogenizationat(e) = myval
10761  enddo
10762  if (initialcondtablestyle == 0) m = m + 1
10763  enddo
10764  endif
10765  endif
10766  enddo
10767 
10769 
10770 
10771 !--------------------------------------------------------------------------------------------------
10773 !--------------------------------------------------------------------------------------------------
10774 subroutine buildcells(connectivity_cell,cellNodeDefinition, &
10775  elem,connectivity_elem)
10777  type(tcellnodedefinition), dimension(:), intent(out) :: cellNodeDefinition ! definition of cell nodes for increasing number of parents
10778  integer, dimension(:,:,:),intent(out) :: connectivity_cell
10779 
10780  type(telement), intent(in) :: elem ! element definition
10781  integer, dimension(:,:), intent(in) :: connectivity_elem ! connectivity of the elements
10782 
10783  integer,dimension(:), allocatable :: candidates_local
10784  integer,dimension(:,:), allocatable :: parentsAndWeights,candidates_global
10785 
10786  integer :: e, n, c, p, s,i,m,j,nParentNodes,nCellNode,Nelem,candidateID
10787 
10788  nelem = size(connectivity_elem,2)
10789 
10790 !---------------------------------------------------------------------------------------------------
10791 ! initialize global connectivity to negative local connectivity
10792  connectivity_cell = -spread(elem%cell,3,nelem) ! local cell node ID
10793 
10794 !---------------------------------------------------------------------------------------------------
10795 ! set connectivity of cell nodes that coincide with FE nodes (defined by 1 parent node)
10796 ! and renumber local (negative) to global (positive) node ID
10797  do e = 1, nelem
10798  do c = 1, elem%NcellNodes
10799  realnode: if (count(elem%cellNodeParentNodeWeights(:,c) /= 0) == 1) then
10800  where(connectivity_cell(:,:,e) == -c)
10801  connectivity_cell(:,:,e) = connectivity_elem(c,e)
10802  end where
10803  endif realnode
10804  enddo
10805  enddo
10806 
10807  ncellnode = maxval(connectivity_elem)
10808 
10809 !---------------------------------------------------------------------------------------------------
10810 ! set connectivity of cell nodes that are defined by 2,...,nNodes real nodes
10811  do nparentnodes = 2, elem%nNodes
10812 
10813  ! get IDs of local cell nodes that are defined by the current number of parent nodes
10814  candidates_local = [integer::]
10815  do c = 1, elem%NcellNodes
10816  if (count(elem%cellNodeParentNodeWeights(:,c) /= 0) == nparentnodes) &
10817  candidates_local = [candidates_local,c]
10818  enddo
10819  s = size(candidates_local)
10820 
10821  if (allocated(candidates_global)) deallocate(candidates_global)
10822  allocate(candidates_global(nparentnodes*2+2,s*nelem)) ! stores parent node ID + weight together with element ID and cellnode id (local)
10823  parentsandweights = reshape([(0, i = 1,2*nparentnodes)],[nparentnodes,2]) ! (re)allocate
10824 
10825  do e = 1, nelem
10826  do i = 1, size(candidates_local)
10827  candidateid = (e-1)*size(candidates_local)+i ! including duplicates, runs to (Nelem*size(candidates_local))
10828  c = candidates_local(i) ! c is local cellnode ID for connectivity
10829  p = 0
10830  do j = 1, size(elem%cellNodeParentNodeWeights(:,c))
10831  if (elem%cellNodeParentNodeWeights(j,c) /= 0) then ! real node 'j' partly defines cell node 'c'
10832  p = p + 1
10833  parentsandweights(p,1:2) = [connectivity_elem(j,e),elem%cellNodeParentNodeWeights(j,c)]
10834  endif
10835  enddo
10836  ! store (and order) real node IDs and their weights together with the element number and local ID
10837  do p = 1, nparentnodes
10838  m = maxloc(parentsandweights(:,1),1)
10839 
10840  candidates_global(p, candidateid) = parentsandweights(m,1)
10841  candidates_global(p+nparentnodes, candidateid) = parentsandweights(m,2)
10842  candidates_global(nparentnodes*2+1:nparentnodes*2+2,candidateid) = [e,c]
10843 
10844  parentsandweights(m,1) = -huge(parentsandweights(m,1)) ! out of the competition
10845  enddo
10846  enddo
10847  enddo
10848 
10849  ! sort according to real node IDs + weight (from left to right)
10850  call math_sort(candidates_global,sortdim=1) ! sort according to first column
10851 
10852  do p = 2, nparentnodes*2
10853  n = 1
10854  do while(n <= size(candidates_local)*nelem)
10855  j=0
10856  do while (n+j<= size(candidates_local)*nelem)
10857  if (candidates_global(p-1,n+j)/=candidates_global(p-1,n)) exit
10858  j = j + 1
10859  enddo
10860  e = n+j-1
10861  if (any(candidates_global(p,n:e)/=candidates_global(p,n))) &
10862  call math_sort(candidates_global(:,n:e),sortdim=p)
10863  n = e+1
10864  enddo
10865  enddo
10866 
10867  i = uniquerows(candidates_global(1:2*nparentnodes,:))
10868  allocate(cellnodedefinition(nparentnodes-1)%parents(i,nparentnodes))
10869  allocate(cellnodedefinition(nparentnodes-1)%weights(i,nparentnodes))
10870 
10871  i = 1
10872  n = 1
10873  do while(n <= size(candidates_local)*nelem)
10874  j=0
10875  parentsandweights(:,1) = candidates_global(1:nparentnodes,n+j)
10876  parentsandweights(:,2) = candidates_global(nparentnodes+1:nparentnodes*2,n+j)
10877 
10878  e = candidates_global(nparentnodes*2+1,n+j)
10879  c = candidates_global(nparentnodes*2+2,n+j)
10880 
10881  do while (n+j<= size(candidates_local)*nelem)
10882  if (any(candidates_global(1:2*nparentnodes,n+j)/=candidates_global(1:2*nparentnodes,n))) exit
10883  where (connectivity_cell(:,:,candidates_global(nparentnodes*2+1,n+j)) == -candidates_global(nparentnodes*2+2,n+j)) ! still locally defined
10884  connectivity_cell(:,:,candidates_global(nparentnodes*2+1,n+j)) = ncellnode + 1 ! gets current new cell node id
10885  end where
10886 
10887  j = j+1
10888  enddo
10889  ncellnode = ncellnode + 1
10890  cellnodedefinition(nparentnodes-1)%parents(i,:) = parentsandweights(:,1)
10891  cellnodedefinition(nparentnodes-1)%weights(i,:) = parentsandweights(:,2)
10892  i = i + 1
10893  n = n+j
10894  enddo
10895 
10896  enddo
10897 
10898  contains
10899  !------------------------------------------------------------------------------------------------
10901  !------------------------------------------------------------------------------------------------
10902  pure function uniquerows(A) result(u)
10904  integer, dimension(:,:), intent(in) :: a
10905 
10906  integer :: &
10907  u, & !< # of unique rows
10908  r, & !< row counter
10909  d
10910 
10911  u = 0
10912  r = 1
10913  do while(r <= size(a,2))
10914  d = 0
10915  do while (r+d<= size(a,2))
10916  if (any(a(:,r)/=a(:,r+d))) exit
10917  d = d+1
10918  enddo
10919  u = u+1
10920  r = r+d
10921  enddo
10922 
10923  end function uniquerows
10924 
10925 end subroutine buildcells
10926 
10927 
10928 !--------------------------------------------------------------------------------------------------
10930 !--------------------------------------------------------------------------------------------------
10931 subroutine buildcellnodes(node_cell, &
10932  definition,node_elem)
10934  real(pReal), dimension(:,:), intent(out) :: node_cell
10935  type(tcellnodedefinition), dimension(:), intent(in) :: definition
10936  real(pReal), dimension(:,:), intent(in) :: node_elem
10937 
10938  integer :: i, j, k, n
10939 
10940  n = size(node_elem,2)
10941  node_cell(:,1:n) = node_elem
10942 
10943  do i = 1, size(cellnodedefinition,1)
10944  do j = 1, size(cellnodedefinition(i)%parents,1)
10945  n = n+1
10946  node_cell(:,n) = 0.0_preal
10947  do k = 1, size(cellnodedefinition(i)%parents,2)
10948  node_cell(:,n) = node_cell(:,n) &
10949  + node_cell(:,definition(i)%parents(j,k)) * real(definition(i)%weights(j,k),preal)
10950  enddo
10951  node_cell(:,n) = node_cell(:,n)/real(sum(definition(i)%weights(j,:)),preal)
10952  enddo
10953  enddo
10954 
10955 end subroutine buildcellnodes
10956 
10957 
10958 !--------------------------------------------------------------------------------------------------
10960 !--------------------------------------------------------------------------------------------------
10961 subroutine buildipcoordinates(IPcoordinates, &
10962  connectivity_cell,node_cell)
10964  real(pReal), dimension(:,:), intent(out):: IPcoordinates
10965  integer, dimension(:,:), intent(in) :: connectivity_cell
10966  real(pReal), dimension(:,:), intent(in) :: node_cell
10967 
10968  integer :: i, n
10969 
10970  do i = 1, size(connectivity_cell,2)
10971  ipcoordinates(:,i) = 0.0_preal
10972  do n = 1, size(connectivity_cell,1)
10973  ipcoordinates(:,i) = ipcoordinates(:,i) &
10974  + node_cell(:,connectivity_cell(n,i))
10975  enddo
10976  ipcoordinates(:,i) = ipcoordinates(:,i)/real(size(connectivity_cell,1),preal)
10977  enddo
10978 
10979 end subroutine buildipcoordinates
10980 
10981 
10982 !---------------------------------------------------------------------------------------------------
10986 !---------------------------------------------------------------------------------------------------
10987 function ipvolume(elem,node,connectivity)
10989  type(telement), intent(in) :: elem
10990  real(preal), dimension(:,:), intent(in) :: node
10991  integer, dimension(:,:,:), intent(in) :: connectivity
10992 
10993  real(preal), dimension(elem%nIPs,size(connectivity,3)) :: ipvolume
10994  real(preal), dimension(3) :: x0,x1,x2,x3,x4,x5,x6,x7
10995 
10996  integer :: e,i
10997 
10998  do e = 1,size(connectivity,3)
10999  do i = 1,elem%nIPs
11000 
11001  select case (elem%cellType)
11002  case (1) ! 2D 3node
11003  ipvolume(i,e) = math_areatriangle(node(1:3,connectivity(1,i,e)), &
11004  node(1:3,connectivity(2,i,e)), &
11005  node(1:3,connectivity(3,i,e)))
11006 
11007  case (2) ! 2D 4node
11008  ipvolume(i,e) = math_areatriangle(node(1:3,connectivity(1,i,e)), & ! assume planar shape, division in two triangles suffices
11009  node(1:3,connectivity(2,i,e)), &
11010  node(1:3,connectivity(3,i,e))) &
11011  + math_areatriangle(node(1:3,connectivity(3,i,e)), &
11012  node(1:3,connectivity(4,i,e)), &
11013  node(1:3,connectivity(1,i,e)))
11014  case (3) ! 3D 4node
11015  ipvolume(i,e) = math_voltetrahedron(node(1:3,connectivity(1,i,e)), &
11016  node(1:3,connectivity(2,i,e)), &
11017  node(1:3,connectivity(3,i,e)), &
11018  node(1:3,connectivity(4,i,e)))
11019  case (4) ! 3D 8node
11020  ! J. Grandy, Efficient Calculation of Volume of Hexahedral Cells
11021  ! Lawrence Livermore National Laboratory
11022  ! https://www.osti.gov/servlets/purl/632793
11023  x0 = node(1:3,connectivity(1,i,e))
11024  x1 = node(1:3,connectivity(2,i,e))
11025  x2 = node(1:3,connectivity(4,i,e))
11026  x3 = node(1:3,connectivity(3,i,e))
11027  x4 = node(1:3,connectivity(5,i,e))
11028  x5 = node(1:3,connectivity(6,i,e))
11029  x6 = node(1:3,connectivity(8,i,e))
11030  x7 = node(1:3,connectivity(7,i,e))
11031  ipvolume(i,e) = dot_product((x7-x1)+(x6-x0),math_cross((x7-x2), (x3-x0))) &
11032  + dot_product((x6-x0), math_cross((x7-x2)+(x5-x0),(x7-x4))) &
11033  + dot_product((x7-x1), math_cross((x5-x0), (x7-x4)+(x3-x0)))
11034  ipvolume(i,e) = ipvolume(i,e)/12.0_preal
11035  end select
11036  enddo
11037  enddo
11038 
11039 end function ipvolume
11040 
11041 
11042 !--------------------------------------------------------------------------------------------------
11044 !--------------------------------------------------------------------------------------------------
11045 function ipareanormal(elem,nElem,connectivity,node)
11047  type(telement), intent(in) :: elem
11048  integer, intent(in) :: nelem
11049  integer, dimension(:,:,:), intent(in) :: connectivity
11050  real(preal), dimension(:,:), intent(in) :: node
11051 
11052  real(preal), dimension(3,elem%nIPneighbors,elem%nIPs,nElem) :: ipareanormal
11053 
11054  real(preal), dimension (3,size(elem%cellFace,1)) :: nodepos
11055  integer :: e,i,f,n,m
11056 
11057  m = size(elem%cellFace,1)
11058 
11059  do e = 1,nelem
11060  do i = 1,elem%nIPs
11061  do f = 1,elem%nIPneighbors
11062  nodepos = node(1:3,connectivity(elem%cellface(1:m,f),i,e))
11063 
11064  select case (elem%cellType)
11065  case (1,2) ! 2D 3 or 4 node
11066  ipareanormal(1,f,i,e) = nodepos(2,2) - nodepos(2,1) ! x_normal = y_connectingVector
11067  ipareanormal(2,f,i,e) = -(nodepos(1,2) - nodepos(1,1)) ! y_normal = -x_connectingVector
11068  ipareanormal(3,f,i,e) = 0.0_preal
11069  case (3) ! 3D 4node
11070  ipareanormal(1:3,f,i,e) = math_cross(nodepos(1:3,2) - nodepos(1:3,1), &
11071  nodepos(1:3,3) - nodepos(1:3,1))
11072  case (4) ! 3D 8node
11073  ! for this cell type we get the normal of the quadrilateral face as an average of
11074  ! four normals of triangular subfaces; since the face consists only of two triangles,
11075  ! the sum has to be divided by two; this whole prcedure tries to compensate for
11076  ! probable non-planar cell surfaces
11077  ipareanormal(1:3,f,i,e) = 0.0_preal
11078  do n = 1, m
11079  ipareanormal(1:3,f,i,e) = ipareanormal(1:3,f,i,e) &
11080  + math_cross(nodepos(1:3,mod(n+0,m)+1) - nodepos(1:3,n), &
11081  nodepos(1:3,mod(n+1,m)+1) - nodepos(1:3,n)) * 0.5_preal
11082  enddo
11083  end select
11084  enddo
11085  enddo
11086  enddo
11087 
11088 end function ipareanormal
11089 
11090 
11091 !--------------------------------------------------------------------------------------------------
11095 !--------------------------------------------------------------------------------------------------
11096 function continuousintvalues(fileContent,maxN,lookupName,lookupMap,lookupMaxN)
11098  character(len=*), dimension(:), intent(in) :: filecontent
11099  integer, intent(in) :: maxn
11100  integer, intent(in) :: lookupmaxn
11101  integer, dimension(:,:), intent(in) :: lookupmap
11102  character(len=*), dimension(:), intent(in) :: lookupname
11103 
11104  integer, dimension(1+maxN) :: continuousintvalues
11105 
11106  integer :: l,i,first,last
11107  integer, allocatable, dimension(:) :: chunkpos
11108  logical :: rangegeneration
11109 
11111  rangegeneration = .false.
11112 
11113  do l = 1, size(filecontent)
11114  chunkpos = io_stringpos(filecontent(l))
11115  if (chunkpos(1) < 1) then ! empty line
11116  exit
11117  elseif (verify(io_stringvalue(filecontent(l),chunkpos,1),'0123456789') > 0) then ! a non-int, i.e. set name
11118  do i = 1, lookupmaxn ! loop over known set names
11119  if (io_stringvalue(filecontent(l),chunkpos,1) == lookupname(i)) then ! found matching name
11120  continuousintvalues = lookupmap(:,i) ! return resp. entity list
11121  exit
11122  endif
11123  enddo
11124  exit
11125  elseif(containsrange(filecontent(l),chunkpos)) then
11126  first = io_intvalue(filecontent(l),chunkpos,1)
11127  last = io_intvalue(filecontent(l),chunkpos,3)
11128  do i = first, last, sign(1,last-first)
11131  enddo
11132  exit
11133  else
11134  do i = 1,chunkpos(1)-1 ! interpret up to second to last value
11136  continuousintvalues(1+continuousintvalues(1)) = io_intvalue(filecontent(l),chunkpos,i)
11137  enddo
11138  if ( io_lc(io_stringvalue(filecontent(l),chunkpos,chunkpos(1))) /= 'c' ) then ! line finished, read last value
11140  continuousintvalues(1+continuousintvalues(1)) = io_intvalue(filecontent(l),chunkpos,chunkpos(1))
11141  exit
11142  endif
11143  endif
11144  enddo
11145 
11146 end function continuousintvalues
11147 
11148 
11149 !--------------------------------------------------------------------------------------------------
11151 !--------------------------------------------------------------------------------------------------
11152 logical function containsrange(str,chunkPos)
11154  character(len=*), intent(in) :: str
11155  integer, dimension(:), intent(in) :: chunkpos
11156 
11157  containsrange = .false.
11158  if(chunkpos(1) == 3) then
11159  if(io_lc(io_stringvalue(str,chunkpos,2)) == 'to') containsrange = .true.
11160  endif
11161 
11162 end function containsrange
11163 
11164 
11165 end module discretization_marc
11166 # 24 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
11167 
11168 
11169 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/material.f90" 1
11170 !--------------------------------------------------------------------------------------------------
11175 !--------------------------------------------------------------------------------------------------
11176 module material
11177  use prec
11178  use math
11179  use config
11180  use results
11181  use io
11182  use debug
11183  use numerics
11184  use rotations
11185  use discretization
11186 
11187  implicit none
11188  private
11189 
11190  character(len=*), parameter, public :: &
11191  elasticity_hooke_label = 'hooke', &
11192  plasticity_none_label = 'none', &
11193  plasticity_isotropic_label = 'isotropic', &
11194  plasticity_phenopowerlaw_label = 'phenopowerlaw', &
11195  plasticity_kinehardening_label = 'kinehardening', &
11196  plasticity_dislotwin_label = 'dislotwin', &
11197  plasticity_disloucla_label = 'disloucla', &
11198  plasticity_nonlocal_label = 'nonlocal', &
11199  source_thermal_dissipation_label = 'thermal_dissipation', &
11200  source_thermal_externalheat_label = 'thermal_externalheat', &
11201  source_damage_isobrittle_label = 'damage_isobrittle', &
11202  source_damage_isoductile_label = 'damage_isoductile', &
11203  source_damage_anisobrittle_label = 'damage_anisobrittle', &
11204  source_damage_anisoductile_label = 'damage_anisoductile', &
11205  kinematics_thermal_expansion_label = 'thermal_expansion', &
11206  kinematics_cleavage_opening_label = 'cleavage_opening', &
11207  kinematics_slipplane_opening_label = 'slipplane_opening', &
11209  thermal_isothermal_label = 'isothermal', &
11210  thermal_adiabatic_label = 'adiabatic', &
11211  thermal_conduction_label = 'conduction', &
11212  damage_none_label = 'none', &
11213  damage_local_label = 'local', &
11214  damage_nonlocal_label = 'nonlocal', &
11215  homogenization_none_label = 'none', &
11216  homogenization_isostrain_label = 'isostrain', &
11217  homogenization_rgc_label = 'rgc'
11218 
11219  enum, bind(c); enumerator :: &
11246  damage_none_id, &
11247  damage_local_id, &
11253  end enum
11254 
11255  integer(kind(ELASTICITY_undefined_ID)), dimension(:), allocatable, public, protected :: &
11257  integer(kind(PLASTICITY_undefined_ID)), dimension(:), allocatable, public, protected :: &
11259  integer(kind(THERMAL_isothermal_ID)), dimension(:), allocatable, public, protected :: &
11260  thermal_type
11261  integer(kind(DAMAGE_none_ID)), dimension(:), allocatable, public, protected :: &
11262  damage_type
11263  integer(kind(HOMOGENIZATION_undefined_ID)), dimension(:), allocatable, public, protected :: &
11265 
11266  integer, public, protected :: &
11267  material_nphase, & !< number of phases
11269 
11270  integer(kind(SOURCE_undefined_ID)), dimension(:,:), allocatable, public, protected :: &
11271  phase_source, & !< active sources mechanisms of each phase
11272  phase_kinematics, & !< active kinematic mechanisms of each phase
11274 
11275  integer, public, protected :: &
11277 
11278  integer, dimension(:), allocatable, public, protected :: &
11279  phase_nsources, & !< number of source mechanisms active in each phase
11280  phase_nkinematics, & !< number of kinematic mechanisms active in each phase
11281  phase_nstiffnessdegradations, & !< number of stiffness degradation mechanisms active in each phase
11282  phase_elasticityinstance, & !< instance of particular elasticity of each phase
11283  phase_plasticityinstance, & !< instance of particular plasticity of each phase
11284  homogenization_ngrains, & !< number of grains in each homogenization
11285  homogenization_typeinstance, & !< instance of particular type of each homogenization
11286  thermal_typeinstance, & !< instance of particular type of each thermal transport
11288 
11289  real(preal), dimension(:), allocatable, public, protected :: &
11290  thermal_initialt, & !< initial temperature per each homogenization
11292 
11293  integer, dimension(:), allocatable, public, protected :: & ! (elem)
11295  integer, dimension(:,:), allocatable, public, target :: & ! (ip,elem) ToDo: ugly target for mapping hack
11297  integer, dimension(:,:), allocatable, public, protected :: & ! (constituent,elem)
11299  integer, dimension(:,:,:), allocatable, public, protected :: & ! (constituent,elem)
11301 
11302  type(tplasticstate), allocatable, dimension(:), public :: &
11303  plasticstate
11304  type(tsourcestate), allocatable, dimension(:), public :: &
11305  sourcestate
11306  type(tstate), allocatable, dimension(:), public :: &
11307  homogstate, &
11308  thermalstate, &
11309  damagestate
11310 
11311  integer, dimension(:,:,:), allocatable, public, protected :: &
11313 
11314  type(rotation), dimension(:,:,:), allocatable, public, protected :: &
11316 
11317  logical, dimension(:), allocatable, public, protected :: &
11319 
11320  integer, dimension(:), allocatable, private :: &
11322 
11323  integer, dimension(:,:), allocatable, private :: &
11324  microstructure_phase, & !< phase IDs of each microstructure
11326 
11327  type(rotation), dimension(:), allocatable, private :: &
11329 
11330 
11331 ! BEGIN DEPRECATED
11332  integer, dimension(:,:), allocatable, private, target :: mappinghomogenizationconst
11333 ! END DEPRECATED
11334 
11335  type(thomogmapping), allocatable, dimension(:), public :: &
11336  thermalmapping, & !< mapping for thermal state/fields
11338 
11339  type(group_float), allocatable, dimension(:), public :: &
11340  temperature, & !< temperature field
11341  damage, & !< damage field
11343 
11344  public :: &
11345  material_init, &
11369  damage_none_id, &
11370  damage_local_id, &
11375 
11376 contains
11377 
11378 !--------------------------------------------------------------------------------------------------
11380 !--------------------------------------------------------------------------------------------------
11381 subroutine material_init
11383  integer :: i,e,m,c,h, mydebug, myphase, myhomog, mymicro
11384  integer, dimension(:), allocatable :: &
11385  counterphase, &
11386  counterhomogenization
11387 
11388  mydebug = debug_level(debug_material)
11389 
11390  write(6,'(/,a)') ' <<<+- material init -+>>>'; flush(6)
11391 
11392  call material_parsephase()
11393  if (iand(mydebug,debug_levelbasic) /= 0) write(6,'(a)') ' Phase parsed'; flush(6)
11394 
11396  if (iand(mydebug,debug_levelbasic) /= 0) write(6,'(a)') ' Microstructure parsed'; flush(6)
11397 
11399  if (iand(mydebug,debug_levelbasic) /= 0) write(6,'(a)') ' Homogenization parsed'; flush(6)
11400 
11401  call material_parsetexture()
11402  if (iand(mydebug,debug_levelbasic) /= 0) write(6,'(a)') ' Texture parsed'; flush(6)
11403 
11406 
11407 
11408  allocate(plasticstate(material_nphase))
11409  allocate(sourcestate(material_nphase))
11410  do myphase = 1,material_nphase
11411  allocate(sourcestate(myphase)%p(phase_nsources(myphase)))
11412  enddo
11413 
11417 
11420 
11422  allocate(damage(material_nhomogenization))
11423 
11425 
11426  do m = 1,size(config_microstructure)
11427  if(minval(microstructure_phase(1:microstructure_nconstituents(m),m)) < 1 .or. &
11429  call io_error(150,m,ext_msg='phase')
11430  if(minval(microstructure_texture(1:microstructure_nconstituents(m),m)) < 1 .or. &
11432  call io_error(150,m,ext_msg='texture')
11433  if(microstructure_nconstituents(m) < 1) &
11434  call io_error(151,m)
11435  enddo
11437 
11438  debugout: if (iand(mydebug,debug_levelextensive) /= 0) then
11439  write(6,'(/,a,/)') ' MATERIAL configuration'
11440  write(6,'(a32,1x,a16,1x,a6)') 'homogenization ','type ','grains'
11441  do h = 1,size(config_homogenization)
11442  write(6,'(1x,a32,1x,a16,1x,i6)') config_name_homogenization(h),homogenization_type(h),homogenization_ngrains(h)
11443  enddo
11444  write(6,'(/,a14,18x,1x,a11,1x,a12,1x,a13)') 'microstructure','constituents'
11445  do m = 1,size(config_microstructure)
11446  write(6,'(1x,a32,1x,i12)') config_name_microstructure(m), microstructure_nconstituents(m)
11447  if (microstructure_nconstituents(m) > 0) then
11448  do c = 1,microstructure_nconstituents(m)
11449  write(6,'(a1,1x,a32,1x,a32)') '>',config_name_phase(microstructure_phase(c,m)),&
11451  enddo
11452  write(6,*)
11453  endif
11454  enddo
11455  endif debugout
11456 
11458  allocate(material_texture(homogenization_maxngrains,discretization_nip,discretization_nelem),source=0) !this is only needed by plasticity nonlocal
11460 
11461  do e = 1, discretization_nelem
11462  do i = 1, discretization_nip
11463  mymicro = discretization_microstructureat(e)
11465  if(microstructure_phase(c,mymicro) > 0) then
11466  material_phaseat(c,e) = microstructure_phase(c,mymicro)
11467  else
11468  call io_error(150,ext_msg='phase')
11469  endif
11470  if(microstructure_texture(c,mymicro) > 0) then
11471  material_texture(c,i,e) = microstructure_texture(c,mymicro)
11473  else
11474  call io_error(150,ext_msg='texture')
11475  endif
11476  enddo
11477  enddo
11478  enddo
11479 
11480  deallocate(microstructure_phase)
11481  deallocate(microstructure_texture)
11482  deallocate(texture_orientation)
11483 
11484 
11487 
11488  allocate(counterhomogenization(size(config_homogenization)),source=0)
11489  do e = 1, discretization_nelem
11490  do i = 1, discretization_nip
11491  counterhomogenization(material_homogenizationat(e)) = &
11492  counterhomogenization(material_homogenizationat(e)) + 1
11493  material_homogenizationmemberat(i,e) = counterhomogenization(material_homogenizationat(e))
11494  enddo
11495  enddo
11496 
11498 
11499  allocate(counterphase(size(config_phase)),source=0)
11500  do e = 1, discretization_nelem
11501  do i = 1, discretization_nip
11502  do c = 1, homogenization_maxngrains
11503  counterphase(material_phaseat(c,e)) = &
11504  counterphase(material_phaseat(c,e)) + 1
11505  material_phasememberat(c,i,e) = counterphase(material_phaseat(c,e))
11506  enddo
11507  enddo
11508  enddo
11509 
11510  call config_deallocate('material.config/microstructure')
11511  call config_deallocate('material.config/texture')
11512 
11513  call results_openjobfile
11517 
11518 
11519 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
11520 ! BEGIN DEPRECATED
11522 
11523 ! hack needed to initialize field values used during constitutive initialization
11524  do myhomog = 1,size(config_homogenization)
11527  allocate(temperature(myhomog)%p(1), source=thermal_initialt(myhomog))
11528  allocate(damage(myhomog)%p(1), source=damage_initialphi(myhomog))
11529  allocate(temperaturerate(myhomog)%p(1), source=0.0_preal)
11530  enddo
11531 ! END DEPRECATED
11532 
11533 end subroutine material_init
11534 
11535 !--------------------------------------------------------------------------------------------------
11537 !--------------------------------------------------------------------------------------------------
11540  integer :: h
11541  character(len=pStringLen) :: tag
11542 
11543  logical, dimension(:), allocatable :: homogenization_active
11544 
11547  allocate(damage_type(size(config_homogenization)), source=damage_none_id)
11548  allocate(homogenization_typeinstance(size(config_homogenization)), source=0)
11549  allocate(thermal_typeinstance(size(config_homogenization)), source=0)
11550  allocate(damage_typeinstance(size(config_homogenization)), source=0)
11551  allocate(homogenization_ngrains(size(config_homogenization)), source=0)
11552  allocate(homogenization_active(size(config_homogenization)), source=.false.) !!!!!!!!!!!!!!!
11553  allocate(thermal_initialt(size(config_homogenization)), source=300.0_preal)
11554  allocate(damage_initialphi(size(config_homogenization)), source=1.0_preal)
11555 
11556  forall (h = 1:size(config_homogenization)) &
11557  homogenization_active(h) = any(discretization_homogenizationat == h)
11558 
11559 
11560  do h=1, size(config_homogenization)
11561 
11562  tag = config_homogenization(h)%getString('mech')
11563  select case (trim(tag))
11566  homogenization_ngrains(h) = 1
11569  homogenization_ngrains(h) = config_homogenization(h)%getInt('nconstituents')
11572  homogenization_ngrains(h) = config_homogenization(h)%getInt('nconstituents')
11573  case default
11574  call io_error(500,ext_msg=trim(tag))
11575  end select
11576 
11578 
11579  if (config_homogenization(h)%keyExists('thermal')) then
11580  thermal_initialt(h) = config_homogenization(h)%getFloat('t0',defaultval=300.0_preal)
11581 
11582  tag = config_homogenization(h)%getString('thermal')
11583  select case (trim(tag))
11590  case default
11591  call io_error(500,ext_msg=trim(tag))
11592  end select
11593 
11594  endif
11595 
11596  if (config_homogenization(h)%keyExists('damage')) then
11597  damage_initialphi(h) = config_homogenization(h)%getFloat('initialdamage',defaultval=1.0_preal)
11598 
11599  tag = config_homogenization(h)%getString('damage')
11600  select case (trim(tag))
11601  case(damage_none_label)
11603  case(damage_local_label)
11605  case(damage_nonlocal_label)
11607  case default
11608  call io_error(500,ext_msg=trim(tag))
11609  end select
11610 
11611  endif
11612 
11613  enddo
11614 
11615  do h=1, size(config_homogenization)
11617  thermal_typeinstance(h) = count(thermal_type(1:h) == thermal_type(h))
11618  damage_typeinstance(h) = count(damage_type(1:h) == damage_type(h))
11619  enddo
11620 
11621  homogenization_maxngrains = maxval(homogenization_ngrains,homogenization_active)
11622 
11623 end subroutine material_parsehomogenization
11624 
11625 
11626 !--------------------------------------------------------------------------------------------------
11628 !--------------------------------------------------------------------------------------------------
11631  character(len=pStringLen), dimension(:), allocatable :: &
11632  strings
11633  integer, allocatable, dimension(:) :: chunkPos
11634  integer :: m, c, i
11635  character(len=pStringLen) :: &
11636  tag
11637  real(pReal), dimension(:,:), allocatable :: &
11638  microstructure_fraction
11639  integer :: &
11640  maxNconstituents
11641 
11642  allocate(microstructure_nconstituents(size(config_microstructure)), source=0)
11643 
11645  call io_error(155,ext_msg='More microstructures in geometry than sections in material.config')
11646 
11647  do m=1, size(config_microstructure)
11648  microstructure_nconstituents(m) = config_microstructure(m)%countKeys('(constituent)')
11649  enddo
11650 
11651  maxnconstituents = maxval(microstructure_nconstituents)
11652  allocate(microstructure_phase(maxnconstituents,size(config_microstructure)),source=0)
11653  allocate(microstructure_texture(maxnconstituents,size(config_microstructure)),source=0)
11654  allocate(microstructure_fraction(maxnconstituents,size(config_microstructure)),source=0.0_preal)
11655 
11656  allocate(strings(1)) ! Intel 16.0 Bug
11657  do m=1, size(config_microstructure)
11658  strings = config_microstructure(m)%getStrings('(constituent)',raw=.true.)
11659  do c = 1, size(strings)
11660  chunkpos = io_stringpos(strings(c))
11661 
11662  do i = 1,5,2
11663  tag = io_stringvalue(strings(c),chunkpos,i)
11664 
11665  select case (tag)
11666  case('phase')
11667  microstructure_phase(c,m) = io_intvalue(strings(c),chunkpos,i+1)
11668  case('texture')
11669  microstructure_texture(c,m) = io_intvalue(strings(c),chunkpos,i+1)
11670  case('fraction')
11671  microstructure_fraction(c,m) = io_floatvalue(strings(c),chunkpos,i+1)
11672  end select
11673 
11674  enddo
11675  enddo
11676  if (dneq(sum(microstructure_fraction(:,m)),1.0_preal)) call io_error(153,ext_msg=config_name_microstructure(m))
11677  enddo
11678 
11679 
11680 end subroutine material_parsemicrostructure
11681 
11682 
11683 !--------------------------------------------------------------------------------------------------
11685 !--------------------------------------------------------------------------------------------------
11686 subroutine material_parsephase
11688  integer :: sourceCtr, kinematicsCtr, stiffDegradationCtr, p
11689  character(len=pStringLen), dimension(:), allocatable :: str
11690 
11691 
11692  allocate(phase_elasticity(size(config_phase)),source=elasticity_undefined_id)
11693  allocate(phase_plasticity(size(config_phase)),source=plasticity_undefined_id)
11694  allocate(phase_nsources(size(config_phase)), source=0)
11695  allocate(phase_nkinematics(size(config_phase)), source=0)
11696  allocate(phase_nstiffnessdegradations(size(config_phase)),source=0)
11697  allocate(phase_localplasticity(size(config_phase)), source=.false.)
11698 
11699  do p=1, size(config_phase)
11700  phase_nsources(p) = config_phase(p)%countKeys('(source)')
11701  phase_nkinematics(p) = config_phase(p)%countKeys('(kinematics)')
11702  phase_nstiffnessdegradations(p) = config_phase(p)%countKeys('(stiffness_degradation)')
11703  phase_localplasticity(p) = .not. config_phase(p)%KeyExists('/nonlocal/')
11704 
11705  select case (config_phase(p)%getString('elasticity'))
11706  case (elasticity_hooke_label)
11708  case default
11709  call io_error(200,ext_msg=trim(config_phase(p)%getString('elasticity')))
11710  end select
11711 
11712  select case (config_phase(p)%getString('plasticity'))
11713  case (plasticity_none_label)
11727  case default
11728  call io_error(201,ext_msg=trim(config_phase(p)%getString('plasticity')))
11729  end select
11730 
11731  enddo
11732 
11733  allocate(phase_source(maxval(phase_nsources),size(config_phase)), source=source_undefined_id)
11737  do p=1, size(config_phase)
11738 
11739  str = ['GfortranBug86277']
11740  str = config_phase(p)%getStrings('(source)',defaultval=str)
11741  if (str(1) == 'GfortranBug86277') str = [character(len=pStringLen)::]
11742 
11743 
11744 
11745  do sourcectr = 1, size(str)
11746  select case (trim(str(sourcectr)))
11759  end select
11760  enddo
11761 
11762 
11763  str = ['GfortranBug86277']
11764  str = config_phase(p)%getStrings('(kinematics)',defaultval=str)
11765  if (str(1) == 'GfortranBug86277') str = [character(len=pStringLen)::]
11766 
11767 
11768 
11769  do kinematicsctr = 1, size(str)
11770  select case (trim(str(kinematicsctr)))
11777  end select
11778  enddo
11779 
11780  str = ['GfortranBug86277']
11781  str = config_phase(p)%getStrings('(stiffness_degradation)',defaultval=str)
11782  if (str(1) == 'GfortranBug86277') str = [character(len=pStringLen)::]
11783 
11784 
11785 
11786  do stiffdegradationctr = 1, size(str)
11787  select case (trim(str(stiffdegradationctr)))
11790  end select
11791  enddo
11792  enddo
11793 
11794  allocate(phase_plasticityinstance(size(config_phase)),source=0)
11795  allocate(phase_elasticityinstance(size(config_phase)),source=0)
11796 
11797  do p=1, size(config_phase)
11800  enddo
11801 
11802 end subroutine material_parsephase
11803 
11804 
11805 !--------------------------------------------------------------------------------------------------
11807 !--------------------------------------------------------------------------------------------------
11808 subroutine material_parsetexture
11810  integer :: j,t
11811  character(len=pStringLen), dimension(:), allocatable :: strings ! Values for given key in material config
11812  integer, dimension(:), allocatable :: chunkPos
11813  real(pReal), dimension(3,3) :: transformation ! maps texture to microstructure coordinate system
11814  real(pReal), dimension(3) :: Eulers ! Euler angles in degrees from file
11815  type(rotation) :: transformation_
11816 
11817  do t=1, size(config_texture)
11818  if (config_texture(t)%countKeys('(gauss)') /= 1) call io_error(147,ext_msg='count((gauss)) != 1')
11819  if (config_texture(t)%keyExists('symmetry')) call io_error(147,ext_msg='symmetry')
11820  if (config_texture(t)%keyExists('(random)')) call io_error(147,ext_msg='(random)')
11821  if (config_texture(t)%keyExists('(fiber)')) call io_error(147,ext_msg='(fiber)')
11822  enddo
11823 
11824  allocate(texture_orientation(size(config_texture)))
11825 
11826  do t=1, size(config_texture)
11827 
11828  strings = config_texture(t)%getStrings('(gauss)',raw= .true.)
11829  chunkpos = io_stringpos(strings(1))
11830  do j = 1,5,2
11831  select case (io_stringvalue(strings(1),chunkpos,j))
11832  case('phi1')
11833  eulers(1) = io_floatvalue(strings(1),chunkpos,j+1)
11834  case('phi')
11835  eulers(2) = io_floatvalue(strings(1),chunkpos,j+1)
11836  case('phi2')
11837  eulers(3) = io_floatvalue(strings(1),chunkpos,j+1)
11838  end select
11839  enddo
11840  call texture_orientation(t)%fromEulers(eulers,degrees=.true.)
11841 
11842  if (config_texture(t)%keyExists('axes')) then
11843  strings = config_texture(t)%getStrings('axes')
11844  do j = 1, 3 ! look for "x", "y", and "z" entries
11845  select case (strings(j))
11846  case('x', '+x')
11847  transformation(j,1:3) = [ 1.0_preal, 0.0_preal, 0.0_preal] ! original axis is now +x-axis
11848  case('-x')
11849  transformation(j,1:3) = [-1.0_preal, 0.0_preal, 0.0_preal] ! original axis is now -x-axis
11850  case('y', '+y')
11851  transformation(j,1:3) = [ 0.0_preal, 1.0_preal, 0.0_preal] ! original axis is now +y-axis
11852  case('-y')
11853  transformation(j,1:3) = [ 0.0_preal,-1.0_preal, 0.0_preal] ! original axis is now -y-axis
11854  case('z', '+z')
11855  transformation(j,1:3) = [ 0.0_preal, 0.0_preal, 1.0_preal] ! original axis is now +z-axis
11856  case('-z')
11857  transformation(j,1:3) = [ 0.0_preal, 0.0_preal,-1.0_preal] ! original axis is now -z-axis
11858  case default
11859  call io_error(157,t)
11860  end select
11861  enddo
11862  call transformation_%fromMatrix(transformation)
11863  texture_orientation(t) = texture_orientation(t) * transformation_
11864  endif
11865 
11866  enddo
11867 
11868 end subroutine material_parsetexture
11869 
11870 
11871 !--------------------------------------------------------------------------------------------------
11873 !--------------------------------------------------------------------------------------------------
11874 subroutine material_allocateplasticstate(phase,NipcMyPhase,&
11875  sizeState,sizeDotState,sizeDeltaState)
11877  integer, intent(in) :: &
11878  phase, &
11879  nipcmyphase, &
11880  sizestate, &
11881  sizedotstate, &
11882  sizedeltastate
11883 
11884  plasticstate(phase)%sizeState = sizestate
11885  plasticstate(phase)%sizeDotState = sizedotstate
11886  plasticstate(phase)%sizeDeltaState = sizedeltastate
11887  plasticstate(phase)%offsetDeltaState = sizestate-sizedeltastate ! deltaState occupies latter part of state by definition
11888 
11889  allocate(plasticstate(phase)%atol (sizestate), source=0.0_preal)
11890  allocate(plasticstate(phase)%state0 (sizestate,nipcmyphase), source=0.0_preal)
11891  allocate(plasticstate(phase)%partionedState0 (sizestate,nipcmyphase), source=0.0_preal)
11892  allocate(plasticstate(phase)%subState0 (sizestate,nipcmyphase), source=0.0_preal)
11893  allocate(plasticstate(phase)%state (sizestate,nipcmyphase), source=0.0_preal)
11894 
11895  allocate(plasticstate(phase)%dotState (sizedotstate,nipcmyphase),source=0.0_preal)
11896  if (numerics_integrator == 1) then
11897  allocate(plasticstate(phase)%previousDotState (sizedotstate,nipcmyphase),source=0.0_preal)
11898  allocate(plasticstate(phase)%previousDotState2 (sizedotstate,nipcmyphase),source=0.0_preal)
11899  endif
11900  if (numerics_integrator == 4) &
11901  allocate(plasticstate(phase)%RK4dotState (4,sizedotstate,nipcmyphase),source=0.0_preal)
11902  if (numerics_integrator == 5) &
11903  allocate(plasticstate(phase)%RKCK45dotState (6,sizedotstate,nipcmyphase),source=0.0_preal)
11904 
11905  allocate(plasticstate(phase)%deltaState (sizedeltastate,nipcmyphase),source=0.0_preal)
11906 
11907 end subroutine material_allocateplasticstate
11908 
11909 
11910 !--------------------------------------------------------------------------------------------------
11912 !--------------------------------------------------------------------------------------------------
11913 subroutine material_allocatesourcestate(phase,of,NipcMyPhase,&
11914  sizeState,sizeDotState,sizeDeltaState)
11916  integer, intent(in) :: &
11917  phase, &
11918  of, &
11919  nipcmyphase, &
11920  sizestate, sizedotstate,sizedeltastate
11921 
11922  sourcestate(phase)%p(of)%sizeState = sizestate
11923  sourcestate(phase)%p(of)%sizeDotState = sizedotstate
11924  sourcestate(phase)%p(of)%sizeDeltaState = sizedeltastate
11925  sourcestate(phase)%p(of)%offsetDeltaState = sizestate-sizedeltastate ! deltaState occupies latter part of state by definition
11926 
11927  allocate(sourcestate(phase)%p(of)%atol (sizestate), source=0.0_preal)
11928  allocate(sourcestate(phase)%p(of)%state0 (sizestate,nipcmyphase), source=0.0_preal)
11929  allocate(sourcestate(phase)%p(of)%partionedState0 (sizestate,nipcmyphase), source=0.0_preal)
11930  allocate(sourcestate(phase)%p(of)%subState0 (sizestate,nipcmyphase), source=0.0_preal)
11931  allocate(sourcestate(phase)%p(of)%state (sizestate,nipcmyphase), source=0.0_preal)
11932 
11933  allocate(sourcestate(phase)%p(of)%dotState (sizedotstate,nipcmyphase),source=0.0_preal)
11934  if (numerics_integrator == 1) then
11935  allocate(sourcestate(phase)%p(of)%previousDotState (sizedotstate,nipcmyphase),source=0.0_preal)
11936  allocate(sourcestate(phase)%p(of)%previousDotState2 (sizedotstate,nipcmyphase),source=0.0_preal)
11937  endif
11938  if (numerics_integrator == 4) &
11939  allocate(sourcestate(phase)%p(of)%RK4dotState (4,sizedotstate,nipcmyphase),source=0.0_preal)
11940  if (numerics_integrator == 5) &
11941  allocate(sourcestate(phase)%p(of)%RKCK45dotState (6,sizedotstate,nipcmyphase),source=0.0_preal)
11942 
11943  allocate(sourcestate(phase)%p(of)%deltaState (sizedeltastate,nipcmyphase),source=0.0_preal)
11944 
11945 end subroutine material_allocatesourcestate
11946 
11947 end module material
11948 # 26 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
11949 
11950 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/lattice.f90" 1
11951 !--------------------------------------------------------------------------------------------------
11957 ! and cleavage as well as interaction among the various systems
11958 !--------------------------------------------------------------------------------------------------
11959 module lattice
11960  use prec
11961  use io
11962  use config
11963  use math
11964  use rotations
11965 
11966  implicit none
11967  private
11968 
11969 !--------------------------------------------------------------------------------------------------
11970 ! face centered cubic
11971  integer, dimension(2), parameter :: &
11972  fcc_nslipsystem = [12, 6]
11973 
11974  integer, dimension(1), parameter :: &
11975  fcc_ntwinsystem = [12]
11976 
11977  integer, dimension(1), parameter :: &
11978  fcc_ntranssystem = [12]
11979 
11980  integer, dimension(1), parameter :: &
11981  fcc_ncleavagesystem = [3]
11982 
11983  integer, parameter :: &
11984 
11985  fcc_nslip = sum(fcc_nslipsystem), &
11986  fcc_ntwin = sum(fcc_ntwinsystem), &
11987  fcc_ntrans = sum(fcc_ntranssystem), &
11989 
11990 
11991 
11992 
11993 
11994 
11995 
11996  real(preal), dimension(3+3,FCC_NSLIP), parameter :: &
11997  fcc_systemslip = reshape(real([&
11998  ! Slip direction Plane normal ! SCHMID-BOAS notation
11999  0, 1,-1, 1, 1, 1, & ! B2
12000  -1, 0, 1, 1, 1, 1, & ! B4
12001  1,-1, 0, 1, 1, 1, & ! B5
12002  0,-1,-1, -1,-1, 1, & ! C1
12003  1, 0, 1, -1,-1, 1, & ! C3
12004  -1, 1, 0, -1,-1, 1, & ! C5
12005  0,-1, 1, 1,-1,-1, & ! A2
12006  -1, 0,-1, 1,-1,-1, & ! A3
12007  1, 1, 0, 1,-1,-1, & ! A6
12008  0, 1, 1, -1, 1,-1, & ! D1
12009  1, 0,-1, -1, 1,-1, & ! D4
12010  -1,-1, 0, -1, 1,-1, & ! D6
12011  ! Slip system <110>{110}
12012  1, 1, 0, 1,-1, 0, &
12013  1,-1, 0, 1, 1, 0, &
12014  1, 0, 1, 1, 0,-1, &
12015  1, 0,-1, 1, 0, 1, &
12016  0, 1, 1, 0, 1,-1, &
12017  0, 1,-1, 0, 1, 1 &
12018  ],preal),shape(fcc_systemslip))
12019 
12020  real(preal), dimension(3+3,FCC_NTWIN), parameter :: &
12021  fcc_systemtwin = reshape(real( [&
12022  -2, 1, 1, 1, 1, 1, &
12023  1,-2, 1, 1, 1, 1, &
12024  1, 1,-2, 1, 1, 1, &
12025  2,-1, 1, -1,-1, 1, &
12026  -1, 2, 1, -1,-1, 1, &
12027  -1,-1,-2, -1,-1, 1, &
12028  -2,-1,-1, 1,-1,-1, &
12029  1, 2,-1, 1,-1,-1, &
12030  1,-1, 2, 1,-1,-1, &
12031  2, 1,-1, -1, 1,-1, &
12032  -1,-2,-1, -1, 1,-1, &
12033  -1, 1, 2, -1, 1,-1 &
12034  ],preal),shape(fcc_systemtwin))
12035 
12036  integer, dimension(2,FCC_NTWIN), parameter, public :: &
12038  2,3, &
12039  1,3, &
12040  1,2, &
12041  5,6, &
12042  4,6, &
12043  4,5, &
12044  8,9, &
12045  7,9, &
12046  7,8, &
12047  11,12, &
12048  10,12, &
12049  10,11 &
12051 
12052  real(preal), dimension(3+3,FCC_NCLEAVAGE), parameter :: &
12053  fcc_systemcleavage = reshape(real([&
12054  ! Cleavage direction Plane normal
12055  0, 1, 0, 1, 0, 0, &
12056  0, 0, 1, 0, 1, 0, &
12057  1, 0, 0, 0, 0, 1 &
12058  ],preal),shape(fcc_systemcleavage))
12059 
12060 !--------------------------------------------------------------------------------------------------
12061 ! body centered cubic
12062  integer, dimension(2), parameter :: &
12063  bcc_nslipsystem = [12, 12]
12064 
12065  integer, dimension(1), parameter :: &
12066  bcc_ntwinsystem = [12]
12067 
12068  integer, dimension(1), parameter :: &
12069  bcc_ncleavagesystem = [3]
12070 
12071  integer, parameter :: &
12072 
12073  bcc_nslip = sum(bcc_nslipsystem), &
12074  bcc_ntwin = sum(bcc_ntwinsystem), &
12076 
12077 
12078 
12079 
12080 
12081 
12082  real(preal), dimension(3+3,BCC_NSLIP), parameter :: &
12083  bcc_systemslip = reshape(real([&
12084  ! Slip direction Plane normal
12085  ! Slip system <111>{110}
12086  1,-1, 1, 0, 1, 1, &
12087  -1,-1, 1, 0, 1, 1, &
12088  1, 1, 1, 0,-1, 1, &
12089  -1, 1, 1, 0,-1, 1, &
12090  -1, 1, 1, 1, 0, 1, &
12091  -1,-1, 1, 1, 0, 1, &
12092  1, 1, 1, -1, 0, 1, &
12093  1,-1, 1, -1, 0, 1, &
12094  -1, 1, 1, 1, 1, 0, &
12095  -1, 1,-1, 1, 1, 0, &
12096  1, 1, 1, -1, 1, 0, &
12097  1, 1,-1, -1, 1, 0, &
12098  ! Slip system <111>{112}
12099  -1, 1, 1, 2, 1, 1, &
12100  1, 1, 1, -2, 1, 1, &
12101  1, 1,-1, 2,-1, 1, &
12102  1,-1, 1, 2, 1,-1, &
12103  1,-1, 1, 1, 2, 1, &
12104  1, 1,-1, -1, 2, 1, &
12105  1, 1, 1, 1,-2, 1, &
12106  -1, 1, 1, 1, 2,-1, &
12107  1, 1,-1, 1, 1, 2, &
12108  1,-1, 1, -1, 1, 2, &
12109  -1, 1, 1, 1,-1, 2, &
12110  1, 1, 1, 1, 1,-2 &
12111  ],preal),shape(bcc_systemslip))
12112 
12113  real(preal), dimension(3+3,BCC_NTWIN), parameter :: &
12114  bcc_systemtwin = reshape(real([&
12115  ! Twin system <111>{112}
12116  -1, 1, 1, 2, 1, 1, &
12117  1, 1, 1, -2, 1, 1, &
12118  1, 1,-1, 2,-1, 1, &
12119  1,-1, 1, 2, 1,-1, &
12120  1,-1, 1, 1, 2, 1, &
12121  1, 1,-1, -1, 2, 1, &
12122  1, 1, 1, 1,-2, 1, &
12123  -1, 1, 1, 1, 2,-1, &
12124  1, 1,-1, 1, 1, 2, &
12125  1,-1, 1, -1, 1, 2, &
12126  -1, 1, 1, 1,-1, 2, &
12127  1, 1, 1, 1, 1,-2 &
12128  ],preal),shape(bcc_systemtwin))
12129 
12130  real(preal), dimension(3+3,BCC_NCLEAVAGE), parameter :: &
12131  bcc_systemcleavage = reshape(real([&
12132  ! Cleavage direction Plane normal
12133  0, 1, 0, 1, 0, 0, &
12134  0, 0, 1, 0, 1, 0, &
12135  1, 0, 0, 0, 0, 1 &
12136  ],preal),shape(bcc_systemcleavage))
12137 
12138 !--------------------------------------------------------------------------------------------------
12139 ! hexagonal
12140  integer, dimension(6), parameter :: &
12141  hex_nslipsystem = [3, 3, 3, 6, 12, 6]
12142 
12143  integer, dimension(4), parameter :: &
12144  hex_ntwinsystem = [6, 6, 6, 6]
12145 
12146  integer, parameter :: &
12147 
12148  hex_nslip = sum(hex_nslipsystem), &
12149  hex_ntwin = sum(hex_ntwinsystem)
12150 
12151 
12152 
12153 
12154 
12155  real(preal), dimension(4+4,HEX_NSLIP), parameter :: &
12156  hex_systemslip = reshape(real([&
12157  ! Slip direction Plane normal
12158  ! Basal systems <-1-1.0>{00.1} (independent of c/a-ratio, Bravais notation (4 coordinate base))
12159  2, -1, -1, 0, 0, 0, 0, 1, &
12160  -1, 2, -1, 0, 0, 0, 0, 1, &
12161  -1, -1, 2, 0, 0, 0, 0, 1, &
12162  ! 1st type prismatic systems <-1-1.0>{1-1.0} (independent of c/a-ratio)
12163  2, -1, -1, 0, 0, 1, -1, 0, &
12164  -1, 2, -1, 0, -1, 0, 1, 0, &
12165  -1, -1, 2, 0, 1, -1, 0, 0, &
12166  ! 2nd type prismatic systems <-11.0>{11.0} -- a slip; plane normals independent of c/a-ratio
12167  -1, 1, 0, 0, 1, 1, -2, 0, &
12168  0, -1, 1, 0, -2, 1, 1, 0, &
12169  1, 0, -1, 0, 1, -2, 1, 0, &
12170  ! 1st type 1st order pyramidal systems <-1-1.0>{-11.1} -- plane normals depend on the c/a-ratio
12171  -1, 2, -1, 0, 1, 0, -1, 1, &
12172  -2, 1, 1, 0, 0, 1, -1, 1, &
12173  -1, -1, 2, 0, -1, 1, 0, 1, &
12174  1, -2, 1, 0, -1, 0, 1, 1, &
12175  2, -1, -1, 0, 0, -1, 1, 1, &
12176  1, 1, -2, 0, 1, -1, 0, 1, &
12177  ! pyramidal system: c+a slip <11.3>{-10.1} -- plane normals depend on the c/a-ratio
12178  -2, 1, 1, 3, 1, 0, -1, 1, &
12179  -1, -1, 2, 3, 1, 0, -1, 1, &
12180  -1, -1, 2, 3, 0, 1, -1, 1, &
12181  1, -2, 1, 3, 0, 1, -1, 1, &
12182  1, -2, 1, 3, -1, 1, 0, 1, &
12183  2, -1, -1, 3, -1, 1, 0, 1, &
12184  2, -1, -1, 3, -1, 0, 1, 1, &
12185  1, 1, -2, 3, -1, 0, 1, 1, &
12186  1, 1, -2, 3, 0, -1, 1, 1, &
12187  -1, 2, -1, 3, 0, -1, 1, 1, &
12188  -1, 2, -1, 3, 1, -1, 0, 1, &
12189  -2, 1, 1, 3, 1, -1, 0, 1, &
12190  ! pyramidal system: c+a slip <11.3>{-1-1.2} -- as for hexagonal ice (Castelnau et al. 1996, similar to twin system found below)
12191  -1, -1, 2, 3, 1, 1, -2, 2, & ! <11.3>{-1-1.2} shear = 2((c/a)^2-2)/(3 c/a)
12192  1, -2, 1, 3, -1, 2, -1, 2, &
12193  2, -1, -1, 3, -2, 1, 1, 2, &
12194  1, 1, -2, 3, -1, -1, 2, 2, &
12195  -1, 2, -1, 3, 1, -2, 1, 2, &
12196  -2, 1, 1, 3, 2, -1, -1, 2 &
12197  ],preal),shape(hex_systemslip))
12198 
12199  real(preal), dimension(4+4,HEX_NTWIN), parameter :: &
12200  hex_systemtwin = reshape(real([&
12201  ! Compression or Tension = f(twinning shear=f(c/a)) for each metal ! (according to Yoo 1981)
12202  -1, 0, 1, 1, 1, 0, -1, 2, & ! <-10.1>{10.2} shear = (3-(c/a)^2)/(sqrt(3) c/a)
12203  0, -1, 1, 1, 0, 1, -1, 2, &
12204  1, -1, 0, 1, -1, 1, 0, 2, &
12205  1, 0, -1, 1, -1, 0, 1, 2, &
12206  0, 1, -1, 1, 0, -1, 1, 2, &
12207  -1, 1, 0, 1, 1, -1, 0, 2, &
12208 !
12209  -1, -1, 2, 6, 1, 1, -2, 1, & ! <11.6>{-1-1.1} shear = 1/(c/a)
12210  1, -2, 1, 6, -1, 2, -1, 1, &
12211  2, -1, -1, 6, -2, 1, 1, 1, &
12212  1, 1, -2, 6, -1, -1, 2, 1, &
12213  -1, 2, -1, 6, 1, -2, 1, 1, &
12214  -2, 1, 1, 6, 2, -1, -1, 1, &
12215 !
12216  1, 0, -1, -2, 1, 0, -1, 1, & ! <10.-2>{10.1} shear = (4(c/a)^2-9)/(4 sqrt(3) c/a)
12217  0, 1, -1, -2, 0, 1, -1, 1, &
12218  -1, 1, 0, -2, -1, 1, 0, 1, &
12219  -1, 0, 1, -2, -1, 0, 1, 1, &
12220  0, -1, 1, -2, 0, -1, 1, 1, &
12221  1, -1, 0, -2, 1, -1, 0, 1, &
12222 !
12223  1, 1, -2, -3, 1, 1, -2, 2, & ! <11.-3>{11.2} shear = 2((c/a)^2-2)/(3 c/a)
12224  -1, 2, -1, -3, -1, 2, -1, 2, &
12225  -2, 1, 1, -3, -2, 1, 1, 2, &
12226  -1, -1, 2, -3, -1, -1, 2, 2, &
12227  1, -2, 1, -3, 1, -2, 1, 2, &
12228  2, -1, -1, -3, 2, -1, -1, 2 &
12229  ],preal),shape(hex_systemtwin))
12230 
12231 !--------------------------------------------------------------------------------------------------
12232 ! body centered tetragonal
12233  integer, dimension(13), parameter :: &
12234  bct_nslipsystem = [2, 2, 2, 4, 2, 4, 2, 2, 4, 8, 4, 8, 8 ]
12235 
12236  integer, parameter :: &
12237 
12238  bct_nslip = sum(bct_nslipsystem)
12239 
12240 
12241 
12242 
12243  real(preal), dimension(3+3,BCT_NSLIP), parameter :: &
12244  bct_systemslip = reshape(real([&
12245  ! Slip direction Plane normal
12246  ! Slip family 1 {100)<001] (Bravais notation {hkl)<uvw] for bct c/a = 0.5456)
12247  0, 0, 1, 1, 0, 0, &
12248  0, 0, 1, 0, 1, 0, &
12249  ! Slip family 2 {110)<001]
12250  0, 0, 1, 1, 1, 0, &
12251  0, 0, 1, -1, 1, 0, &
12252  ! slip family 3 {100)<010]
12253  0, 1, 0, 1, 0, 0, &
12254  1, 0, 0, 0, 1, 0, &
12255  ! Slip family 4 {110)<1-11]/2
12256  1,-1, 1, 1, 1, 0, &
12257  1,-1,-1, 1, 1, 0, &
12258  -1,-1,-1, -1, 1, 0, &
12259  -1,-1, 1, -1, 1, 0, &
12260  ! Slip family 5 {110)<1-10]
12261  1, -1, 0, 1, 1, 0, &
12262  1, 1, 0, 1,-1, 0, &
12263  ! Slip family 6 {100)<011]
12264  0, 1, 1, 1, 0, 0, &
12265  0,-1, 1, 1, 0, 0, &
12266  -1, 0, 1, 0, 1, 0, &
12267  1, 0, 1, 0, 1, 0, &
12268  ! Slip family 7 {001)<010]
12269  0, 1, 0, 0, 0, 1, &
12270  1, 0, 0, 0, 0, 1, &
12271  ! Slip family 8 {001)<110]
12272  1, 1, 0, 0, 0, 1, &
12273  -1, 1, 0, 0, 0, 1, &
12274  ! Slip family 9 {011)<01-1]
12275  0, 1,-1, 0, 1, 1, &
12276  0,-1,-1, 0,-1, 1, &
12277  -1, 0,-1, -1, 0, 1, &
12278  1, 0,-1, 1, 0, 1, &
12279  ! Slip family 10 {011)<1-11]/2
12280  1,-1, 1, 0, 1, 1, &
12281  1, 1,-1, 0, 1, 1, &
12282  1, 1, 1, 0, 1,-1, &
12283  -1, 1, 1, 0, 1,-1, &
12284  1,-1,-1, 1, 0, 1, &
12285  -1,-1, 1, 1, 0, 1, &
12286  1, 1, 1, 1, 0,-1, &
12287  1,-1, 1, 1, 0,-1, &
12288  ! Slip family 11 {011)<100]
12289  1, 0, 0, 0, 1, 1, &
12290  1, 0, 0, 0, 1,-1, &
12291  0, 1, 0, 1, 0, 1, &
12292  0, 1, 0, 1, 0,-1, &
12293  ! Slip family 12 {211)<01-1]
12294  0, 1,-1, 2, 1, 1, &
12295  0,-1,-1, 2,-1, 1, &
12296  1, 0,-1, 1, 2, 1, &
12297  -1, 0,-1, -1, 2, 1, &
12298  0, 1,-1, -2, 1, 1, &
12299  0,-1,-1, -2,-1, 1, &
12300  -1, 0,-1, -1,-2, 1, &
12301  1, 0,-1, 1,-2, 1, &
12302  ! Slip family 13 {211)<-111]/2
12303  -1, 1, 1, 2, 1, 1, &
12304  -1,-1, 1, 2,-1, 1, &
12305  1,-1, 1, 1, 2, 1, &
12306  -1,-1, 1, -1, 2, 1, &
12307  1, 1, 1, -2, 1, 1, &
12308  1,-1, 1, -2,-1, 1, &
12309  -1, 1, 1, -1,-2, 1, &
12310  1, 1, 1, 1,-2, 1 &
12311  ],preal),shape(bct_systemslip))
12312 
12313 !--------------------------------------------------------------------------------------------------
12314 ! orthorhombic
12315  integer, dimension(3), parameter :: &
12316  ort_ncleavagesystem = [1, 1, 1]
12317 
12318  integer, parameter :: &
12319 
12321 
12322 
12323 
12324 
12325  real(preal), dimension(3+3,ORT_NCLEAVAGE), parameter :: &
12326  ort_systemcleavage = reshape(real([&
12327  ! Cleavage direction Plane normal
12328  0, 1, 0, 1, 0, 0, &
12329  0, 0, 1, 0, 1, 0, &
12330  1, 0, 0, 0, 0, 1 &
12331  ],preal),shape(ort_systemcleavage))
12332 
12333 
12334  enum, bind(c); enumerator :: &
12336  lattice_iso_id, &
12337  lattice_fcc_id, &
12338  lattice_bcc_id, &
12339  lattice_bct_id, &
12340  lattice_hex_id, &
12342  end enum
12343 
12344 ! SHOULD NOT BE PART OF LATTICE BEGIN
12345  real(preal), dimension(:), allocatable, public, protected :: &
12350  real(preal), dimension(:,:,:), allocatable, public, protected :: &
12351  lattice_c66, &
12354  integer(kind(lattice_UNDEFINED_ID)), dimension(:), allocatable, public, protected :: &
12356 ! SHOULD NOT BE PART OF LATTICE END
12357 
12359  module procedure slipprojection_transverse
12360  end interface lattice_forestprojection_edge
12361 
12363  module procedure slipprojection_direction
12364  end interface lattice_forestprojection_screw
12365 
12366  public :: &
12367  lattice_init, &
12368  lattice_iso_id, &
12369  lattice_fcc_id, &
12370  lattice_bcc_id, &
12371  lattice_bct_id, &
12372  lattice_hex_id, &
12373  lattice_ort_id, &
12387  lattice_c66_twin, &
12396 
12397 contains
12398 
12399 !--------------------------------------------------------------------------------------------------
12401 !--------------------------------------------------------------------------------------------------
12402 subroutine lattice_init
12404  integer :: nphases, p,i
12405  character(len=pStringLen) :: structure = ''
12406 
12407  write(6,'(/,a)') ' <<<+- lattice init -+>>>'; flush(6)
12408 
12409  nphases = size(config_phase)
12410 
12411  allocate(lattice_structure(nphases),source = lattice_undefined_id)
12412  allocate(lattice_c66(6,6,nphases), source=0.0_preal)
12413 
12414  allocate(lattice_thermalconductivity(3,3,nphases), source=0.0_preal)
12415  allocate(lattice_damagediffusion(3,3,nphases), source=0.0_preal)
12416 
12417  allocate(lattice_damagemobility,&
12420  source=[(0.0_preal,i=1,nphases)])
12421 
12422  do p = 1, size(config_phase)
12423 
12424  lattice_c66(1,1,p) = config_phase(p)%getFloat('c11')
12425  lattice_c66(1,2,p) = config_phase(p)%getFloat('c12')
12426 
12427  lattice_c66(1,3,p) = config_phase(p)%getFloat('c13',defaultval=0.0_preal)
12428  lattice_c66(2,2,p) = config_phase(p)%getFloat('c22',defaultval=0.0_preal)
12429  lattice_c66(2,3,p) = config_phase(p)%getFloat('c23',defaultval=0.0_preal)
12430  lattice_c66(3,3,p) = config_phase(p)%getFloat('c33',defaultval=0.0_preal)
12431  lattice_c66(4,4,p) = config_phase(p)%getFloat('c44',defaultval=0.0_preal)
12432  lattice_c66(5,5,p) = config_phase(p)%getFloat('c55',defaultval=0.0_preal)
12433  lattice_c66(6,6,p) = config_phase(p)%getFloat('c66',defaultval=0.0_preal)
12434 
12435  structure = config_phase(p)%getString('lattice_structure')
12436  select case(trim(structure))
12437  case('iso')
12439  case('fcc')
12441  case('bcc')
12443  case('hex')
12445  case('bct')
12447  case('ort')
12449  case default
12450  call io_error(130,ext_msg='lattice_init: '//trim(structure))
12451  end select
12452 
12453  lattice_c66(1:6,1:6,p) = applylatticesymmetryc66(lattice_c66(1:6,1:6,p),structure)
12454 
12455  lattice_mu(p) = equivalent_mu(lattice_c66(1:6,1:6,p),'voigt')
12456  lattice_nu(p) = equivalent_nu(lattice_c66(1:6,1:6,p),'voigt')
12457 
12458  lattice_c66(1:6,1:6,p) = math_sym3333to66(math_voigt66to3333(lattice_c66(1:6,1:6,p))) ! Literature data is in Voigt notation
12459  do i = 1, 6
12460  if (abs(lattice_c66(i,i,p))<tol_math_check) &
12461  call io_error(135,el=i,ip=p,ext_msg='matrix diagonal "el"ement of phase "ip"')
12462  enddo
12463 
12464 
12465  ! SHOULD NOT BE PART OF LATTICE BEGIN
12466  lattice_thermalconductivity(1,1,p) = config_phase(p)%getFloat('thermal_conductivity11',defaultval=0.0_preal)
12467  lattice_thermalconductivity(2,2,p) = config_phase(p)%getFloat('thermal_conductivity22',defaultval=0.0_preal)
12468  lattice_thermalconductivity(3,3,p) = config_phase(p)%getFloat('thermal_conductivity33',defaultval=0.0_preal)
12470 
12471  lattice_specificheat(p) = config_phase(p)%getFloat('specific_heat',defaultval=0.0_preal)
12472  lattice_massdensity(p) = config_phase(p)%getFloat('mass_density', defaultval=0.0_preal)
12473 
12474  lattice_damagediffusion(1,1,p) = config_phase(p)%getFloat('damage_diffusion11',defaultval=0.0_preal)
12475  lattice_damagediffusion(2,2,p) = config_phase(p)%getFloat('damage_diffusion22',defaultval=0.0_preal)
12476  lattice_damagediffusion(3,3,p) = config_phase(p)%getFloat('damage_diffusion33',defaultval=0.0_preal)
12478 
12479  lattice_damagemobility(p) = config_phase(p)%getFloat('damage_mobility',defaultval=0.0_preal)
12480  ! SHOULD NOT BE PART OF LATTICE END
12481 
12482  call unittest
12483 
12484  enddo
12485 
12486 end subroutine lattice_init
12487 
12488 
12489 !--------------------------------------------------------------------------------------------------
12491 !--------------------------------------------------------------------------------------------------
12492 function lattice_characteristicshear_twin(Ntwin,structure,CoverA) result(characteristicShear)
12494  integer, dimension(:), intent(in) :: ntwin
12495  character(len=*), intent(in) :: structure
12496  real(preal), intent(in) :: covera
12497  real(preal), dimension(sum(Ntwin)) :: characteristicshear
12498 
12499  integer :: &
12500  a, & !< index of active system
12501  p, & !< index in potential system list
12502  f, & !< index of my family
12503  s
12504 
12505  integer, dimension(HEX_NTWIN), parameter :: &
12506  hex_sheartwin = reshape( [&
12507  1, & ! <-10.1>{10.2}
12508  1, &
12509  1, &
12510  1, &
12511  1, &
12512  1, &
12513  2, & ! <11.6>{-1-1.1}
12514  2, &
12515  2, &
12516  2, &
12517  2, &
12518  2, &
12519  3, & ! <10.-2>{10.1}
12520  3, &
12521  3, &
12522  3, &
12523  3, &
12524  3, &
12525  4, & ! <11.-3>{11.2}
12526  4, &
12527  4, &
12528  4, &
12529  4, &
12530  4 &
12531  ],[hex_ntwin]) ! indicator to formulas below
12532 
12533  if (len_trim(structure) /= 3) &
12534  call io_error(137,ext_msg='lattice_characteristicShear_Twin: '//trim(structure))
12535 
12536  a = 0
12537  myfamilies: do f = 1,size(ntwin,1)
12538  mysystems: do s = 1,ntwin(f)
12539  a = a + 1
12540  select case(structure)
12541  case('fcc','bcc')
12542  characteristicshear(a) = 0.5_preal*sqrt(2.0_preal)
12543  case('hex')
12544  if (covera < 1.0_preal .or. covera > 2.0_preal) &
12545  call io_error(131,ext_msg='lattice_characteristicShear_Twin')
12546  p = sum(hex_ntwinsystem(1:f-1))+s
12547  select case(hex_sheartwin(p)) ! from Christian & Mahajan 1995 p.29
12548  case (1) ! <-10.1>{10.2}
12549  characteristicshear(a) = (3.0_preal-covera**2.0_preal)/sqrt(3.0_preal)/covera
12550  case (2) ! <11.6>{-1-1.1}
12551  characteristicshear(a) = 1.0_preal/covera
12552  case (3) ! <10.-2>{10.1}
12553  characteristicshear(a) = (4.0_preal*covera**2.0_preal-9.0_preal)/sqrt(48.0_preal)/covera
12554  case (4) ! <11.-3>{11.2}
12555  characteristicshear(a) = 2.0_preal*(covera**2.0_preal-2.0_preal)/3.0_preal/covera
12556  end select
12557  case default
12558  call io_error(137,ext_msg='lattice_characteristicShear_Twin: '//trim(structure))
12559  end select
12560  enddo mysystems
12561  enddo myfamilies
12562 
12564 
12565 
12566 !--------------------------------------------------------------------------------------------------
12568 !--------------------------------------------------------------------------------------------------
12569 function lattice_c66_twin(Ntwin,C66,structure,CoverA)
12571  integer, dimension(:), intent(in) :: ntwin
12572  character(len=*), intent(in) :: structure
12573  real(preal), dimension(6,6), intent(in) :: c66
12574  real(preal), intent(in) :: covera
12575  real(preal), dimension(6,6,sum(Ntwin)) :: lattice_c66_twin
12576 
12577  real(preal), dimension(3,3,sum(Ntwin)):: coordinatesystem
12578  type(rotation) :: r
12579  integer :: i
12580 
12581  if (len_trim(structure) /= 3) &
12582  call io_error(137,ext_msg='lattice_C66_twin: '//trim(structure))
12583 
12584  select case(structure)
12585  case('fcc')
12586  coordinatesystem = buildcoordinatesystem(ntwin,fcc_nslipsystem,fcc_systemtwin,&
12587  trim(structure),0.0_preal)
12588  case('bcc')
12589  coordinatesystem = buildcoordinatesystem(ntwin,bcc_nslipsystem,bcc_systemtwin,&
12590  trim(structure),0.0_preal)
12591  case('hex')
12592  coordinatesystem = buildcoordinatesystem(ntwin,hex_nslipsystem,hex_systemtwin,&
12593  'hex',covera)
12594  case default
12595  call io_error(137,ext_msg='lattice_C66_twin: '//trim(structure))
12596  end select
12597 
12598  do i = 1, sum(ntwin)
12599  call r%fromAxisAngle([coordinatesystem(1:3,2,i),pi],p=1) ! ToDo: Why always 180 deg?
12600  lattice_c66_twin(1:6,1:6,i) = r%rotTensor4sym(c66)
12601  enddo
12602 
12603 end function lattice_c66_twin
12604 
12605 
12606 !--------------------------------------------------------------------------------------------------
12608 !--------------------------------------------------------------------------------------------------
12609 function lattice_c66_trans(Ntrans,C_parent66,structure_target, &
12610  cOverA_trans,a_bcc,a_fcc)
12612  integer, dimension(:), intent(in) :: ntrans
12613  character(len=*), intent(in) :: structure_target
12614  real(preal), dimension(6,6), intent(in) :: c_parent66
12615  real(preal), dimension(6,6,sum(Ntrans)) :: lattice_c66_trans
12616 
12617  real(preal), dimension(6,6) :: c_bar66, c_target_unrotated66
12618  real(preal), dimension(3,3,sum(Ntrans)) :: q,s
12619  type(rotation) :: r
12620  real(preal) :: a_bcc, a_fcc, covera_trans
12621  integer :: i
12622 
12623  if (len_trim(structure_target) /= 3) &
12624  call io_error(137,ext_msg='lattice_C66_trans (target): '//trim(structure_target))
12625 
12626  !--------------------------------------------------------------------------------------------------
12627  ! elasticity matrix of the target phase in cube orientation
12628  if (structure_target(1:3) == 'hex') then
12629  if (covera_trans < 1.0_preal .or. covera_trans > 2.0_preal) &
12630  call io_error(131,ext_msg='lattice_C66_trans: '//trim(structure_target))
12631  c_bar66(1,1) = (c_parent66(1,1) + c_parent66(1,2) + 2.0_preal*c_parent66(4,4))/2.0_preal
12632  c_bar66(1,2) = (c_parent66(1,1) + 5.0_preal*c_parent66(1,2) - 2.0_preal*c_parent66(4,4))/6.0_preal
12633  c_bar66(3,3) = (c_parent66(1,1) + 2.0_preal*c_parent66(1,2) + 4.0_preal*c_parent66(4,4))/3.0_preal
12634  c_bar66(1,3) = (c_parent66(1,1) + 2.0_preal*c_parent66(1,2) - 2.0_preal*c_parent66(4,4))/3.0_preal
12635  c_bar66(4,4) = (c_parent66(1,1) - c_parent66(1,2) + c_parent66(4,4))/3.0_preal
12636  c_bar66(1,4) = (c_parent66(1,1) - c_parent66(1,2) - 2.0_preal*c_parent66(4,4)) /(3.0_preal*sqrt(2.0_preal))
12637 
12638  c_target_unrotated66 = 0.0_preal
12639  c_target_unrotated66(1,1) = c_bar66(1,1) - c_bar66(1,4)**2.0_preal/c_bar66(4,4)
12640  c_target_unrotated66(1,2) = c_bar66(1,2) + c_bar66(1,4)**2.0_preal/c_bar66(4,4)
12641  c_target_unrotated66(1,3) = c_bar66(1,3)
12642  c_target_unrotated66(3,3) = c_bar66(3,3)
12643  c_target_unrotated66(4,4) = c_bar66(4,4) - c_bar66(1,4)**2.0_preal/(0.5_preal*(c_bar66(1,1) - c_bar66(1,2)))
12644  c_target_unrotated66 = applylatticesymmetryc66(c_target_unrotated66,'hex')
12645  elseif (structure_target(1:3) == 'bcc') then
12646  if (a_bcc <= 0.0_preal .or. a_fcc <= 0.0_preal) &
12647  call io_error(134,ext_msg='lattice_C66_trans: '//trim(structure_target))
12648  c_target_unrotated66 = c_parent66
12649  else
12650  call io_error(137,ext_msg='lattice_C66_trans : '//trim(structure_target))
12651  endif
12652 
12653  do i = 1, 6
12654  if (abs(c_target_unrotated66(i,i))<tol_math_check) &
12655  call io_error(135,el=i,ext_msg='matrix diagonal "el"ement in transformation')
12656  enddo
12657 
12658  call buildtransformationsystem(q,s,ntrans,covera_trans,a_fcc,a_bcc)
12659 
12660  do i = 1, sum(ntrans)
12661  call r%fromMatrix(q(1:3,1:3,i))
12662  lattice_c66_trans(1:6,1:6,i) = r%rotTensor4sym(c_target_unrotated66)
12663  enddo
12664 
12665  end function lattice_c66_trans
12666 
12667 
12668 !--------------------------------------------------------------------------------------------------
12670 ! Koester et al. 2012, Acta Materialia 60 (2012) 3894–3901, eq. (17)
12671 ! Gröger et al. 2008, Acta Materialia 56 (2008) 5412–5425, table 1
12672 !--------------------------------------------------------------------------------------------------
12673 function lattice_nonschmidmatrix(Nslip,nonSchmidCoefficients,sense) result(nonSchmidMatrix)
12675  integer, dimension(:), intent(in) :: nslip
12676  real(preal), dimension(:), intent(in) :: nonschmidcoefficients
12677  integer, intent(in) :: sense
12678  real(preal), dimension(1:3,1:3,sum(Nslip)) :: nonschmidmatrix
12679 
12680  real(preal), dimension(1:3,1:3,sum(Nslip)) :: coordinatesystem
12681  real(preal), dimension(3) :: direction, normal, np
12682  type(rotation) :: r
12683  integer :: i
12684 
12685  if (abs(sense) /= 1) call io_error(0,ext_msg='lattice_nonSchmidMatrix')
12686 
12687  coordinatesystem = buildcoordinatesystem(nslip,bcc_nslipsystem,bcc_systemslip,&
12688  'bcc',0.0_preal)
12689  coordinatesystem(1:3,1,1:sum(nslip)) = coordinatesystem(1:3,1,1:sum(nslip))*real(sense,preal) ! convert unidirectional coordinate system
12690  nonschmidmatrix = lattice_schmidmatrix_slip(nslip,'bcc',0.0_preal) ! Schmid contribution
12691 
12692  do i = 1,sum(nslip)
12693  direction = coordinatesystem(1:3,1,i)
12694  normal = coordinatesystem(1:3,2,i)
12695  call r%fromAxisAngle([direction,60.0_preal],degrees=.true.,p=1)
12696  np = r%rotate(normal)
12697 
12698  if (size(nonschmidcoefficients)>0) nonschmidmatrix(1:3,1:3,i) = nonschmidmatrix(1:3,1:3,i) &
12699  + nonschmidcoefficients(1) * math_outer(direction, np)
12700  if (size(nonschmidcoefficients)>1) nonschmidmatrix(1:3,1:3,i) = nonschmidmatrix(1:3,1:3,i) &
12701  + nonschmidcoefficients(2) * math_outer(math_cross(normal, direction), normal)
12702  if (size(nonschmidcoefficients)>2) nonschmidmatrix(1:3,1:3,i) = nonschmidmatrix(1:3,1:3,i) &
12703  + nonschmidcoefficients(3) * math_outer(math_cross(np, direction), np)
12704  if (size(nonschmidcoefficients)>3) nonschmidmatrix(1:3,1:3,i) = nonschmidmatrix(1:3,1:3,i) &
12705  + nonschmidcoefficients(4) * math_outer(normal, normal)
12706  if (size(nonschmidcoefficients)>4) nonschmidmatrix(1:3,1:3,i) = nonschmidmatrix(1:3,1:3,i) &
12707  + nonschmidcoefficients(5) * math_outer(math_cross(normal, direction), &
12708  math_cross(normal, direction))
12709  if (size(nonschmidcoefficients)>5) nonschmidmatrix(1:3,1:3,i) = nonschmidmatrix(1:3,1:3,i) &
12710  + nonschmidcoefficients(6) * math_outer(direction, direction)
12711  enddo
12712 
12713 end function lattice_nonschmidmatrix
12714 
12715 
12716 !--------------------------------------------------------------------------------------------------
12719 !--------------------------------------------------------------------------------------------------
12720 function lattice_interaction_slipbyslip(Nslip,interactionValues,structure) result(interactionMatrix)
12722  integer, dimension(:), intent(in) :: nslip
12723  real(preal), dimension(:), intent(in) :: interactionvalues
12724  character(len=*), intent(in) :: structure
12725  real(preal), dimension(sum(Nslip),sum(Nslip)) :: interactionmatrix
12726 
12727  integer, dimension(:), allocatable :: nslipmax
12728  integer, dimension(:,:), allocatable :: interactiontypes
12729 
12730  integer, dimension(FCC_NSLIP,FCC_NSLIP), parameter :: &
12731  fcc_interactionslipslip = reshape( [&
12732  1, 2, 2, 4, 6, 5, 3, 5, 5, 4, 5, 6, 9,10, 9,10,11,12, & ! -----> acting
12733  2, 1, 2, 6, 4, 5, 5, 4, 6, 5, 3, 5, 9,10,11,12, 9,10, & ! |
12734  2, 2, 1, 5, 5, 3, 5, 6, 4, 6, 5, 4, 11,12, 9,10, 9,10, & ! |
12735  4, 6, 5, 1, 2, 2, 4, 5, 6, 3, 5, 5, 9,10,10, 9,12,11, & ! v
12736  6, 4, 5, 2, 1, 2, 5, 3, 5, 5, 4, 6, 9,10,12,11,10, 9, & ! reacting
12737  5, 5, 3, 2, 2, 1, 6, 5, 4, 5, 6, 4, 11,12,10, 9,10, 9, &
12738  3, 5, 5, 4, 5, 6, 1, 2, 2, 4, 6, 5, 10, 9,10, 9,11,12, &
12739  5, 4, 6, 5, 3, 5, 2, 1, 2, 6, 4, 5, 10, 9,12,11, 9,10, &
12740  5, 6, 4, 6, 5, 4, 2, 2, 1, 5, 5, 3, 12,11,10, 9, 9,10, &
12741  4, 5, 6, 3, 5, 5, 4, 6, 5, 1, 2, 2, 10, 9, 9,10,12,11, &
12742  5, 3, 5, 5, 4, 6, 6, 4, 5, 2, 1, 2, 10, 9,11,12,10, 9, &
12743  6, 5, 4, 5, 6, 4, 5, 5, 3, 2, 2, 1, 12,11, 9,10,10, 9, &
12744 
12745  9, 9,11, 9, 9,11,10,10,12,10,10,12, 1, 7, 8, 8, 8, 8, &
12746  10,10,12,10,10,12, 9, 9,11, 9, 9,11, 7, 1, 8, 8, 8, 8, &
12747  9,11, 9,10,12,10,10,12,10, 9,11, 9, 8, 8, 1, 7, 8, 8, &
12748  10,12,10, 9,11, 9, 9,11, 9,10,12,10, 8, 8, 7, 1, 8, 8, &
12749  11, 9, 9,12,10,10,11, 9, 9,12,10,10, 8, 8, 8, 8, 1, 7, &
12750  12,10,10,11, 9, 9,12,10,10,11, 9, 9, 8, 8, 8, 8, 7, 1 &
12751  ],shape(fcc_interactionslipslip))
12764 
12765  integer, dimension(BCC_NSLIP,BCC_NSLIP), parameter :: &
12766  bcc_interactionslipslip = reshape( [&
12767  1,2,6,6,5,4,4,3,4,3,5,4, 6,6,4,3,3,4,6,6,4,3,6,6, & ! -----> acting
12768  2,1,6,6,4,3,5,4,5,4,4,3, 6,6,3,4,4,3,6,6,3,4,6,6, & ! |
12769  6,6,1,2,4,5,3,4,4,5,3,4, 4,3,6,6,6,6,3,4,6,6,4,3, & ! |
12770  6,6,2,1,3,4,4,5,3,4,4,5, 3,4,6,6,6,6,4,3,6,6,3,4, & ! v
12771  5,4,4,3,1,2,6,6,3,4,5,4, 3,6,4,6,6,4,6,3,4,6,3,6, & ! reacting
12772  4,3,5,4,2,1,6,6,4,5,4,3, 4,6,3,6,6,3,6,4,3,6,4,6, &
12773  4,5,3,4,6,6,1,2,5,4,3,4, 6,3,6,4,4,6,3,6,6,4,6,3, &
12774  3,4,4,5,6,6,2,1,4,3,4,5, 6,4,6,3,3,6,4,6,6,3,6,4, &
12775  4,5,4,3,3,4,5,4,1,2,6,6, 3,6,6,4,4,6,6,3,6,4,3,6, &
12776  3,4,5,4,4,5,4,3,2,1,6,6, 4,6,6,3,3,6,6,4,6,3,4,6, &
12777  5,4,3,4,5,4,3,4,6,6,1,2, 6,3,4,6,6,4,3,6,4,6,6,3, &
12778  4,3,4,5,4,3,4,5,6,6,2,1, 6,4,3,6,6,3,4,6,3,6,6,4, &
12779  !
12780  6,6,4,3,3,4,6,6,3,4,6,6, 1,5,6,6,5,6,6,3,5,6,3,6, &
12781  6,6,3,4,6,6,3,4,6,6,3,4, 5,1,6,6,6,5,3,6,6,5,6,3, &
12782  4,3,6,6,4,3,6,6,6,6,4,3, 6,6,1,5,6,3,5,6,3,6,5,6, &
12783  3,4,6,6,6,6,4,3,4,3,6,6, 6,6,5,1,3,6,6,5,6,3,6,5, &
12784  3,4,6,6,6,6,4,3,4,3,6,6, 5,6,6,3,1,6,5,6,5,3,6,6, &
12785  4,3,6,6,4,3,6,6,6,6,4,3, 6,5,3,6,6,1,6,5,3,5,6,6, &
12786  6,6,3,4,6,6,3,4,6,6,3,4, 6,3,5,6,5,6,1,6,6,6,5,3, &
12787  6,6,4,3,3,4,6,6,3,4,6,6, 3,6,6,5,6,5,6,1,6,6,3,5, &
12788  4,3,6,6,4,3,6,6,6,6,4,3, 5,6,3,6,5,3,6,6,1,6,6,5, &
12789  3,4,6,6,6,6,4,3,4,3,6,6, 6,5,6,3,3,5,6,6,6,1,5,6, &
12790  6,6,4,3,3,4,6,6,3,4,6,6, 3,6,5,6,6,6,5,3,6,5,1,6, &
12791  6,6,3,4,6,6,3,4,6,6,3,4, 6,3,6,5,6,6,3,5,5,6,6,1 &
12792  ],shape(bcc_interactionslipslip))
12799 
12800  integer, dimension(HEX_NSLIP,HEX_NSLIP), parameter :: &
12801  hex_interactionslipslip = reshape( [&
12802  1, 2, 2, 3, 3, 3, 7, 7, 7, 13,13,13,13,13,13, 21,21,21,21,21,21,21,21,21,21,21,21, 31,31,31,31,31,31, & ! -----> acting
12803  2, 1, 2, 3, 3, 3, 7, 7, 7, 13,13,13,13,13,13, 21,21,21,21,21,21,21,21,21,21,21,21, 31,31,31,31,31,31, & ! |
12804  2, 2, 1, 3, 3, 3, 7, 7, 7, 13,13,13,13,13,13, 21,21,21,21,21,21,21,21,21,21,21,21, 31,31,31,31,31,31, & ! |
12805  ! ! v
12806  6, 6, 6, 4, 5, 5, 8, 8, 8, 14,14,14,14,14,14, 22,22,22,22,22,22,22,22,22,22,22,22, 32,32,32,32,32,32, & ! reacting
12807  6, 6, 6, 5, 4, 5, 8, 8, 8, 14,14,14,14,14,14, 22,22,22,22,22,22,22,22,22,22,22,22, 32,32,32,32,32,32, &
12808  6, 6, 6, 5, 5, 4, 8, 8, 8, 14,14,14,14,14,14, 22,22,22,22,22,22,22,22,22,22,22,22, 32,32,32,32,32,32, &
12809  !
12810  12,12,12, 11,11,11, 9,10,10, 15,15,15,15,15,15, 23,23,23,23,23,23,23,23,23,23,23,23, 33,33,33,33,33,33, &
12811  12,12,12, 11,11,11, 10, 9,10, 15,15,15,15,15,15, 23,23,23,23,23,23,23,23,23,23,23,23, 33,33,33,33,33,33, &
12812  12,12,12, 11,11,11, 10,10, 9, 15,15,15,15,15,15, 23,23,23,23,23,23,23,23,23,23,23,23, 33,33,33,33,33,33, &
12813  !
12814  20,20,20, 19,19,19, 18,18,18, 16,17,17,17,17,17, 24,24,24,24,24,24,24,24,24,24,24,24, 34,34,34,34,34,34, &
12815  20,20,20, 19,19,19, 18,18,18, 17,16,17,17,17,17, 24,24,24,24,24,24,24,24,24,24,24,24, 34,34,34,34,34,34, &
12816  20,20,20, 19,19,19, 18,18,18, 17,17,16,17,17,17, 24,24,24,24,24,24,24,24,24,24,24,24, 34,34,34,34,34,34, &
12817  20,20,20, 19,19,19, 18,18,18, 17,17,17,16,17,17, 24,24,24,24,24,24,24,24,24,24,24,24, 34,34,34,34,34,34, &
12818  20,20,20, 19,19,19, 18,18,18, 17,17,17,17,16,17, 24,24,24,24,24,24,24,24,24,24,24,24, 34,34,34,34,34,34, &
12819  20,20,20, 19,19,19, 18,18,18, 17,17,17,17,17,16, 24,24,24,24,24,24,24,24,24,24,24,24, 34,34,34,34,34,34, &
12820  !
12821  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 25,26,26,26,26,26,26,26,26,26,26,26, 35,35,35,35,35,35, &
12822  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,25,26,26,26,26,26,26,26,26,26,26, 35,35,35,35,35,35, &
12823  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,26,25,26,26,26,26,26,26,26,26,26, 35,35,35,35,35,35, &
12824  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,26,26,25,26,26,26,26,26,26,26,26, 35,35,35,35,35,35, &
12825  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,26,26,26,25,26,26,26,26,26,26,26, 35,35,35,35,35,35, &
12826  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,26,26,26,26,25,26,26,26,26,26,26, 35,35,35,35,35,35, &
12827  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,26,26,26,26,26,25,26,26,26,26,26, 35,35,35,35,35,35, &
12828  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,26,26,26,26,26,26,25,26,26,26,26, 35,35,35,35,35,35, &
12829  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,26,26,26,26,26,26,26,25,26,26,26, 35,35,35,35,35,35, &
12830  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,26,26,26,26,26,26,26,26,25,26,26, 35,35,35,35,35,35, &
12831  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,26,26,26,26,26,26,26,26,26,25,26, 35,35,35,35,35,35, &
12832  30,30,30, 29,29,29, 28,28,28, 27,27,27,27,27,27, 26,26,26,26,26,26,26,26,26,26,26,25, 35,35,35,35,35,35, &
12833  !
12834  42,42,42, 41,41,41, 40,40,40, 39,39,39,39,39,39, 38,38,38,38,38,38,38,38,38,38,38,38, 36,37,37,37,37,37, &
12835  42,42,42, 41,41,41, 40,40,40, 39,39,39,39,39,39, 38,38,38,38,38,38,38,38,38,38,38,38, 37,36,37,37,37,37, &
12836  42,42,42, 41,41,41, 40,40,40, 39,39,39,39,39,39, 38,38,38,38,38,38,38,38,38,38,38,38, 37,37,36,37,37,37, &
12837  42,42,42, 41,41,41, 40,40,40, 39,39,39,39,39,39, 38,38,38,38,38,38,38,38,38,38,38,38, 37,37,37,36,37,37, &
12838  42,42,42, 41,41,41, 40,40,40, 39,39,39,39,39,39, 38,38,38,38,38,38,38,38,38,38,38,38, 37,37,37,37,36,37, &
12839  42,42,42, 41,41,41, 40,40,40, 39,39,39,39,39,39, 38,38,38,38,38,38,38,38,38,38,38,38, 37,37,37,37,37,36 &
12840  ],shape(hex_interactionslipslip))
12841 
12842  integer, dimension(BCT_NSLIP,BCT_NSLIP), parameter :: &
12843  bct_interactionslipslip = reshape( [&
12844  1, 2, 3, 3, 7, 7, 13, 13, 13, 13, 21, 21, 31, 31, 31, 31, 43, 43, 57, 57, 73, 73, 73, 73, 91, 91, 91, 91, 91, 91, 91, 91, 111, 111, 111, 111, 133,133,133,133,133,133,133,133, 157,157,157,157,157,157,157,157, & ! -----> acting
12845  2, 1, 3, 3, 7, 7, 13, 13, 13, 13, 21, 21, 31, 31, 31, 31, 43, 43, 57, 57, 73, 73, 73, 73, 91, 91, 91, 91, 91, 91, 91, 91, 111, 111, 111, 111, 133,133,133,133,133,133,133,133, 157,157,157,157,157,157,157,157, & ! |
12846  ! |
12847  6, 6, 4, 5, 8, 8, 14, 14, 14, 14, 22, 22, 32, 32, 32, 32, 44, 44, 58, 58, 74, 74, 74, 74, 92, 92, 92, 92, 92, 92, 92, 92, 112, 112, 112, 112, 134,134,134,134,134,134,134,134, 158,158,158,158,158,158,158,158, & ! v
12848  6, 6, 5, 4, 8, 8, 14, 14, 14, 14, 22, 22, 32, 32, 32, 32, 44, 44, 58, 58, 74, 74, 74, 74, 92, 92, 92, 92, 92, 92, 92, 92, 112, 112, 112, 112, 134,134,134,134,134,134,134,134, 158,158,158,158,158,158,158,158, & ! reacting
12849  !
12850  12, 12, 11, 11, 9, 10, 15, 15, 15, 15, 23, 23, 33, 33, 33, 33, 45, 45, 59, 59, 75, 75, 75, 75, 93, 93, 93, 93, 93, 93, 93, 93, 113, 113, 113, 113, 135,135,135,135,135,135,135,135, 159,159,159,159,159,159,159,159, &
12851  12, 12, 11, 11, 10, 9, 15, 15, 15, 15, 23, 23, 33, 33, 33, 33, 45, 45, 59, 59, 75, 75, 75, 75, 93, 93, 93, 93, 93, 93, 93, 93, 113, 113, 113, 113, 135,135,135,135,135,135,135,135, 159,159,159,159,159,159,159,159, &
12852  !
12853  20, 20, 19, 19, 18, 18, 16, 17, 17, 17, 24, 24, 34, 34, 34, 34, 46, 46, 60, 60, 76, 76, 76, 76, 94, 94, 94, 94, 94, 94, 94, 94, 114, 114, 114, 114, 136,136,136,136,136,136,136,136, 160,160,160,160,160,160,160,160, &
12854  20, 20, 19, 19, 18, 18, 17, 16, 17, 17, 24, 24, 34, 34, 34, 34, 46, 46, 60, 60, 76, 76, 76, 76, 94, 94, 94, 94, 94, 94, 94, 94, 114, 114, 114, 114, 136,136,136,136,136,136,136,136, 160,160,160,160,160,160,160,160, &
12855  20, 20, 19, 19, 18, 18, 17, 17, 16, 17, 24, 24, 34, 34, 34, 34, 46, 46, 60, 60, 76, 76, 76, 76, 94, 94, 94, 94, 94, 94, 94, 94, 114, 114, 114, 114, 136,136,136,136,136,136,136,136, 160,160,160,160,160,160,160,160, &
12856  20, 20, 19, 19, 18, 18, 17, 17, 17, 16, 24, 24, 34, 34, 34, 34, 46, 46, 60, 60, 76, 76, 76, 76, 94, 94, 94, 94, 94, 94, 94, 94, 114, 114, 114, 114, 136,136,136,136,136,136,136,136, 160,160,160,160,160,160,160,160, &
12857  !
12858  30, 30, 29, 29, 28, 28, 27, 27, 27, 27, 25, 26, 35, 35, 35, 35, 47, 47, 61, 61, 77, 77, 77, 77, 95, 95, 95, 95, 95, 95, 95, 95, 115, 115, 115, 115, 137,137,137,137,137,137,137,137, 161,161,161,161,161,161,161,161, &
12859  30, 30, 29, 29, 28, 28, 27, 27, 27, 27, 26, 25, 35, 35, 35, 35, 47, 47, 61, 61, 77, 77, 77, 77, 95, 95, 95, 95, 95, 95, 95, 95, 115, 115, 115, 115, 137,137,137,137,137,137,137,137, 161,161,161,161,161,161,161,161, &
12860  !
12861  42, 42, 41, 41, 40, 40, 39, 39, 39, 39, 38, 38, 36, 37, 37, 37, 48, 48, 62, 62, 78, 78, 78, 78, 96, 96, 96, 96, 96, 96, 96, 96, 116, 116, 116, 116, 138,138,138,138,138,138,138,138, 162,162,162,162,162,162,162,162, &
12862  42, 42, 41, 41, 40, 40, 39, 39, 39, 39, 38, 38, 37, 36, 37, 37, 48, 48, 62, 62, 78, 78, 78, 78, 96, 96, 96, 96, 96, 96, 96, 96, 116, 116, 116, 116, 138,138,138,138,138,138,138,138, 162,162,162,162,162,162,162,162, &
12863  42, 42, 41, 41, 40, 40, 39, 39, 39, 39, 38, 38, 37, 37, 36, 37, 48, 48, 62, 62, 78, 78, 78, 78, 96, 96, 96, 96, 96, 96, 96, 96, 116, 116, 116, 116, 138,138,138,138,138,138,138,138, 162,162,162,162,162,162,162,162, &
12864  42, 42, 41, 41, 40, 40, 39, 39, 39, 39, 38, 38, 37, 37, 37, 36, 48, 48, 62, 62, 78, 78, 78, 78, 96, 96, 96, 96, 96, 96, 96, 96, 116, 116, 116, 116, 138,138,138,138,138,138,138,138, 162,162,162,162,162,162,162,162, &
12865  !
12866  56, 56, 55, 55, 54, 54, 53, 53, 53, 53, 52, 52, 51, 51, 51, 51, 49, 50, 63, 63, 79, 79, 79, 79, 97, 97, 97, 97, 97, 97, 97, 97, 117, 117, 117, 117, 139,139,139,139,139,139,139,139, 163,163,163,163,163,163,163,163, &
12867  56, 56, 55, 55, 54, 54, 53, 53, 53, 53, 52, 52, 51, 51, 51, 51, 50, 49, 63, 63, 79, 79, 79, 79, 97, 97, 97, 97, 97, 97, 97, 97, 117, 117, 117, 117, 139,139,139,139,139,139,139,139, 163,163,163,163,163,163,163,163, &
12868  !
12869  72, 72, 71, 71, 70, 70, 69, 69, 69, 69, 68, 68, 67, 67, 67, 67, 66, 66, 64, 65, 80, 80, 80, 80, 98, 98, 98, 98, 98, 98, 98, 98, 118, 118, 118, 118, 140,140,140,140,140,140,140,140, 164,164,164,164,164,164,164,164, &
12870  72, 72, 71, 71, 70, 70, 69, 69, 69, 69, 68, 68, 67, 67, 67, 67, 66, 66, 65, 64, 80, 80, 80, 80, 98, 98, 98, 98, 98, 98, 98, 98, 118, 118, 118, 118, 140,140,140,140,140,140,140,140, 164,164,164,164,164,164,164,164, &
12871  !
12872  90, 90, 89, 89, 88, 88, 87, 87, 87, 87, 86, 86, 85, 85, 85, 85, 84, 84, 83, 83, 81, 82, 82, 82, 99, 99, 99, 99, 99, 99, 99, 99, 119, 119, 119, 119, 141,141,141,141,141,141,141,141, 165,165,165,165,165,165,165,165, &
12873  90, 90, 89, 89, 88, 88, 87, 87, 87, 87, 86, 86, 85, 85, 85, 85, 84, 84, 83, 83, 82, 81, 82, 82, 99, 99, 99, 99, 99, 99, 99, 99, 119, 119, 119, 119, 141,141,141,141,141,141,141,141, 165,165,165,165,165,165,165,165, &
12874  90, 90, 89, 89, 88, 88, 87, 87, 87, 87, 86, 86, 85, 85, 85, 85, 84, 84, 83, 83, 82, 82, 81, 82, 99, 99, 99, 99, 99, 99, 99, 99, 119, 119, 119, 119, 141,141,141,141,141,141,141,141, 165,165,165,165,165,165,165,165, &
12875  90, 90, 89, 89, 88, 88, 87, 87, 87, 87, 86, 86, 85, 85, 85, 85, 84, 84, 83, 83, 82, 82, 82, 81, 99, 99, 99, 99, 99, 99, 99, 99, 119, 119, 119, 119, 141,141,141,141,141,141,141,141, 165,165,165,165,165,165,165,165, &
12876  !
12877  110,110, 109,109, 108,108, 107,107,107,107, 106,106, 105,105,105,105, 104,104, 103,103, 102,102,102,102, 100,101,101,101,101,101,101,101, 120, 120, 120, 120, 142,142,142,142,142,142,142,142, 166,166,166,166,166,166,166,166, &
12878  110,110, 109,109, 108,108, 107,107,107,107, 106,106, 105,105,105,105, 104,104, 103,103, 102,102,102,102, 101,100,101,101,101,101,101,101, 120, 120, 120, 120, 142,142,142,142,142,142,142,142, 166,166,166,166,166,166,166,166, &
12879  110,110, 109,109, 108,108, 107,107,107,107, 106,106, 105,105,105,105, 104,104, 103,103, 102,102,102,102, 101,101,100,101,101,101,101,101, 120, 120, 120, 120, 142,142,142,142,142,142,142,142, 166,166,166,166,166,166,166,166, &
12880  110,110, 109,109, 108,108, 107,107,107,107, 106,106, 105,105,105,105, 104,104, 103,103, 102,102,102,102, 101,101,101,100,101,101,101,101, 120, 120, 120, 120, 142,142,142,142,142,142,142,142, 166,166,166,166,166,166,166,166, &
12881  110,110, 109,109, 108,108, 107,107,107,107, 106,106, 105,105,105,105, 104,104, 103,103, 102,102,102,102, 101,101,101,101,100,101,101,101, 120, 120, 120, 120, 142,142,142,142,142,142,142,142, 166,166,166,166,166,166,166,166, &
12882  110,110, 109,109, 108,108, 107,107,107,107, 106,106, 105,105,105,105, 104,104, 103,103, 102,102,102,102, 101,101,101,101,101,100,101,101, 120, 120, 120, 120, 142,142,142,142,142,142,142,142, 166,166,166,166,166,166,166,166, &
12883  110,110, 109,109, 108,108, 107,107,107,107, 106,106, 105,105,105,105, 104,104, 103,103, 102,102,102,102, 101,101,101,101,101,101,100,101, 120, 120, 120, 120, 142,142,142,142,142,142,142,142, 166,166,166,166,166,166,166,166, &
12884  110,110, 109,109, 108,108, 107,107,107,107, 106,106, 105,105,105,105, 104,104, 103,103, 102,102,102,102, 101,101,101,101,101,101,101,100, 120, 120, 120, 120, 142,142,142,142,142,142,142,142, 166,166,166,166,166,166,166,166, &
12885  !
12886  132,132, 131,131, 130,130, 129,129,129,129, 128,128, 127,127,127,127, 126,126, 125,125, 124,124,124,124, 123,123,123,123,123,123,123,123, 121, 122, 122, 122, 143,143,143,143,143,143,143,143, 167,167,167,167,167,167,167,167, &
12887  132,132, 131,131, 130,130, 129,129,129,129, 128,128, 127,127,127,127, 126,126, 125,125, 124,124,124,124, 123,123,123,123,123,123,123,123, 121, 121, 122, 122, 143,143,143,143,143,143,143,143, 167,167,167,167,167,167,167,167, &
12888  132,132, 131,131, 130,130, 129,129,129,129, 128,128, 127,127,127,127, 126,126, 125,125, 124,124,124,124, 123,123,123,123,123,123,123,123, 121, 122, 121, 122, 143,143,143,143,143,143,143,143, 167,167,167,167,167,167,167,167, &
12889  132,132, 131,131, 130,130, 129,129,129,129, 128,128, 127,127,127,127, 126,126, 125,125, 124,124,124,124, 123,123,123,123,123,123,123,123, 121, 122, 122, 121, 143,143,143,143,143,143,143,143, 167,167,167,167,167,167,167,167, &
12890  !
12891  156,156, 155,155, 154,154, 153,153,153,153, 152,152, 151,151,151,151, 150,150, 149,149, 148,148,148,148, 147,147,147,147,147,147,147,147, 146, 146, 146, 146, 144,145,145,145,145,145,145,145, 168,168,168,168,168,168,168,168, &
12892  156,156, 155,155, 154,154, 153,153,153,153, 152,152, 151,151,151,151, 150,150, 149,149, 148,148,148,148, 147,147,147,147,147,147,147,147, 146, 146, 146, 146, 145,144,145,145,145,145,145,145, 168,168,168,168,168,168,168,168, &
12893  156,156, 155,155, 154,154, 153,153,153,153, 152,152, 151,151,151,151, 150,150, 149,149, 148,148,148,148, 147,147,147,147,147,147,147,147, 146, 146, 146, 146, 145,145,144,145,145,145,145,145, 168,168,168,168,168,168,168,168, &
12894  156,156, 155,155, 154,154, 153,153,153,153, 152,152, 151,151,151,151, 150,150, 149,149, 148,148,148,148, 147,147,147,147,147,147,147,147, 146, 146, 146, 146, 145,145,145,144,145,145,145,145, 168,168,168,168,168,168,168,168, &
12895  156,156, 155,155, 154,154, 153,153,153,153, 152,152, 151,151,151,151, 150,150, 149,149, 148,148,148,148, 147,147,147,147,147,147,147,147, 146, 146, 146, 146, 145,145,145,145,144,145,145,145, 168,168,168,168,168,168,168,168, &
12896  156,156, 155,155, 154,154, 153,153,153,153, 152,152, 151,151,151,151, 150,150, 149,149, 148,148,148,148, 147,147,147,147,147,147,147,147, 146, 146, 146, 146, 145,145,145,145,145,144,145,145, 168,168,168,168,168,168,168,168, &
12897  156,156, 155,155, 154,154, 153,153,153,153, 152,152, 151,151,151,151, 150,150, 149,149, 148,148,148,148, 147,147,147,147,147,147,147,147, 146, 146, 146, 146, 145,145,145,145,145,145,144,145, 168,168,168,168,168,168,168,168, &
12898  156,156, 155,155, 154,154, 153,153,153,153, 152,152, 151,151,151,151, 150,150, 149,149, 148,148,148,148, 147,147,147,147,147,147,147,147, 146, 146, 146, 146, 145,145,145,145,145,145,145,144, 168,168,168,168,168,168,168,168, &
12899  !
12900  182,182, 181,181, 180,180, 179,179,179,179, 178,178, 177,177,177,177, 176,176, 175,175, 174,174,174,174, 173,173,173,173,173,173,173,173, 172, 172, 172, 172, 171,171,171,171,171,171,171,171, 169,170,170,170,170,170,170,170, &
12901  182,182, 181,181, 180,180, 179,179,179,179, 178,178, 177,177,177,177, 176,176, 175,175, 174,174,174,174, 173,173,173,173,173,173,173,173, 172, 172, 172, 172, 171,171,171,171,171,171,171,171, 170,169,170,170,170,170,170,170, &
12902  182,182, 181,181, 180,180, 179,179,179,179, 178,178, 177,177,177,177, 176,176, 175,175, 174,174,174,174, 173,173,173,173,173,173,173,173, 172, 172, 172, 172, 171,171,171,171,171,171,171,171, 170,170,169,170,170,170,170,170, &
12903  182,182, 181,181, 180,180, 179,179,179,179, 178,178, 177,177,177,177, 176,176, 175,175, 174,174,174,174, 173,173,173,173,173,173,173,173, 172, 172, 172, 172, 171,171,171,171,171,171,171,171, 170,170,170,169,170,170,170,170, &
12904  182,182, 181,181, 180,180, 179,179,179,179, 178,178, 177,177,177,177, 176,176, 175,175, 174,174,174,174, 173,173,173,173,173,173,173,173, 172, 172, 172, 172, 171,171,171,171,171,171,171,171, 170,170,170,170,169,170,170,170, &
12905  182,182, 181,181, 180,180, 179,179,179,179, 178,178, 177,177,177,177, 176,176, 175,175, 174,174,174,174, 173,173,173,173,173,173,173,173, 172, 172, 172, 172, 171,171,171,171,171,171,171,171, 169,170,170,170,170,169,170,170, &
12906  182,182, 181,181, 180,180, 179,179,179,179, 178,178, 177,177,177,177, 176,176, 175,175, 174,174,174,174, 173,173,173,173,173,173,173,173, 172, 172, 172, 172, 171,171,171,171,171,171,171,171, 169,170,170,170,170,170,169,170, &
12907  182,182, 181,181, 180,180, 179,179,179,179, 178,178, 177,177,177,177, 176,176, 175,175, 174,174,174,174, 173,173,173,173,173,173,173,173, 172, 172, 172, 172, 171,171,171,171,171,171,171,171, 169,170,170,170,170,170,170,169 &
12908  ],shape(bct_interactionslipslip))
12909 
12910 
12911  if (len_trim(structure) /= 3) &
12912  call io_error(137,ext_msg='lattice_interaction_SlipBySlip: '//trim(structure))
12913 
12914  select case(structure)
12915  case('fcc')
12916  interactiontypes = fcc_interactionslipslip
12917  nslipmax = fcc_nslipsystem
12918  case('bcc')
12919  interactiontypes = bcc_interactionslipslip
12920  nslipmax = bcc_nslipsystem
12921  case('hex')
12922  interactiontypes = hex_interactionslipslip
12923  nslipmax = hex_nslipsystem
12924  case('bct')
12925  interactiontypes = bct_interactionslipslip
12926  nslipmax = bct_nslipsystem
12927  case default
12928  call io_error(137,ext_msg='lattice_interaction_SlipBySlip: '//trim(structure))
12929  end select
12930 
12931  interactionmatrix = buildinteraction(nslip,nslip,nslipmax,nslipmax,interactionvalues,interactiontypes)
12932 
12933 end function lattice_interaction_slipbyslip
12934 
12935 
12936 !--------------------------------------------------------------------------------------------------
12939 !--------------------------------------------------------------------------------------------------
12940 function lattice_interaction_twinbytwin(Ntwin,interactionValues,structure) result(interactionMatrix)
12942  integer, dimension(:), intent(in) :: ntwin
12943  real(preal), dimension(:), intent(in) :: interactionvalues
12944  character(len=*), intent(in) :: structure
12945  real(preal), dimension(sum(Ntwin),sum(Ntwin)) :: interactionmatrix
12946 
12947  integer, dimension(:), allocatable :: ntwinmax
12948  integer, dimension(:,:), allocatable :: interactiontypes
12949 
12950  integer, dimension(FCC_NTWIN,FCC_NTWIN), parameter :: &
12951  fcc_interactiontwintwin = reshape( [&
12952  1,1,1,2,2,2,2,2,2,2,2,2, & ! -----> acting
12953  1,1,1,2,2,2,2,2,2,2,2,2, & ! |
12954  1,1,1,2,2,2,2,2,2,2,2,2, & ! |
12955  2,2,2,1,1,1,2,2,2,2,2,2, & ! v
12956  2,2,2,1,1,1,2,2,2,2,2,2, & ! reacting
12957  2,2,2,1,1,1,2,2,2,2,2,2, &
12958  2,2,2,2,2,2,1,1,1,2,2,2, &
12959  2,2,2,2,2,2,1,1,1,2,2,2, &
12960  2,2,2,2,2,2,1,1,1,2,2,2, &
12961  2,2,2,2,2,2,2,2,2,1,1,1, &
12962  2,2,2,2,2,2,2,2,2,1,1,1, &
12963  2,2,2,2,2,2,2,2,2,1,1,1 &
12964  ],shape(fcc_interactiontwintwin))
12965 
12966  integer, dimension(BCC_NTWIN,BCC_NTWIN), parameter :: &
12967  bcc_interactiontwintwin = reshape( [&
12968  1,3,3,3,3,3,3,2,3,3,2,3, & ! -----> acting
12969  3,1,3,3,3,3,2,3,3,3,3,2, & ! |
12970  3,3,1,3,3,2,3,3,2,3,3,3, & ! |
12971  3,3,3,1,2,3,3,3,3,2,3,3, & ! v
12972  3,3,3,2,1,3,3,3,3,2,3,3, & ! reacting
12973  3,3,2,3,3,1,3,3,2,3,3,3, &
12974  3,2,3,3,3,3,1,3,3,3,3,2, &
12975  2,3,3,3,3,3,3,1,3,3,2,3, &
12976  3,3,2,3,3,2,3,3,1,3,3,3, &
12977  3,3,3,2,2,3,3,3,3,1,3,3, &
12978  2,3,3,3,3,3,3,2,3,3,1,3, &
12979  3,2,3,3,3,3,2,3,3,3,3,1 &
12980  ],shape(bcc_interactiontwintwin))
12984  integer, dimension(HEX_NTWIN,HEX_NTWIN), parameter :: &
12985  hex_interactiontwintwin = reshape( [&
12986  1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 13,13,13,13,13,13, & ! -----> acting
12987  2, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 13,13,13,13,13,13, & ! |
12988  2, 2, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 13,13,13,13,13,13, & ! |
12989  2, 2, 2, 1, 2, 2, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 13,13,13,13,13,13, & ! v
12990  2, 2, 2, 2, 1, 2, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 13,13,13,13,13,13, & ! reacting
12991  2, 2, 2, 2, 2, 1, 3, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 13,13,13,13,13,13, &
12992  !
12993  6, 6, 6, 6, 6, 6, 4, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 14,14,14,14,14,14, &
12994  6, 6, 6, 6, 6, 6, 5, 4, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 14,14,14,14,14,14, &
12995  6, 6, 6, 6, 6, 6, 5, 5, 4, 5, 5, 5, 8, 8, 8, 8, 8, 8, 14,14,14,14,14,14, &
12996  6, 6, 6, 6, 6, 6, 5, 5, 5, 4, 5, 5, 8, 8, 8, 8, 8, 8, 14,14,14,14,14,14, &
12997  6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 4, 5, 8, 8, 8, 8, 8, 8, 14,14,14,14,14,14, &
12998  6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 8, 8, 8, 8, 8, 8, 14,14,14,14,14,14, &
12999  !
13000  12,12,12,12,12,12, 11,11,11,11,11,11, 9,10,10,10,10,10, 15,15,15,15,15,15, &
13001  12,12,12,12,12,12, 11,11,11,11,11,11, 10, 9,10,10,10,10, 15,15,15,15,15,15, &
13002  12,12,12,12,12,12, 11,11,11,11,11,11, 10,10, 9,10,10,10, 15,15,15,15,15,15, &
13003  12,12,12,12,12,12, 11,11,11,11,11,11, 10,10,10, 9,10,10, 15,15,15,15,15,15, &
13004  12,12,12,12,12,12, 11,11,11,11,11,11, 10,10,10,10, 9,10, 15,15,15,15,15,15, &
13005  12,12,12,12,12,12, 11,11,11,11,11,11, 10,10,10,10,10, 9, 15,15,15,15,15,15, &
13006  !
13007  20,20,20,20,20,20, 19,19,19,19,19,19, 18,18,18,18,18,18, 16,17,17,17,17,17, &
13008  20,20,20,20,20,20, 19,19,19,19,19,19, 18,18,18,18,18,18, 17,16,17,17,17,17, &
13009  20,20,20,20,20,20, 19,19,19,19,19,19, 18,18,18,18,18,18, 17,17,16,17,17,17, &
13010  20,20,20,20,20,20, 19,19,19,19,19,19, 18,18,18,18,18,18, 17,17,17,16,17,17, &
13011  20,20,20,20,20,20, 19,19,19,19,19,19, 18,18,18,18,18,18, 17,17,17,17,16,17, &
13012  20,20,20,20,20,20, 19,19,19,19,19,19, 18,18,18,18,18,18, 17,17,17,17,17,16 &
13013  ],shape(hex_interactiontwintwin))
13014 
13015  if (len_trim(structure) /= 3) &
13016  call io_error(137,ext_msg='lattice_interaction_TwinByTwin: '//trim(structure))
13017 
13018  select case(structure)
13019  case('fcc')
13020  interactiontypes = fcc_interactiontwintwin
13021  ntwinmax = fcc_ntwinsystem
13022  case('bcc')
13023  interactiontypes = bcc_interactiontwintwin
13024  ntwinmax = bcc_ntwinsystem
13025  case('hex')
13026  interactiontypes = hex_interactiontwintwin
13027  ntwinmax = hex_ntwinsystem
13028  case default
13029  call io_error(137,ext_msg='lattice_interaction_TwinByTwin: '//trim(structure))
13030  end select
13031 
13032  interactionmatrix = buildinteraction(ntwin,ntwin,ntwinmax,ntwinmax,interactionvalues,interactiontypes)
13033 
13034 end function lattice_interaction_twinbytwin
13035 
13036 
13037 !--------------------------------------------------------------------------------------------------
13040 !--------------------------------------------------------------------------------------------------
13041 function lattice_interaction_transbytrans(Ntrans,interactionValues,structure) result(interactionMatrix)
13043  integer, dimension(:), intent(in) :: ntrans
13044  real(preal), dimension(:), intent(in) :: interactionvalues
13045  character(len=*), intent(in) :: structure
13046  real(preal), dimension(sum(Ntrans),sum(Ntrans)) :: interactionmatrix
13047 
13048  integer, dimension(:), allocatable :: ntransmax
13049  integer, dimension(:,:), allocatable :: interactiontypes
13050 
13051  integer, dimension(FCC_NTRANS,FCC_NTRANS), parameter :: &
13052  fcc_interactiontranstrans = reshape( [&
13053  1,1,1,2,2,2,2,2,2,2,2,2, & ! -----> acting
13054  1,1,1,2,2,2,2,2,2,2,2,2, & ! |
13055  1,1,1,2,2,2,2,2,2,2,2,2, & ! |
13056  2,2,2,1,1,1,2,2,2,2,2,2, & ! v
13057  2,2,2,1,1,1,2,2,2,2,2,2, & ! reacting
13058  2,2,2,1,1,1,2,2,2,2,2,2, &
13059  2,2,2,2,2,2,1,1,1,2,2,2, &
13060  2,2,2,2,2,2,1,1,1,2,2,2, &
13061  2,2,2,2,2,2,1,1,1,2,2,2, &
13062  2,2,2,2,2,2,2,2,2,1,1,1, &
13063  2,2,2,2,2,2,2,2,2,1,1,1, &
13064  2,2,2,2,2,2,2,2,2,1,1,1 &
13065  ],shape(fcc_interactiontranstrans))
13066 
13067  if (len_trim(structure) /= 3) &
13068  call io_error(137,ext_msg='lattice_interaction_TransByTrans: '//trim(structure))
13069 
13070  if(structure == 'fcc') then
13071  interactiontypes = fcc_interactiontranstrans
13072  ntransmax = fcc_ntranssystem
13073  else
13074  call io_error(137,ext_msg='lattice_interaction_TransByTrans: '//trim(structure))
13075  end if
13076 
13077  interactionmatrix = buildinteraction(ntrans,ntrans,ntransmax,ntransmax,interactionvalues,interactiontypes)
13078 
13080 
13081 
13082 !--------------------------------------------------------------------------------------------------
13085 !--------------------------------------------------------------------------------------------------
13086 function lattice_interaction_slipbytwin(Nslip,Ntwin,interactionValues,structure) result(interactionMatrix)
13088  integer, dimension(:), intent(in) :: nslip, & !< number of active slip systems per family
13089  ntwin
13090  real(preal), dimension(:), intent(in) :: interactionvalues
13091  character(len=*), intent(in) :: structure
13092  real(preal), dimension(sum(Nslip),sum(Ntwin)) :: interactionmatrix
13093 
13094  integer, dimension(:), allocatable :: nslipmax, &
13095  ntwinmax
13096  integer, dimension(:,:), allocatable :: interactiontypes
13097 
13098  integer, dimension(FCC_NTWIN,FCC_NSLIP), parameter :: &
13099  fcc_interactionsliptwin = reshape( [&
13100  1,1,1,3,3,3,2,2,2,3,3,3, & ! -----> twin (acting)
13101  1,1,1,3,3,3,3,3,3,2,2,2, & ! |
13102  1,1,1,2,2,2,3,3,3,3,3,3, & ! |
13103  3,3,3,1,1,1,3,3,3,2,2,2, & ! v
13104  3,3,3,1,1,1,2,2,2,3,3,3, & ! slip (reacting)
13105  2,2,2,1,1,1,3,3,3,3,3,3, &
13106  2,2,2,3,3,3,1,1,1,3,3,3, &
13107  3,3,3,2,2,2,1,1,1,3,3,3, &
13108  3,3,3,3,3,3,1,1,1,2,2,2, &
13109  3,3,3,2,2,2,3,3,3,1,1,1, &
13110  2,2,2,3,3,3,3,3,3,1,1,1, &
13111  3,3,3,3,3,3,2,2,2,1,1,1, &
13112 
13113  4,4,4,4,4,4,4,4,4,4,4,4, &
13114  4,4,4,4,4,4,4,4,4,4,4,4, &
13115  4,4,4,4,4,4,4,4,4,4,4,4, &
13116  4,4,4,4,4,4,4,4,4,4,4,4, &
13117  4,4,4,4,4,4,4,4,4,4,4,4, &
13118  4,4,4,4,4,4,4,4,4,4,4,4 &
13119  ],shape(fcc_interactionsliptwin))
13123  integer, dimension(BCC_NTWIN,BCC_NSLIP), parameter :: &
13124  bcc_interactionsliptwin = reshape( [&
13125  3,3,3,2,2,3,3,3,3,2,3,3, & ! -----> twin (acting)
13126  3,3,2,3,3,2,3,3,2,3,3,3, & ! |
13127  3,2,3,3,3,3,2,3,3,3,3,2, & ! |
13128  2,3,3,3,3,3,3,2,3,3,2,3, & ! v
13129  2,3,3,3,3,3,3,2,3,3,2,3, & ! slip (reacting)
13130  3,3,2,3,3,2,3,3,2,3,3,3, &
13131  3,2,3,3,3,3,2,3,3,3,3,2, &
13132  3,3,3,2,2,3,3,3,3,2,3,3, &
13133  2,3,3,3,3,3,3,2,3,3,2,3, &
13134  3,3,3,2,2,3,3,3,3,2,3,3, &
13135  3,2,3,3,3,3,2,3,3,3,3,2, &
13136  3,3,2,3,3,2,3,3,2,3,3,3, &
13137  !
13138  1,3,3,3,3,3,3,2,3,3,2,3, &
13139  3,1,3,3,3,3,2,3,3,3,3,2, &
13140  3,3,1,3,3,2,3,3,2,3,3,3, &
13141  3,3,3,1,2,3,3,3,3,2,3,3, &
13142  3,3,3,2,1,3,3,3,3,2,3,3, &
13143  3,3,2,3,3,1,3,3,2,3,3,3, &
13144  3,2,3,3,3,3,1,3,3,3,3,2, &
13145  2,3,3,3,3,3,3,1,3,3,2,3, &
13146  3,3,2,3,3,2,3,3,1,3,3,3, &
13147  3,3,3,2,2,3,3,3,3,1,3,3, &
13148  2,3,3,3,3,3,3,2,3,3,1,3, &
13149  3,2,3,3,3,3,2,3,3,3,3,1 &
13150  ],shape(bcc_interactionsliptwin))
13154  integer, dimension(HEX_NTWIN,HEX_NSLIP), parameter :: &
13155  hex_interactionsliptwin = reshape( [&
13156  1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, & ! ----> twin (acting)
13157  1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, & ! |
13158  1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, & ! |
13159  ! v
13160  5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, & ! slip (reacting)
13161  5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, &
13162  5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, &
13163  !
13164  9, 9, 9, 9, 9, 9, 10,10,10,10,10,10, 11,11,11,11,11,11, 12,12,12,12,12,12, &
13165  9, 9, 9, 9, 9, 9, 10,10,10,10,10,10, 11,11,11,11,11,11, 12,12,12,12,12,12, &
13166  9, 9, 9, 9, 9, 9, 10,10,10,10,10,10, 11,11,11,11,11,11, 12,12,12,12,12,12, &
13167  !
13168  13,13,13,13,13,13, 14,14,14,14,14,14, 15,15,15,15,15,15, 16,16,16,16,16,16, &
13169  13,13,13,13,13,13, 14,14,14,14,14,14, 15,15,15,15,15,15, 16,16,16,16,16,16, &
13170  13,13,13,13,13,13, 14,14,14,14,14,14, 15,15,15,15,15,15, 16,16,16,16,16,16, &
13171  13,13,13,13,13,13, 14,14,14,14,14,14, 15,15,15,15,15,15, 16,16,16,16,16,16, &
13172  13,13,13,13,13,13, 14,14,14,14,14,14, 15,15,15,15,15,15, 16,16,16,16,16,16, &
13173  13,13,13,13,13,13, 14,14,14,14,14,14, 15,15,15,15,15,15, 16,16,16,16,16,16, &
13174  !
13175  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13176  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13177  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13178  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13179  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13180  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13181  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13182  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13183  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13184  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13185  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13186  17,17,17,17,17,17, 18,18,18,18,18,18, 19,19,19,19,19,19, 20,20,20,20,20,20, &
13187  !
13188  21,21,21,21,21,21, 22,22,22,22,22,22, 23,23,23,23,23,23, 24,24,24,24,24,24, &
13189  21,21,21,21,21,21, 22,22,22,22,22,22, 23,23,23,23,23,23, 24,24,24,24,24,24, &
13190  21,21,21,21,21,21, 22,22,22,22,22,22, 23,23,23,23,23,23, 24,24,24,24,24,24, &
13191  21,21,21,21,21,21, 22,22,22,22,22,22, 23,23,23,23,23,23, 24,24,24,24,24,24, &
13192  21,21,21,21,21,21, 22,22,22,22,22,22, 23,23,23,23,23,23, 24,24,24,24,24,24, &
13193  21,21,21,21,21,21, 22,22,22,22,22,22, 23,23,23,23,23,23, 24,24,24,24,24,24 &
13194  !
13195  ],shape(hex_interactionsliptwin))
13196 
13197  if (len_trim(structure) /= 3) &
13198  call io_error(137,ext_msg='lattice_interaction_SlipByTwin: '//trim(structure))
13199 
13200  select case(structure)
13201  case('fcc')
13202  interactiontypes = fcc_interactionsliptwin
13203  nslipmax = fcc_nslipsystem
13204  ntwinmax = fcc_ntwinsystem
13205  case('bcc')
13206  interactiontypes = bcc_interactionsliptwin
13207  nslipmax = bcc_nslipsystem
13208  ntwinmax = bcc_ntwinsystem
13209  case('hex')
13210  interactiontypes = hex_interactionsliptwin
13211  nslipmax = hex_nslipsystem
13212  ntwinmax = hex_ntwinsystem
13213  case default
13214  call io_error(137,ext_msg='lattice_interaction_SlipByTwin: '//trim(structure))
13215  end select
13216 
13217  interactionmatrix = buildinteraction(nslip,ntwin,nslipmax,ntwinmax,interactionvalues,interactiontypes)
13218 
13219 end function lattice_interaction_slipbytwin
13220 
13221 
13222 !--------------------------------------------------------------------------------------------------
13225 !--------------------------------------------------------------------------------------------------
13226 function lattice_interaction_slipbytrans(Nslip,Ntrans,interactionValues,structure) result(interactionMatrix)
13228  integer, dimension(:), intent(in) :: nslip, & !< number of active slip systems per family
13229  ntrans
13230  real(preal), dimension(:), intent(in) :: interactionvalues
13231  character(len=*), intent(in) :: structure
13232  real(preal), dimension(sum(Nslip),sum(Ntrans)) :: interactionmatrix
13233 
13234  integer, dimension(:), allocatable :: nslipmax, &
13235  ntransmax
13236  integer, dimension(:,:), allocatable :: interactiontypes
13237 
13238  integer, dimension(FCC_NTRANS,FCC_NSLIP), parameter :: &
13239  fcc_interactionsliptrans = reshape( [&
13240  1,1,1,3,3,3,2,2,2,3,3,3, & ! -----> trans (acting)
13241  1,1,1,3,3,3,3,3,3,2,2,2, & ! |
13242  1,1,1,2,2,2,3,3,3,3,3,3, & ! |
13243  3,3,3,1,1,1,3,3,3,2,2,2, & ! v
13244  3,3,3,1,1,1,2,2,2,3,3,3, & ! slip (reacting)
13245  2,2,2,1,1,1,3,3,3,3,3,3, &
13246  2,2,2,3,3,3,1,1,1,3,3,3, &
13247  3,3,3,2,2,2,1,1,1,3,3,3, &
13248  3,3,3,3,3,3,1,1,1,2,2,2, &
13249  3,3,3,2,2,2,3,3,3,1,1,1, &
13250  2,2,2,3,3,3,3,3,3,1,1,1, &
13251  3,3,3,3,3,3,2,2,2,1,1,1, &
13252 
13253  4,4,4,4,4,4,4,4,4,4,4,4, &
13254  4,4,4,4,4,4,4,4,4,4,4,4, &
13255  4,4,4,4,4,4,4,4,4,4,4,4, &
13256  4,4,4,4,4,4,4,4,4,4,4,4, &
13257  4,4,4,4,4,4,4,4,4,4,4,4, &
13258  4,4,4,4,4,4,4,4,4,4,4,4 &
13259  ],shape(fcc_interactionsliptrans))
13260 
13261  if (len_trim(structure) /= 3) &
13262  call io_error(137,ext_msg='lattice_interaction_SlipByTrans: '//trim(structure))
13263 
13264  select case(structure)
13265  case('fcc')
13266  interactiontypes = fcc_interactionsliptrans
13267  nslipmax = fcc_nslipsystem
13268  ntransmax = fcc_ntranssystem
13269  case default
13270  call io_error(137,ext_msg='lattice_interaction_SlipByTrans: '//trim(structure))
13271  end select
13272 
13273  interactionmatrix = buildinteraction(nslip,ntrans,nslipmax,ntransmax,interactionvalues,interactiontypes)
13274 
13275  end function lattice_interaction_slipbytrans
13276 
13277 
13278 !--------------------------------------------------------------------------------------------------
13281 !--------------------------------------------------------------------------------------------------
13282 function lattice_interaction_twinbyslip(Ntwin,Nslip,interactionValues,structure) result(interactionMatrix)
13284  integer, dimension(:), intent(in) :: ntwin, & !< number of active twin systems per family
13285  nslip
13286  real(preal), dimension(:), intent(in) :: interactionvalues
13287  character(len=*), intent(in) :: structure
13288  real(preal), dimension(sum(Ntwin),sum(Nslip)) :: interactionmatrix
13289 
13290  integer, dimension(:), allocatable :: ntwinmax, &
13291  nslipmax
13292  integer, dimension(:,:), allocatable :: interactiontypes
13293 
13294  integer, dimension(FCC_NSLIP,FCC_NTWIN), parameter :: &
13295  fcc_interactiontwinslip = 1
13296 
13297  integer, dimension(BCC_NSLIP,BCC_NTWIN), parameter :: &
13298  bcc_interactiontwinslip = 1
13299 
13300  integer, dimension(HEX_NSLIP,HEX_NTWIN), parameter :: &
13301  hex_interactiontwinslip = reshape( [&
13302  1, 1, 1, 5, 5, 5, 9, 9, 9, 13,13,13,13,13,13, 17,17,17,17,17,17,17,17,17,17,17,17, 21,21,21,21,21,21, & ! ----> slip (acting)
13303  1, 1, 1, 5, 5, 5, 9, 9, 9, 13,13,13,13,13,13, 17,17,17,17,17,17,17,17,17,17,17,17, 21,21,21,21,21,21, & ! |
13304  1, 1, 1, 5, 5, 5, 9, 9, 9, 13,13,13,13,13,13, 17,17,17,17,17,17,17,17,17,17,17,17, 21,21,21,21,21,21, & ! |
13305  1, 1, 1, 5, 5, 5, 9, 9, 9, 13,13,13,13,13,13, 17,17,17,17,17,17,17,17,17,17,17,17, 21,21,21,21,21,21, & ! v
13306  1, 1, 1, 5, 5, 5, 9, 9, 9, 13,13,13,13,13,13, 17,17,17,17,17,17,17,17,17,17,17,17, 21,21,21,21,21,21, & ! twin (reacting)
13307  1, 1, 1, 5, 5, 5, 9, 9, 9, 13,13,13,13,13,13, 17,17,17,17,17,17,17,17,17,17,17,17, 21,21,21,21,21,21, &
13308  !
13309  2, 2, 2, 6, 6, 6, 10,10,10, 14,14,14,14,14,14, 18,18,18,18,18,18,18,18,18,18,18,18, 22,22,22,22,22,22, &
13310  2, 2, 2, 6, 6, 6, 10,10,10, 14,14,14,14,14,14, 18,18,18,18,18,18,18,18,18,18,18,18, 22,22,22,22,22,22, &
13311  2, 2, 2, 6, 6, 6, 10,10,10, 14,14,14,14,14,14, 18,18,18,18,18,18,18,18,18,18,18,18, 22,22,22,22,22,22, &
13312  2, 2, 2, 6, 6, 6, 10,10,10, 14,14,14,14,14,14, 18,18,18,18,18,18,18,18,18,18,18,18, 22,22,22,22,22,22, &
13313  2, 2, 2, 6, 6, 6, 10,10,10, 14,14,14,14,14,14, 18,18,18,18,18,18,18,18,18,18,18,18, 22,22,22,22,22,22, &
13314  2, 2, 2, 6, 6, 6, 10,10,10, 14,14,14,14,14,14, 18,18,18,18,18,18,18,18,18,18,18,18, 22,22,22,22,22,22, &
13315  !
13316  3, 3, 3, 7, 7, 7, 11,11,11, 15,15,15,15,15,15, 19,19,19,19,19,19,19,19,19,19,19,19, 23,23,23,23,23,23, &
13317  3, 3, 3, 7, 7, 7, 11,11,11, 15,15,15,15,15,15, 19,19,19,19,19,19,19,19,19,19,19,19, 23,23,23,23,23,23, &
13318  3, 3, 3, 7, 7, 7, 11,11,11, 15,15,15,15,15,15, 19,19,19,19,19,19,19,19,19,19,19,19, 23,23,23,23,23,23, &
13319  3, 3, 3, 7, 7, 7, 11,11,11, 15,15,15,15,15,15, 19,19,19,19,19,19,19,19,19,19,19,19, 23,23,23,23,23,23, &
13320  3, 3, 3, 7, 7, 7, 11,11,11, 15,15,15,15,15,15, 19,19,19,19,19,19,19,19,19,19,19,19, 23,23,23,23,23,23, &
13321  3, 3, 3, 7, 7, 7, 11,11,11, 15,15,15,15,15,15, 19,19,19,19,19,19,19,19,19,19,19,19, 23,23,23,23,23,23, &
13322  !
13323  4, 4, 4, 8, 8, 8, 12,12,12, 16,16,16,16,16,16, 20,20,20,20,20,20,20,20,20,20,20,20, 24,24,24,24,24,24, &
13324  4, 4, 4, 8, 8, 8, 12,12,12, 16,16,16,16,16,16, 20,20,20,20,20,20,20,20,20,20,20,20, 24,24,24,24,24,24, &
13325  4, 4, 4, 8, 8, 8, 12,12,12, 16,16,16,16,16,16, 20,20,20,20,20,20,20,20,20,20,20,20, 24,24,24,24,24,24, &
13326  4, 4, 4, 8, 8, 8, 12,12,12, 16,16,16,16,16,16, 20,20,20,20,20,20,20,20,20,20,20,20, 24,24,24,24,24,24, &
13327  4, 4, 4, 8, 8, 8, 12,12,12, 16,16,16,16,16,16, 20,20,20,20,20,20,20,20,20,20,20,20, 24,24,24,24,24,24, &
13328  4, 4, 4, 8, 8, 8, 12,12,12, 16,16,16,16,16,16, 20,20,20,20,20,20,20,20,20,20,20,20, 24,24,24,24,24,24 &
13329  ],shape(hex_interactiontwinslip))
13330 
13331  if (len_trim(structure) /= 3) &
13332  call io_error(137,ext_msg='lattice_interaction_TwinBySlip: '//trim(structure))
13333 
13334  select case(structure)
13335  case('fcc')
13336  interactiontypes = fcc_interactiontwinslip
13337  ntwinmax = fcc_ntwinsystem
13338  nslipmax = fcc_nslipsystem
13339  case('bcc')
13340  interactiontypes = bcc_interactiontwinslip
13341  ntwinmax = bcc_ntwinsystem
13342  nslipmax = bcc_nslipsystem
13343  case('hex')
13344  interactiontypes = hex_interactiontwinslip
13345  ntwinmax = hex_ntwinsystem
13346  nslipmax = hex_nslipsystem
13347  case default
13348  call io_error(137,ext_msg='lattice_interaction_TwinBySlip: '//trim(structure))
13349  end select
13350 
13351  interactionmatrix = buildinteraction(ntwin,nslip,ntwinmax,nslipmax,interactionvalues,interactiontypes)
13352 
13353 end function lattice_interaction_twinbyslip
13354 
13355 
13356 !--------------------------------------------------------------------------------------------------
13359 !--------------------------------------------------------------------------------------------------
13360 function lattice_schmidmatrix_slip(Nslip,structure,cOverA) result(SchmidMatrix)
13362  integer, dimension(:), intent(in) :: nslip
13363  character(len=*), intent(in) :: structure
13364  real(preal), intent(in) :: covera
13365  real(preal), dimension(3,3,sum(Nslip)) :: schmidmatrix
13366 
13367  real(preal), dimension(3,3,sum(Nslip)) :: coordinatesystem
13368  real(preal), dimension(:,:), allocatable :: slipsystems
13369  integer, dimension(:), allocatable :: nslipmax
13370  integer :: i
13371 
13372  if (len_trim(structure) /= 3) &
13373  call io_error(137,ext_msg='lattice_SchmidMatrix_slip: '//trim(structure))
13374 
13375  select case(structure)
13376  case('fcc')
13377  nslipmax = fcc_nslipsystem
13378  slipsystems = fcc_systemslip
13379  case('bcc')
13380  nslipmax = bcc_nslipsystem
13381  slipsystems = bcc_systemslip
13382  case('hex')
13383  nslipmax = hex_nslipsystem
13384  slipsystems = hex_systemslip
13385  case('bct')
13386  nslipmax = bct_nslipsystem
13387  slipsystems = bct_systemslip
13388  case default
13389  call io_error(137,ext_msg='lattice_SchmidMatrix_slip: '//trim(structure))
13390  end select
13391 
13392  if (any(nslipmax(1:size(nslip)) - nslip < 0)) &
13393  call io_error(145,ext_msg='Nslip '//trim(structure))
13394  if (any(nslip < 0)) &
13395  call io_error(144,ext_msg='Nslip '//trim(structure))
13396 
13397  coordinatesystem = buildcoordinatesystem(nslip,nslipmax,slipsystems,structure,covera)
13398 
13399  do i = 1, sum(nslip)
13400  schmidmatrix(1:3,1:3,i) = math_outer(coordinatesystem(1:3,1,i),coordinatesystem(1:3,2,i))
13401  if (abs(math_trace33(schmidmatrix(1:3,1:3,i))) > tol_math_check) &
13402  call io_error(0,i,ext_msg = 'dilatational Schmid matrix for slip')
13403  enddo
13404 
13405 end function lattice_schmidmatrix_slip
13406 
13407 
13408 !--------------------------------------------------------------------------------------------------
13411 !--------------------------------------------------------------------------------------------------
13412 function lattice_schmidmatrix_twin(Ntwin,structure,cOverA) result(SchmidMatrix)
13414  integer, dimension(:), intent(in) :: ntwin
13415  character(len=*), intent(in) :: structure
13416  real(preal), intent(in) :: covera
13417  real(preal), dimension(3,3,sum(Ntwin)) :: schmidmatrix
13418 
13419  real(preal), dimension(3,3,sum(Ntwin)) :: coordinatesystem
13420  real(preal), dimension(:,:), allocatable :: twinsystems
13421  integer, dimension(:), allocatable :: ntwinmax
13422  integer :: i
13423 
13424  if (len_trim(structure) /= 3) &
13425  call io_error(137,ext_msg='lattice_SchmidMatrix_twin: '//trim(structure))
13426 
13427  select case(structure)
13428  case('fcc')
13429  ntwinmax = fcc_ntwinsystem
13430  twinsystems = fcc_systemtwin
13431  case('bcc')
13432  ntwinmax = bcc_ntwinsystem
13433  twinsystems = bcc_systemtwin
13434  case('hex')
13435  ntwinmax = hex_ntwinsystem
13436  twinsystems = hex_systemtwin
13437  case default
13438  call io_error(137,ext_msg='lattice_SchmidMatrix_twin: '//trim(structure))
13439  end select
13440 
13441  if (any(ntwinmax(1:size(ntwin)) - ntwin < 0)) &
13442  call io_error(145,ext_msg='Ntwin '//trim(structure))
13443  if (any(ntwin < 0)) &
13444  call io_error(144,ext_msg='Ntwin '//trim(structure))
13445 
13446  coordinatesystem = buildcoordinatesystem(ntwin,ntwinmax,twinsystems,structure,covera)
13447 
13448  do i = 1, sum(ntwin)
13449  schmidmatrix(1:3,1:3,i) = math_outer(coordinatesystem(1:3,1,i),coordinatesystem(1:3,2,i))
13450  if (abs(math_trace33(schmidmatrix(1:3,1:3,i))) > tol_math_check) &
13451  call io_error(0,i,ext_msg = 'dilatational Schmid matrix for twin')
13452  enddo
13453 
13454 end function lattice_schmidmatrix_twin
13455 
13456 
13457 !--------------------------------------------------------------------------------------------------
13460 !--------------------------------------------------------------------------------------------------
13461 function lattice_schmidmatrix_trans(Ntrans,structure_target,cOverA,a_bcc,a_fcc) result(SchmidMatrix)
13463  integer, dimension(:), intent(in) :: ntrans
13464  character(len=*), intent(in) :: structure_target
13465  real(preal), intent(in) :: covera
13466  real(preal), dimension(3,3,sum(Ntrans)) :: schmidmatrix
13467 
13468  real(preal), dimension(3,3,sum(Ntrans)) :: devnull
13469  real(preal) :: a_bcc, a_fcc
13470 
13471  if (len_trim(structure_target) /= 3) &
13472  call io_error(137,ext_msg='lattice_SchmidMatrix_trans: '//trim(structure_target))
13473  if (structure_target(1:3) /= 'bcc' .and. structure_target(1:3) /= 'hex') &
13474  call io_error(137,ext_msg='lattice_SchmidMatrix_trans: '//trim(structure_target))
13475 
13476  if (structure_target(1:3) == 'hex' .and. (covera < 1.0_preal .or. covera > 2.0_preal)) &
13477  call io_error(131,ext_msg='lattice_SchmidMatrix_trans: '//trim(structure_target))
13478 
13479  if (structure_target(1:3) == 'bcc' .and. (a_bcc <= 0.0_preal .or. a_fcc <= 0.0_preal)) &
13480  call io_error(134,ext_msg='lattice_SchmidMatrix_trans: '//trim(structure_target))
13481 
13482  call buildtransformationsystem(devnull,schmidmatrix,ntrans,covera,a_fcc,a_bcc)
13483 
13484 end function lattice_schmidmatrix_trans
13485 
13486 
13487 !--------------------------------------------------------------------------------------------------
13490 !--------------------------------------------------------------------------------------------------
13491 function lattice_schmidmatrix_cleavage(Ncleavage,structure,cOverA) result(SchmidMatrix)
13493  integer, dimension(:), intent(in) :: ncleavage
13494  character(len=*), intent(in) :: structure
13495  real(preal), intent(in) :: covera
13496  real(preal), dimension(3,3,3,sum(Ncleavage)) :: schmidmatrix
13497 
13498  real(preal), dimension(3,3,sum(Ncleavage)) :: coordinatesystem
13499  real(preal), dimension(:,:), allocatable :: cleavagesystems
13500  integer, dimension(:), allocatable :: ncleavagemax
13501  integer :: i
13502 
13503  if (len_trim(structure) /= 3) &
13504  call io_error(137,ext_msg='lattice_SchmidMatrix_cleavage: '//trim(structure))
13505 
13506  select case(structure)
13507  case('ort')
13508  ncleavagemax = ort_ncleavagesystem
13509  cleavagesystems = ort_systemcleavage
13510  case('fcc')
13511  ncleavagemax = fcc_ncleavagesystem
13512  cleavagesystems = fcc_systemcleavage
13513  case('bcc')
13514  ncleavagemax = bcc_ncleavagesystem
13515  cleavagesystems = bcc_systemcleavage
13516  case default
13517  call io_error(137,ext_msg='lattice_SchmidMatrix_cleavage: '//trim(structure))
13518  end select
13519 
13520  if (any(ncleavagemax(1:size(ncleavage)) - ncleavage < 0)) &
13521  call io_error(145,ext_msg='Ncleavage '//trim(structure))
13522  if (any(ncleavage < 0)) &
13523  call io_error(144,ext_msg='Ncleavage '//trim(structure))
13524 
13525  coordinatesystem = buildcoordinatesystem(ncleavage,ncleavagemax,cleavagesystems,structure,covera)
13526 
13527  do i = 1, sum(ncleavage)
13528  schmidmatrix(1:3,1:3,1,i) = math_outer(coordinatesystem(1:3,1,i),coordinatesystem(1:3,2,i))
13529  schmidmatrix(1:3,1:3,2,i) = math_outer(coordinatesystem(1:3,3,i),coordinatesystem(1:3,2,i))
13530  schmidmatrix(1:3,1:3,3,i) = math_outer(coordinatesystem(1:3,2,i),coordinatesystem(1:3,2,i))
13531  enddo
13532 
13533 end function lattice_schmidmatrix_cleavage
13534 
13535 
13536 !--------------------------------------------------------------------------------------------------
13538 !--------------------------------------------------------------------------------------------------
13539 function lattice_slip_direction(Nslip,structure,cOverA) result(d)
13541  integer, dimension(:), intent(in) :: nslip
13542  character(len=*), intent(in) :: structure
13543  real(preal), intent(in) :: covera
13544  real(preal), dimension(3,sum(Nslip)) :: d
13545 
13546  real(preal), dimension(3,3,sum(Nslip)) :: coordinatesystem
13547 
13548  coordinatesystem = coordinatesystem_slip(nslip,structure,covera)
13549  d = coordinatesystem(1:3,1,1:sum(nslip))
13550 
13551 end function lattice_slip_direction
13552 
13553 
13554 !--------------------------------------------------------------------------------------------------
13556 !--------------------------------------------------------------------------------------------------
13557 function lattice_slip_normal(Nslip,structure,cOverA) result(n)
13559  integer, dimension(:), intent(in) :: nslip
13560  character(len=*), intent(in) :: structure
13561  real(preal), intent(in) :: covera
13562  real(preal), dimension(3,sum(Nslip)) :: n
13563 
13564  real(preal), dimension(3,3,sum(Nslip)) :: coordinatesystem
13565 
13566  coordinatesystem = coordinatesystem_slip(nslip,structure,covera)
13567  n = coordinatesystem(1:3,2,1:sum(nslip))
13568 
13569 end function lattice_slip_normal
13570 
13571 
13572 !--------------------------------------------------------------------------------------------------
13574 !--------------------------------------------------------------------------------------------------
13575 function lattice_slip_transverse(Nslip,structure,cOverA) result(t)
13577  integer, dimension(:), intent(in) :: nslip
13578  character(len=*), intent(in) :: structure
13579  real(preal), intent(in) :: covera
13580  real(preal), dimension(3,sum(Nslip)) :: t
13581 
13582  real(preal), dimension(3,3,sum(Nslip)) :: coordinatesystem
13583 
13584  coordinatesystem = coordinatesystem_slip(nslip,structure,covera)
13585  t = coordinatesystem(1:3,3,1:sum(nslip))
13586 
13587 end function lattice_slip_transverse
13588 
13589 
13590 !--------------------------------------------------------------------------------------------------
13593 !--------------------------------------------------------------------------------------------------
13594 function lattice_labels_slip(Nslip,structure) result(labels)
13596  integer, dimension(:), intent(in) :: nslip
13597  character(len=*), intent(in) :: structure
13598 
13599  character(len=:), dimension(:), allocatable :: labels
13600 
13601  real(preal), dimension(:,:), allocatable :: slipsystems
13602  integer, dimension(:), allocatable :: nslipmax
13603 
13604  if (len_trim(structure) /= 3) &
13605  call io_error(137,ext_msg='lattice_labels_slip: '//trim(structure))
13606 
13607  select case(structure)
13608  case('fcc')
13609  nslipmax = fcc_nslipsystem
13610  slipsystems = fcc_systemslip
13611  case('bcc')
13612  nslipmax = bcc_nslipsystem
13613  slipsystems = bcc_systemslip
13614  case('hex')
13615  nslipmax = hex_nslipsystem
13616  slipsystems = hex_systemslip
13617  case('bct')
13618  nslipmax = bct_nslipsystem
13619  slipsystems = bct_systemslip
13620  case default
13621  call io_error(137,ext_msg='lattice_labels_slip: '//trim(structure))
13622  end select
13623 
13624  if (any(nslipmax(1:size(nslip)) - nslip < 0)) &
13625  call io_error(145,ext_msg='Nslip '//trim(structure))
13626  if (any(nslip < 0)) &
13627  call io_error(144,ext_msg='Nslip '//trim(structure))
13628 
13629  labels = getlabels(nslip,nslipmax,slipsystems)
13630 
13631 end function lattice_labels_slip
13632 
13633 
13634 !--------------------------------------------------------------------------------------------------
13636 !--------------------------------------------------------------------------------------------------
13637 function lattice_applylatticesymmetry33(T,structure) result(T_sym)
13639  real(preal), dimension(3,3) :: t_sym
13640 
13641  real(preal), dimension(3,3), intent(in) :: t
13642  character(len=*), intent(in) :: structure
13643 
13644  integer :: k
13645 
13646  t_sym = 0.0_preal
13647 
13648  if (len_trim(structure) /= 3) &
13649  call io_error(137,ext_msg='lattice_applyLatticeSymmetry33: '//trim(structure))
13650 
13651  select case(structure)
13652  case('iso','fcc','bcc')
13653  do k=1,3
13654  t_sym(k,k) = t(1,1)
13655  enddo
13656  case('hex')
13657  t_sym(1,1) = t(1,1)
13658  t_sym(2,2) = t(1,1)
13659  t_sym(3,3) = t(3,3)
13660  case('ort','bct')
13661  t_sym(1,1) = t(1,1)
13662  t_sym(2,2) = t(2,2)
13663  t_sym(3,3) = t(3,3)
13664  case default
13665  call io_error(137,ext_msg='lattice_applyLatticeSymmetry33: '//trim(structure))
13666  end select
13667 
13668 end function lattice_applylatticesymmetry33
13669 
13670 
13671 !--------------------------------------------------------------------------------------------------
13674 !--------------------------------------------------------------------------------------------------
13675 function applylatticesymmetryc66(C66,structure) result(C66_sym)
13677  real(preal), dimension(6,6) :: c66_sym
13678 
13679  real(preal), dimension(6,6), intent(in) :: c66
13680  character(len=*), intent(in) :: structure
13681 
13682  integer :: j,k
13683 
13684  c66_sym = 0.0_preal
13685 
13686  if (len_trim(structure) /= 3) &
13687  call io_error(137,ext_msg='applyLatticeSymmetryC66: '//trim(structure))
13688 
13689  select case(structure)
13690  case ('iso')
13691  do k=1,3
13692  do j=1,3
13693  c66_sym(k,j) = c66(1,2)
13694  enddo
13695  c66_sym(k,k) = c66(1,1)
13696  c66_sym(k+3,k+3) = 0.5_preal*(c66(1,1)-c66(1,2))
13697  enddo
13698  case ('fcc','bcc')
13699  do k=1,3
13700  do j=1,3
13701  c66_sym(k,j) = c66(1,2)
13702  enddo
13703  c66_sym(k,k) = c66(1,1)
13704  c66_sym(k+3,k+3) = c66(4,4)
13705  enddo
13706  case ('hex')
13707  c66_sym(1,1) = c66(1,1)
13708  c66_sym(2,2) = c66(1,1)
13709  c66_sym(3,3) = c66(3,3)
13710  c66_sym(1,2) = c66(1,2)
13711  c66_sym(2,1) = c66(1,2)
13712  c66_sym(1,3) = c66(1,3)
13713  c66_sym(3,1) = c66(1,3)
13714  c66_sym(2,3) = c66(1,3)
13715  c66_sym(3,2) = c66(1,3)
13716  c66_sym(4,4) = c66(4,4)
13717  c66_sym(5,5) = c66(4,4)
13718  c66_sym(6,6) = 0.5_preal*(c66(1,1)-c66(1,2))
13719  case ('ort')
13720  c66_sym(1,1) = c66(1,1)
13721  c66_sym(2,2) = c66(2,2)
13722  c66_sym(3,3) = c66(3,3)
13723  c66_sym(1,2) = c66(1,2)
13724  c66_sym(2,1) = c66(1,2)
13725  c66_sym(1,3) = c66(1,3)
13726  c66_sym(3,1) = c66(1,3)
13727  c66_sym(2,3) = c66(2,3)
13728  c66_sym(3,2) = c66(2,3)
13729  c66_sym(4,4) = c66(4,4)
13730  c66_sym(5,5) = c66(5,5)
13731  c66_sym(6,6) = c66(6,6)
13732  case ('bct')
13733  c66_sym(1,1) = c66(1,1)
13734  c66_sym(2,2) = c66(1,1)
13735  c66_sym(3,3) = c66(3,3)
13736  c66_sym(1,2) = c66(1,2)
13737  c66_sym(2,1) = c66(1,2)
13738  c66_sym(1,3) = c66(1,3)
13739  c66_sym(3,1) = c66(1,3)
13740  c66_sym(2,3) = c66(1,3)
13741  c66_sym(3,2) = c66(1,3)
13742  c66_sym(4,4) = c66(4,4)
13743  c66_sym(5,5) = c66(4,4)
13744  c66_sym(6,6) = c66(6,6)
13745  case default
13746  call io_error(137,ext_msg='applyLatticeSymmetryC66: '//trim(structure))
13747  end select
13748 
13749 end function applylatticesymmetryc66
13750 
13751 
13752 !--------------------------------------------------------------------------------------------------
13755 !--------------------------------------------------------------------------------------------------
13756 function lattice_labels_twin(Ntwin,structure) result(labels)
13758  integer, dimension(:), intent(in) :: ntwin
13759  character(len=*), intent(in) :: structure
13760 
13761  character(len=:), dimension(:), allocatable :: labels
13762 
13763  real(preal), dimension(:,:), allocatable :: twinsystems
13764  integer, dimension(:), allocatable :: ntwinmax
13765 
13766  if (len_trim(structure) /= 3) &
13767  call io_error(137,ext_msg='lattice_labels_twin: '//trim(structure))
13768 
13769  select case(structure)
13770  case('fcc')
13771  ntwinmax = fcc_ntwinsystem
13772  twinsystems = fcc_systemtwin
13773  case('bcc')
13774  ntwinmax = bcc_ntwinsystem
13775  twinsystems = bcc_systemtwin
13776  case('hex')
13777  ntwinmax = hex_ntwinsystem
13778  twinsystems = hex_systemtwin
13779  case default
13780  call io_error(137,ext_msg='lattice_labels_twin: '//trim(structure))
13781  end select
13782 
13783  if (any(ntwinmax(1:size(ntwin)) - ntwin < 0)) &
13784  call io_error(145,ext_msg='Ntwin '//trim(structure))
13785  if (any(ntwin < 0)) &
13786  call io_error(144,ext_msg='Ntwin '//trim(structure))
13787 
13788  labels = getlabels(ntwin,ntwinmax,twinsystems)
13789 
13790 end function lattice_labels_twin
13791 
13792 
13793 !--------------------------------------------------------------------------------------------------
13796 !--------------------------------------------------------------------------------------------------
13797 function slipprojection_transverse(Nslip,structure,cOverA) result(projection)
13799  integer, dimension(:), intent(in) :: nslip
13800  character(len=*), intent(in) :: structure
13801  real(preal), intent(in) :: covera
13802  real(preal), dimension(sum(Nslip),sum(Nslip)) :: projection
13803 
13804  real(preal), dimension(3,sum(Nslip)) :: n, t
13805  integer :: i, j
13806 
13807  n = lattice_slip_normal(nslip,structure,covera)
13808  t = lattice_slip_transverse(nslip,structure,covera)
13809 
13810  do i=1, sum(nslip); do j=1, sum(nslip)
13811  projection(i,j) = abs(math_inner(n(:,i),t(:,j)))
13812  enddo; enddo
13813 
13814 end function slipprojection_transverse
13815 
13816 
13817 !--------------------------------------------------------------------------------------------------
13820 !--------------------------------------------------------------------------------------------------
13821 function slipprojection_direction(Nslip,structure,cOverA) result(projection)
13823  integer, dimension(:), intent(in) :: nslip
13824  character(len=*), intent(in) :: structure
13825  real(preal), intent(in) :: covera
13826  real(preal), dimension(sum(Nslip),sum(Nslip)) :: projection
13827 
13828  real(preal), dimension(3,sum(Nslip)) :: n, d
13829  integer :: i, j
13830 
13831  n = lattice_slip_normal(nslip,structure,covera)
13832  d = lattice_slip_direction(nslip,structure,covera)
13833 
13834  do i=1, sum(nslip); do j=1, sum(nslip)
13835  projection(i,j) = abs(math_inner(n(:,i),d(:,j)))
13836  enddo; enddo
13837 
13838 end function slipprojection_direction
13839 
13840 
13841 !--------------------------------------------------------------------------------------------------
13844 !--------------------------------------------------------------------------------------------------
13845 function coordinatesystem_slip(Nslip,structure,cOverA) result(coordinateSystem)
13847  integer, dimension(:), intent(in) :: nslip
13848  character(len=*), intent(in) :: structure
13849  real(preal), intent(in) :: covera
13850  real(preal), dimension(3,3,sum(Nslip)) :: coordinatesystem
13851 
13852  real(preal), dimension(:,:), allocatable :: slipsystems
13853  integer, dimension(:), allocatable :: nslipmax
13854 
13855  if (len_trim(structure) /= 3) &
13856  call io_error(137,ext_msg='coordinateSystem_slip: '//trim(structure))
13857 
13858  select case(structure)
13859  case('fcc')
13860  nslipmax = fcc_nslipsystem
13861  slipsystems = fcc_systemslip
13862  case('bcc')
13863  nslipmax = bcc_nslipsystem
13864  slipsystems = bcc_systemslip
13865  case('hex')
13866  nslipmax = hex_nslipsystem
13867  slipsystems = hex_systemslip
13868  case('bct')
13869  nslipmax = bct_nslipsystem
13870  slipsystems = bct_systemslip
13871  case default
13872  call io_error(137,ext_msg='coordinateSystem_slip: '//trim(structure))
13873  end select
13874 
13875  if (any(nslipmax(1:size(nslip)) - nslip < 0)) &
13876  call io_error(145,ext_msg='Nslip '//trim(structure))
13877  if (any(nslip < 0)) &
13878  call io_error(144,ext_msg='Nslip '//trim(structure))
13879 
13880  coordinatesystem = buildcoordinatesystem(nslip,nslipmax,slipsystems,structure,covera)
13881 
13882 end function coordinatesystem_slip
13883 
13884 
13885 !--------------------------------------------------------------------------------------------------
13887 !--------------------------------------------------------------------------------------------------
13888 function buildinteraction(reacting_used,acting_used,reacting_max,acting_max,values,matrix)
13890  integer, dimension(:), intent(in) :: &
13891  reacting_used, & !< # of reacting systems per family as specified in material.config
13892  acting_used, & !< # of acting systems per family as specified in material.config
13893  reacting_max, & !< max # of reacting systems per family for given lattice
13894  acting_max
13895  real(preal), dimension(:), intent(in) :: values
13896  integer, dimension(:,:), intent(in) :: matrix
13897  real(preal), dimension(sum(reacting_used),sum(acting_used)) :: buildinteraction
13898 
13899  integer :: &
13900  acting_family_index, acting_family, acting_system, &
13901  reacting_family_index, reacting_family, reacting_system, &
13902  i,j,k,l
13903 
13904  do acting_family = 1,size(acting_used,1)
13905  acting_family_index = sum(acting_used(1:acting_family-1))
13906  do acting_system = 1,acting_used(acting_family)
13907 
13908  do reacting_family = 1,size(reacting_used,1)
13909  reacting_family_index = sum(reacting_used(1:reacting_family-1))
13910  do reacting_system = 1,reacting_used(reacting_family)
13911 
13912  i = sum( acting_max(1: acting_family-1)) + acting_system
13913  j = sum(reacting_max(1:reacting_family-1)) + reacting_system
13914 
13915  k = acting_family_index + acting_system
13916  l = reacting_family_index + reacting_system
13917 
13918  if (matrix(i,j) > size(values)) call io_error(138,ext_msg='buildInteraction')
13919 
13920  buildinteraction(l,k) = values(matrix(i,j))
13921 
13922  enddo; enddo
13923  enddo; enddo
13924 
13925 end function buildinteraction
13926 
13927 
13928 !--------------------------------------------------------------------------------------------------
13931 !--------------------------------------------------------------------------------------------------
13932 function buildcoordinatesystem(active,potential,system,structure,cOverA)
13934  integer, dimension(:), intent(in) :: &
13935  active, & !< # of active systems per family
13936  potential
13937  real(preal), dimension(:,:), intent(in) :: &
13938  system
13939  character(len=*), intent(in) :: &
13940  structure
13941  real(preal), intent(in) :: &
13942  covera
13943  real(preal), dimension(3,3,sum(active)) :: &
13945 
13946  real(preal), dimension(3) :: &
13947  direction, normal
13948  integer :: &
13949  a, & !< index of active system
13950  p, & !< index in potential system matrix
13951  f, & !< index of my family
13952  s
13953 
13954  if (len_trim(structure) /= 3) &
13955  call io_error(137,ext_msg='buildCoordinateSystem: '//trim(structure))
13956  if (trim(structure) == 'bct' .and. covera > 2.0_preal) &
13957  call io_error(131,ext_msg='buildCoordinateSystem:'//trim(structure))
13958  if (trim(structure) == 'hex' .and. (covera < 1.0_preal .or. covera > 2.0_preal)) &
13959  call io_error(131,ext_msg='buildCoordinateSystem:'//trim(structure))
13960 
13961  a = 0
13962  activefamilies: do f = 1,size(active,1)
13963  activesystems: do s = 1,active(f)
13964  a = a + 1
13965  p = sum(potential(1:f-1))+s
13966 
13967  select case(trim(structure))
13968 
13969  case ('fcc','bcc','iso','ort','bct')
13970  direction = system(1:3,p)
13971  normal = system(4:6,p)
13972 
13973  case ('hex')
13974  direction = [ system(1,p)*1.5_preal, &
13975  (system(1,p)+2.0_preal*system(2,p))*sqrt(0.75_preal), &
13976  system(4,p)*covera ] ! direction [uvtw]->[3u/2 (u+2v)*sqrt(3)/2 w*(p/a)])
13977  normal = [ system(5,p), &
13978  (system(5,p)+2.0_preal*system(6,p))/sqrt(3.0_preal), &
13979  system(8,p)/covera ] ! plane (hkil)->(h (h+2k)/sqrt(3) l/(p/a))
13980 
13981  case default
13982  call io_error(137,ext_msg='buildCoordinateSystem: '//trim(structure))
13983 
13984  end select
13985 
13986  buildcoordinatesystem(1:3,1,a) = direction/norm2(direction)
13987  buildcoordinatesystem(1:3,2,a) = normal /norm2(normal)
13988  buildcoordinatesystem(1:3,3,a) = math_cross(direction/norm2(direction),&
13989  normal /norm2(normal))
13990 
13991  enddo activesystems
13992  enddo activefamilies
13993 
13994 end function buildcoordinatesystem
13995 
13996 
13997 !--------------------------------------------------------------------------------------------------
13999 ! Needed to calculate Schmid matrix and rotated stiffness matrices.
14000 ! @details: set c/a = 0.0 for fcc -> bcc transformation
14001 ! set a_Xcc = 0.0 for fcc -> hex transformation
14002 !--------------------------------------------------------------------------------------------------
14003 subroutine buildtransformationsystem(Q,S,Ntrans,cOverA,a_fcc,a_bcc)
14005  integer, dimension(:), intent(in) :: &
14006  Ntrans
14007  real(pReal), dimension(3,3,sum(Ntrans)), intent(out) :: &
14008  Q, & !< Total rotation: Q = R*B
14009  S
14010  real(pReal), intent(in) :: &
14011  cOverA, & !< c/a for target hex structure
14012  a_bcc, & !< lattice parameter a for target bcc structure
14013  a_fcc
14014 
14015  type(rotation) :: &
14016  R, & !< Pitsch rotation
14017  B
14018  real(pReal), dimension(3,3) :: &
14019  U, & !< Bain deformation
14020  ss, sd
14021  real(pReal), dimension(3) :: &
14022  x, y, z
14023  integer :: &
14024  i
14025  real(pReal), dimension(3+3,FCC_NTRANS), parameter :: &
14026  FCCTOHEX_SYSTEMTRANS = reshape(real( [&
14027  -2, 1, 1, 1, 1, 1, &
14028  1,-2, 1, 1, 1, 1, &
14029  1, 1,-2, 1, 1, 1, &
14030  2,-1, 1, -1,-1, 1, &
14031  -1, 2, 1, -1,-1, 1, &
14032  -1,-1,-2, -1,-1, 1, &
14033  -2,-1,-1, 1,-1,-1, &
14034  1, 2,-1, 1,-1,-1, &
14035  1,-1, 2, 1,-1,-1, &
14036  2, 1,-1, -1, 1,-1, &
14037  -1,-2,-1, -1, 1,-1, &
14038  -1, 1, 2, -1, 1,-1 &
14039  ],preal),shape(fcctohex_systemtrans))
14040  real(pReal), dimension(4,fcc_Ntrans), parameter :: &
14041  FCCTOBCC_SYSTEMTRANS = reshape([&
14042  0.0, 1.0, 0.0, 10.26, & ! Pitsch OR (Ma & Hartmaier 2014, Table 3)
14043  0.0,-1.0, 0.0, 10.26, &
14044  0.0, 0.0, 1.0, 10.26, &
14045  0.0, 0.0,-1.0, 10.26, &
14046  1.0, 0.0, 0.0, 10.26, &
14047  -1.0, 0.0, 0.0, 10.26, &
14048  0.0, 0.0, 1.0, 10.26, &
14049  0.0, 0.0,-1.0, 10.26, &
14050  1.0, 0.0, 0.0, 10.26, &
14051  -1.0, 0.0, 0.0, 10.26, &
14052  0.0, 1.0, 0.0, 10.26, &
14053  0.0,-1.0, 0.0, 10.26 &
14054  ],shape(fcctobcc_systemtrans))
14055 
14056  integer, dimension(9,fcc_Ntrans), parameter :: &
14057  FCCTOBCC_BAINVARIANT = reshape( [&
14058  1, 0, 0, 0, 1, 0, 0, 0, 1, & ! Pitsch OR (Ma & Hartmaier 2014, Table 3)
14059  1, 0, 0, 0, 1, 0, 0, 0, 1, &
14060  1, 0, 0, 0, 1, 0, 0, 0, 1, &
14061  1, 0, 0, 0, 1, 0, 0, 0, 1, &
14062  0, 1, 0, 1, 0, 0, 0, 0, 1, &
14063  0, 1, 0, 1, 0, 0, 0, 0, 1, &
14064  0, 1, 0, 1, 0, 0, 0, 0, 1, &
14065  0, 1, 0, 1, 0, 0, 0, 0, 1, &
14066  0, 0, 1, 1, 0, 0, 0, 1, 0, &
14067  0, 0, 1, 1, 0, 0, 0, 1, 0, &
14068  0, 0, 1, 1, 0, 0, 0, 1, 0, &
14069  0, 0, 1, 1, 0, 0, 0, 1, 0 &
14070  ],shape(fcctobcc_bainvariant))
14071 
14072  real(pReal), dimension(4,fcc_Ntrans), parameter :: &
14073  FCCTOBCC_BAINROT = reshape([&
14074  1.0, 0.0, 0.0, 45.0, & ! Rotate fcc austensite to bain variant
14075  1.0, 0.0, 0.0, 45.0, &
14076  1.0, 0.0, 0.0, 45.0, &
14077  1.0, 0.0, 0.0, 45.0, &
14078  0.0, 1.0, 0.0, 45.0, &
14079  0.0, 1.0, 0.0, 45.0, &
14080  0.0, 1.0, 0.0, 45.0, &
14081  0.0, 1.0, 0.0, 45.0, &
14082  0.0, 0.0, 1.0, 45.0, &
14083  0.0, 0.0, 1.0, 45.0, &
14084  0.0, 0.0, 1.0, 45.0, &
14085  0.0, 0.0, 1.0, 45.0 &
14086  ],shape(fcctobcc_bainrot))
14087 
14088  if (a_bcc > 0.0_preal .and. a_fcc > 0.0_preal .and. deq0(covera)) then ! fcc -> bcc transformation
14089  do i = 1,sum(ntrans)
14090  call r%fromAxisAngle(fcctobcc_systemtrans(:,i),degrees=.true.,p=1)
14091  call b%fromAxisAngle(fcctobcc_bainrot(:,i), degrees=.true.,p=1)
14092  x = real(fcctobcc_bainvariant(1:3,i),preal)
14093  y = real(fcctobcc_bainvariant(4:6,i),preal)
14094  z = real(fcctobcc_bainvariant(7:9,i),preal)
14095 
14096  u = (a_bcc/a_fcc)*math_outer(x,x) &
14097  + (a_bcc/a_fcc)*math_outer(y,y) * sqrt(2.0_preal) &
14098  + (a_bcc/a_fcc)*math_outer(z,z) * sqrt(2.0_preal)
14099  q(1:3,1:3,i) = matmul(r%asMatrix(),b%asMatrix())
14100  s(1:3,1:3,i) = matmul(r%asMatrix(),u) - math_i3
14101  enddo
14102  elseif (covera > 0.0_preal .and. deq0(a_bcc)) then ! fcc -> hex transformation
14103  ss = math_i3
14104  sd = math_i3
14105  ss(1,3) = sqrt(2.0_preal)/4.0_preal
14106  sd(3,3) = covera/sqrt(8.0_preal/3.0_preal)
14107 
14108  do i = 1,sum(ntrans)
14109  x = fcctohex_systemtrans(1:3,i)/norm2(fcctohex_systemtrans(1:3,i))
14110  z = fcctohex_systemtrans(4:6,i)/norm2(fcctohex_systemtrans(4:6,i))
14111  y = -math_cross(x,z)
14112  q(1:3,1,i) = x
14113  q(1:3,2,i) = y
14114  q(1:3,3,i) = z
14115  s(1:3,1:3,i) = matmul(q(1:3,1:3,i), matmul(matmul(sd,ss), transpose(q(1:3,1:3,i)))) - math_i3 ! ToDo: This is of interest for the Schmid matrix only
14116  enddo
14117  else
14118  call io_error(132,ext_msg='buildTransformationSystem')
14119  endif
14120 
14121 end subroutine buildtransformationsystem
14122 
14123 
14124 !--------------------------------------------------------------------------------------------------
14126 !--------------------------------------------------------------------------------------------------
14127 function getlabels(active,potential,system) result(labels)
14129  integer, dimension(:), intent(in) :: &
14130  active, & !< # of active systems per family
14131  potential
14132  real(preal), dimension(:,:), intent(in) :: &
14133  system
14134 
14135  character(len=:), dimension(:), allocatable :: labels
14136  character(len=:), allocatable :: label
14137 
14138  integer :: i,j
14139  integer :: &
14140  a, & !< index of active system
14141  p, & !< index in potential system matrix
14142  f, & !< index of my family
14143  s
14144 
14145  i = 2*size(system,1) + (size(system,1) - 2) + 4 ! 2 letters per index + spaces + brackets
14146  allocate(character(len=i) :: labels(sum(active)), label)
14147 
14148  a = 0
14149  activefamilies: do f = 1,size(active,1)
14150  activesystems: do s = 1,active(f)
14151  a = a + 1
14152  p = sum(potential(1:f-1))+s
14153 
14154  i = 1
14155  label(i:i) = '['
14156  direction: do j = 1, size(system,1)/2
14157  write(label(i+1:i+2),'(I2.1)') int(system(j,p))
14158  label(i+3:i+3) = ' '
14159  i = i + 3
14160  enddo direction
14161  label(i:i) = ']'
14162 
14163  i = i +1
14164  label(i:i) = '('
14165  normal: do j = size(system,1)/2+1, size(system,1)
14166  write(label(i+1:i+2),'(I2.1)') int(system(j,p))
14167  label(i+3:i+3) = ' '
14168  i = i + 3
14169  enddo normal
14170  label(i:i) = ')'
14171 
14172  labels(s) = label
14173 
14174  enddo activesystems
14175  enddo activefamilies
14176 
14177 end function getlabels
14178 
14179 
14180 !--------------------------------------------------------------------------------------------------
14183 !--------------------------------------------------------------------------------------------------
14184 function equivalent_nu(C,assumption) result(nu)
14186  real(preal), dimension(6,6), intent(in) :: c
14187  character(len=*), intent(in) :: assumption
14188 
14189  real(preal) :: k, mu, nu
14190  logical :: error
14191  real(preal), dimension(6,6) :: s
14192 
14193  if (io_lc(assumption) == 'voigt') then
14194  k = (c(1,1)+c(2,2)+c(3,3) +2.0_preal*(c(1,2)+c(2,3)+c(1,3))) &
14195  / 9.0_preal
14196  elseif(io_lc(assumption) == 'reuss') then
14197  call math_invert(s,error,c)
14198  if(error) call io_error(0)
14199  k = 1.0_preal &
14200  / (s(1,1)+s(2,2)+s(3,3) +2.0_preal*(s(1,2)+s(2,3)+s(1,3)))
14201  else
14202  call io_error(0)
14203  k = 0.0_preal
14204  endif
14205 
14206  mu = equivalent_mu(c,assumption)
14207  nu = (1.5_preal*k -mu)/(3.0_preal*k+mu)
14208 
14209 end function equivalent_nu
14210 
14211 
14212 !--------------------------------------------------------------------------------------------------
14215 !--------------------------------------------------------------------------------------------------
14216 function equivalent_mu(C,assumption) result(mu)
14218  real(preal), dimension(6,6), intent(in) :: c
14219  character(len=*), intent(in) :: assumption
14220 
14221  real(preal) :: mu
14222  logical :: error
14223  real(preal), dimension(6,6) :: s
14224 
14225  if (io_lc(assumption) == 'voigt') then
14226  mu = (1.0_preal*(c(1,1)+c(2,2)+c(3,3)) -1.0_preal*(c(1,2)+c(2,3)+c(1,3)) +3.0_preal*(c(4,4)+c(5,5)+c(6,6))) &
14227  / 15.0_preal
14228  elseif(io_lc(assumption) == 'reuss') then
14229  call math_invert(s,error,c)
14230  if(error) call io_error(0)
14231  mu = 15.0_preal &
14232  / (4.0_preal*(s(1,1)+s(2,2)+s(3,3)) -4.0_preal*(s(1,2)+s(2,3)+s(1,3)) +3.0_preal*(s(4,4)+s(5,5)+s(6,6)))
14233  else
14234  call io_error(0)
14235  mu = 0.0_preal
14236  endif
14237 
14238 end function equivalent_mu
14239 
14240 
14241 !--------------------------------------------------------------------------------------------------
14243 !--------------------------------------------------------------------------------------------------
14244 subroutine unittest
14246  real(pReal), dimension(:,:,:), allocatable :: CoSy
14247  real(pReal), dimension(:,:), allocatable :: system
14248 
14249  real(pReal), dimension(6,6) :: C
14250  real(pReal), dimension(2) :: r
14251  real(pReal) :: lambda
14252 
14253  call random_number(r)
14254 
14255  system = reshape([1.0_preal+r(1),0.0_preal,0.0_preal, 0.0_preal,1.0_preal+r(2),0.0_preal],[6,1])
14256  cosy = buildcoordinatesystem([1],[1],system,'fcc',0.0_preal)
14257 
14258  if(any(dneq(cosy(1:3,1:3,1),math_i3))) &
14259  call io_error(0)
14260 
14261  call random_number(c)
14262  c(1,1) = c(1,1) + 1.0_preal
14263  c = applylatticesymmetryc66(c,'iso')
14264  if(dneq(c(6,6),equivalent_mu(c,'voigt'),1.0e-12_preal)) &
14265  call io_error(0,ext_msg='equivalent_mu/voigt')
14266  if(dneq(c(6,6),equivalent_mu(c,'voigt'),1.0e-12_preal)) &
14267  call io_error(0,ext_msg='equivalent_mu/reuss')
14268  lambda = c(1,2)
14269  if(dneq(lambda*0.5_preal/(lambda+equivalent_mu(c,'voigt')),equivalent_nu(c,'voigt'),1.0e-12_preal)) &
14270  call io_error(0,ext_msg='equivalent_nu/voigt')
14271  if(dneq(lambda*0.5_preal/(lambda+equivalent_mu(c,'reuss')),equivalent_nu(c,'reuss'),1.0e-12_preal)) &
14272  call io_error(0,ext_msg='equivalent_nu/reuss')
14273 
14274 end subroutine unittest
14275 
14276 end module lattice
14277 # 27 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
14278 
14279 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/source_thermal_dissipation.f90" 1
14280 !--------------------------------------------------------------------------------------------------
14285 !--------------------------------------------------------------------------------------------------
14287  use prec
14288  use debug
14289  use discretization
14290  use material
14291  use config
14292 
14293  implicit none
14294  private
14295 
14296  integer, dimension(:), allocatable :: &
14297  source_thermal_dissipation_offset, & !< which source is my current thermal dissipation mechanism?
14299 
14300  type :: tparameters
14301  real(preal) :: &
14302  kappa
14303  end type tparameters
14304 
14305  type(tparameters), dimension(:), allocatable :: param
14306 
14307 
14308  public :: &
14311 
14312 contains
14313 
14314 
14315 !--------------------------------------------------------------------------------------------------
14318 !--------------------------------------------------------------------------------------------------
14321  integer :: ninstance,sourceoffset,nipcmyphase,p
14322 
14323  write(6,'(/,a)') ' <<<+- source_'//source_thermal_dissipation_label//' init -+>>>'; flush(6)
14324 
14325  ninstance = count(phase_source == source_thermal_dissipation_id)
14327  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
14328 
14329  allocate(source_thermal_dissipation_offset(size(config_phase)), source=0)
14330  allocate(source_thermal_dissipation_instance(size(config_phase)), source=0)
14331  allocate(param(ninstance))
14332 
14333  do p = 1, size(config_phase)
14335  do sourceoffset = 1, phase_nsources(p)
14336  if (phase_source(sourceoffset,p) == source_thermal_dissipation_id) then
14337  source_thermal_dissipation_offset(p) = sourceoffset
14338  exit
14339  endif
14340  enddo
14341 
14342  if (all(phase_source(:,p) /= source_thermal_dissipation_id)) cycle
14343  associate(prm => param(source_thermal_dissipation_instance(p)), &
14344  config => config_phase(p))
14345 
14346  prm%kappa = config%getFloat('dissipation_coldworkcoeff')
14347 
14348  nipcmyphase = count(material_phaseat==p) * discretization_nip
14349  call material_allocatesourcestate(p,sourceoffset,nipcmyphase,0,0,0)
14350 
14351  end associate
14352  enddo
14353 
14354 end subroutine source_thermal_dissipation_init
14355 
14356 
14357 !--------------------------------------------------------------------------------------------------
14359 !--------------------------------------------------------------------------------------------------
14360 subroutine source_thermal_dissipation_getrateanditstangent(TDot, dTDot_dT, Tstar, Lp, phase)
14362  integer, intent(in) :: &
14363  phase
14364  real(preal), intent(in), dimension(3,3) :: &
14365  tstar
14366  real(preal), intent(in), dimension(3,3) :: &
14367  lp
14368 
14369  real(preal), intent(out) :: &
14370  tdot, &
14371  dtdot_dt
14372 
14373  associate(prm => param(source_thermal_dissipation_instance(phase)))
14374  tdot = prm%kappa*sum(abs(tstar*lp))
14375  dtdot_dt = 0.0_preal
14376  end associate
14377 
14379 
14380 end module source_thermal_dissipation
14381 # 28 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
14382 
14383 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/source_thermal_externalheat.f90" 1
14384 !--------------------------------------------------------------------------------------------------
14389 !--------------------------------------------------------------------------------------------------
14391  use prec
14392  use debug
14393  use discretization
14394  use material
14395  use config
14396 
14397  implicit none
14398  private
14399 
14400  integer, dimension(:), allocatable :: &
14401  source_thermal_externalheat_offset, & !< which source is my current thermal dissipation mechanism?
14403 
14404  type :: tparameters
14405  real(preal), dimension(:), allocatable :: &
14406  time, &
14407  heat_rate
14408  integer :: &
14409  nintervals
14410  end type tparameters
14411 
14412  type(tparameters), dimension(:), allocatable :: param
14413 
14414 
14415  public :: &
14419 
14420 contains
14421 
14422 
14423 !--------------------------------------------------------------------------------------------------
14426 !--------------------------------------------------------------------------------------------------
14429  integer :: ninstance,sourceoffset,nipcmyphase,p
14430 
14431  write(6,'(/,a)') ' <<<+- source_'//source_thermal_externalheat_label//' init -+>>>'; flush(6)
14432 
14433  ninstance = count(phase_source == source_thermal_externalheat_id)
14435  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
14436 
14437  allocate(source_thermal_externalheat_offset(size(config_phase)), source=0)
14438  allocate(source_thermal_externalheat_instance(size(config_phase)), source=0)
14439  allocate(param(ninstance))
14440 
14441  do p = 1, size(config_phase)
14443  do sourceoffset = 1, phase_nsources(p)
14444  if (phase_source(sourceoffset,p) == source_thermal_externalheat_id) then
14445  source_thermal_externalheat_offset(p) = sourceoffset
14446  exit
14447  endif
14448  enddo
14449 
14450  if (all(phase_source(:,p) /= source_thermal_externalheat_id)) cycle
14451  associate(prm => param(source_thermal_externalheat_instance(p)), &
14452  config => config_phase(p))
14453 
14454  prm%time = config%getFloats('externalheat_time')
14455  prm%nIntervals = size(prm%time) - 1
14456 
14457  prm%heat_rate = config%getFloats('externalheat_rate',requiredsize = size(prm%time))
14458 
14459  nipcmyphase = count(material_phaseat==p) * discretization_nip
14460  call material_allocatesourcestate(p,sourceoffset,nipcmyphase,1,1,0)
14461 
14462  end associate
14463  enddo
14464 
14465 end subroutine source_thermal_externalheat_init
14466 
14467 
14468 !--------------------------------------------------------------------------------------------------
14471 !--------------------------------------------------------------------------------------------------
14472 subroutine source_thermal_externalheat_dotstate(phase, of)
14474  integer, intent(in) :: &
14475  phase, &
14476  of
14477 
14478  integer :: &
14479  sourceoffset
14480 
14481  sourceoffset = source_thermal_externalheat_offset(phase)
14482 
14483  sourcestate(phase)%p(sourceoffset)%dotState(1,of) = 1.0_preal ! state is current time
14484 
14486 
14487 
14488 !--------------------------------------------------------------------------------------------------
14490 !--------------------------------------------------------------------------------------------------
14491 subroutine source_thermal_externalheat_getrateanditstangent(TDot, dTDot_dT, phase, of)
14493  integer, intent(in) :: &
14494  phase, &
14495  of
14496  real(preal), intent(out) :: &
14497  tdot, &
14498  dtdot_dt
14499 
14500  integer :: &
14501  sourceoffset, interval
14502  real(preal) :: &
14503  frac_time
14504 
14505  sourceoffset = source_thermal_externalheat_offset(phase)
14506 
14507  associate(prm => param(source_thermal_externalheat_instance(phase)))
14508  do interval = 1, prm%nIntervals ! scan through all rate segments
14509  frac_time = (sourcestate(phase)%p(sourceoffset)%state(1,of) - prm%time(interval)) &
14510  / (prm%time(interval+1) - prm%time(interval)) ! fractional time within segment
14511  if ( (frac_time < 0.0_preal .and. interval == 1) &
14512  .or. (frac_time >= 1.0_preal .and. interval == prm%nIntervals) &
14513  .or. (frac_time >= 0.0_preal .and. frac_time < 1.0_preal) ) &
14514  tdot = prm%heat_rate(interval ) * (1.0_preal - frac_time) + &
14515  prm%heat_rate(interval+1) * frac_time ! interpolate heat rate between segment boundaries...
14516  ! ...or extrapolate if outside of bounds
14517  enddo
14518  dtdot_dt = 0.0
14519  end associate
14520 
14522 
14523 end module source_thermal_externalheat
14524 # 29 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
14525 
14526 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/source_damage_isoBrittle.f90" 1
14527 !--------------------------------------------------------------------------------------------------
14532 !--------------------------------------------------------------------------------------------------
14534  use prec
14535  use debug
14536  use io
14537  use math
14538  use discretization
14539  use material
14540  use config
14541  use results
14542 
14543  implicit none
14544  private
14545 
14546  integer, dimension(:), allocatable :: &
14549 
14550  type, private :: tparameters
14551  real(preal) :: &
14552  critstrainenergy, &
14553  n
14554  character(len=pStringLen), allocatable, dimension(:) :: &
14555  output
14556  end type tparameters
14557 
14558  type(tparameters), dimension(:), allocatable :: param
14559 
14560 
14561  public :: &
14566 
14567 contains
14568 
14569 
14570 !--------------------------------------------------------------------------------------------------
14573 !--------------------------------------------------------------------------------------------------
14576  integer :: ninstance,sourceoffset,nipcmyphase,p
14577  character(len=pStringLen) :: extmsg = ''
14578 
14579  write(6,'(/,a)') ' <<<+- source_'//source_damage_isobrittle_label//' init -+>>>'; flush(6)
14580 
14581  ninstance = count(phase_source == source_damage_isobrittle_id)
14583  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
14584 
14585  allocate(source_damage_isobrittle_offset(size(config_phase)), source=0)
14586  allocate(source_damage_isobrittle_instance(size(config_phase)), source=0)
14587  allocate(param(ninstance))
14588 
14589  do p = 1, size(config_phase)
14591  do sourceoffset = 1, phase_nsources(p)
14592  if (phase_source(sourceoffset,p) == source_damage_isobrittle_id) then
14593  source_damage_isobrittle_offset(p) = sourceoffset
14594  exit
14595  endif
14596  enddo
14597 
14598  if (all(phase_source(:,p) /= source_damage_isobrittle_id)) cycle
14599  associate(prm => param(source_damage_isobrittle_instance(p)), &
14600  config => config_phase(p))
14601 
14602  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
14603 
14604  prm%N = config%getFloat('isobrittle_n')
14605  prm%critStrainEnergy = config%getFloat('isobrittle_criticalstrainenergy')
14606 
14607  ! sanity checks
14608  if (prm%N <= 0.0_preal) extmsg = trim(extmsg)//' isobrittle_n'
14609  if (prm%critStrainEnergy <= 0.0_preal) extmsg = trim(extmsg)//' isobrittle_criticalstrainenergy'
14610 
14611  nipcmyphase = count(material_phaseat==p) * discretization_nip
14612  call material_allocatesourcestate(p,sourceoffset,nipcmyphase,1,1,1)
14613  sourcestate(p)%p(sourceoffset)%atol = config%getFloat('isobrittle_atol',defaultval=1.0e-3_preal)
14614  if(any(sourcestate(p)%p(sourceoffset)%atol < 0.0_preal)) extmsg = trim(extmsg)//' isobrittle_atol'
14615 
14616  end associate
14617 
14618 !--------------------------------------------------------------------------------------------------
14619 ! exit if any parameter is out of range
14620  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//source_damage_isobrittle_label//')')
14621 
14622 enddo
14623 
14624 end subroutine source_damage_isobrittle_init
14625 
14626 
14627 !--------------------------------------------------------------------------------------------------
14629 !--------------------------------------------------------------------------------------------------
14630 subroutine source_damage_isobrittle_deltastate(C, Fe, ipc, ip, el)
14632  integer, intent(in) :: &
14633  ipc, & !< component-ID of integration point
14634  ip, & !< integration point
14635  el
14636  real(preal), intent(in), dimension(3,3) :: &
14637  fe
14638  real(preal), intent(in), dimension(6,6) :: &
14639  c
14640 
14641  integer :: &
14642  phase, &
14643  constituent, &
14644  sourceoffset
14645  real(preal), dimension(6) :: &
14646  strain
14647  real(preal) :: &
14648  strainenergy
14649 
14650  phase = material_phaseat(ipc,el)
14651  constituent = material_phasememberat(ipc,ip,el)
14652  sourceoffset = source_damage_isobrittle_offset(phase)
14653 
14654  strain = 0.5_preal*math_sym33to6(matmul(transpose(fe),fe)-math_i3)
14655 
14656  associate(prm => param(source_damage_isobrittle_instance(phase)))
14657  strainenergy = 2.0_preal*sum(strain*matmul(c,strain))/prm%critStrainEnergy
14658  ! ToDo: check strainenergy = 2.0_pReal*dot_product(strain,matmul(C,strain))/param(instance)%critStrainEnergy
14659 
14660  if (strainenergy > sourcestate(phase)%p(sourceoffset)%subState0(1,constituent)) then
14661  sourcestate(phase)%p(sourceoffset)%deltaState(1,constituent) = &
14662  strainenergy - sourcestate(phase)%p(sourceoffset)%state(1,constituent)
14663  else
14664  sourcestate(phase)%p(sourceoffset)%deltaState(1,constituent) = &
14665  sourcestate(phase)%p(sourceoffset)%subState0(1,constituent) - &
14666  sourcestate(phase)%p(sourceoffset)%state(1,constituent)
14667  endif
14668  end associate
14669 
14671 
14672 
14673 !--------------------------------------------------------------------------------------------------
14675 !--------------------------------------------------------------------------------------------------
14676 subroutine source_damage_isobrittle_getrateanditstangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
14678  integer, intent(in) :: &
14679  phase, &
14680  constituent
14681  real(preal), intent(in) :: &
14682  phi
14683  real(preal), intent(out) :: &
14684  localphidot, &
14685  dlocalphidot_dphi
14686 
14687  integer :: &
14688  sourceoffset
14689 
14690  sourceoffset = source_damage_isobrittle_offset(phase)
14691 
14692  associate(prm => param(source_damage_isobrittle_instance(phase)))
14693  localphidot = (1.0_preal - phi)**(prm%n - 1.0_preal) &
14694  - phi*sourcestate(phase)%p(sourceoffset)%state(1,constituent)
14695  dlocalphidot_dphi = - (prm%n - 1.0_preal)* (1.0_preal - phi)**max(0.0_preal,prm%n - 2.0_preal) &
14696  - sourcestate(phase)%p(sourceoffset)%state(1,constituent)
14697  end associate
14698 
14700 
14701 
14702 !--------------------------------------------------------------------------------------------------
14704 !--------------------------------------------------------------------------------------------------
14705 subroutine source_damage_isobrittle_results(phase,group)
14707  integer, intent(in) :: phase
14708  character(len=*), intent(in) :: group
14709 
14710  integer :: o
14711 
14712  associate(prm => param(source_damage_isobrittle_instance(phase)), &
14713  stt => sourcestate(phase)%p(source_damage_isobrittle_offset(phase))%state)
14714  outputsloop: do o = 1,size(prm%output)
14715  select case(trim(prm%output(o)))
14716  case ('isobrittle_drivingforce')
14717  call results_writedataset(group,stt,'tbd','driving force','tbd')
14718  end select
14719  enddo outputsloop
14720  end associate
14721 
14722 end subroutine source_damage_isobrittle_results
14723 
14724 end module source_damage_isobrittle
14725 # 30 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
14726 
14727 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/source_damage_isoDuctile.f90" 1
14728 !--------------------------------------------------------------------------------------------------
14733 !--------------------------------------------------------------------------------------------------
14735  use prec
14736  use debug
14737  use io
14738  use discretization
14739  use material
14740  use config
14741  use results
14742 
14743  implicit none
14744  private
14745 
14746  integer, dimension(:), allocatable :: &
14747  source_damage_isoductile_offset, & !< which source is my current damage mechanism?
14749 
14750  type, private :: tparameters
14751  real(preal) :: &
14752  critplasticstrain, &
14753  n
14754  character(len=pStringLen), allocatable, dimension(:) :: &
14755  output
14756  end type tparameters
14757 
14758  type(tparameters), dimension(:), allocatable, private :: param
14759 
14760 
14761  public :: &
14766 
14767 contains
14768 
14769 
14770 !--------------------------------------------------------------------------------------------------
14773 !--------------------------------------------------------------------------------------------------
14776  integer :: ninstance,sourceoffset,nipcmyphase,p
14777  character(len=pStringLen) :: extmsg = ''
14778 
14779  write(6,'(/,a)') ' <<<+- source_'//source_damage_isoductile_label//' init -+>>>'; flush(6)
14780 
14781  ninstance = count(phase_source == source_damage_isoductile_id)
14783  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
14784 
14785  allocate(source_damage_isoductile_offset(size(config_phase)), source=0)
14786  allocate(source_damage_isoductile_instance(size(config_phase)), source=0)
14787  allocate(param(ninstance))
14788 
14789  do p = 1, size(config_phase)
14791  do sourceoffset = 1, phase_nsources(p)
14792  if (phase_source(sourceoffset,p) == source_damage_isoductile_id) then
14793  source_damage_isoductile_offset(p) = sourceoffset
14794  exit
14795  endif
14796  enddo
14797 
14798  if (all(phase_source(:,p) /= source_damage_isoductile_id)) cycle
14799  associate(prm => param(source_damage_isoductile_instance(p)), &
14800  config => config_phase(p))
14801 
14802  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
14803 
14804  prm%N = config%getFloat('isoductile_ratesensitivity')
14805  prm%critPlasticStrain = config%getFloat('isoductile_criticalplasticstrain')
14806 
14807  ! sanity checks
14808  if (prm%N <= 0.0_preal) extmsg = trim(extmsg)//' isoductile_ratesensitivity'
14809  if (prm%critPlasticStrain <= 0.0_preal) extmsg = trim(extmsg)//' isoductile_criticalplasticstrain'
14810 
14811  nipcmyphase=count(material_phaseat==p) * discretization_nip
14812  call material_allocatesourcestate(p,sourceoffset,nipcmyphase,1,1,0)
14813  sourcestate(p)%p(sourceoffset)%atol = config%getFloat('isoductile_atol',defaultval=1.0e-3_preal)
14814  if(any(sourcestate(p)%p(sourceoffset)%atol < 0.0_preal)) extmsg = trim(extmsg)//' isoductile_atol'
14815 
14816  end associate
14817 
14818 !--------------------------------------------------------------------------------------------------
14819 ! exit if any parameter is out of range
14820  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//source_damage_isoductile_label//')')
14821 
14822 enddo
14823 
14824 end subroutine source_damage_isoductile_init
14825 
14826 
14827 !--------------------------------------------------------------------------------------------------
14829 !--------------------------------------------------------------------------------------------------
14830 subroutine source_damage_isoductile_dotstate(ipc, ip, el)
14832  integer, intent(in) :: &
14833  ipc, & !< component-ID of integration point
14834  ip, & !< integration point
14835  el
14836 
14837  integer :: &
14838  phase, &
14839  constituent, &
14840  sourceoffset, &
14841  damageoffset, &
14842  homog
14843 
14844  phase = material_phaseat(ipc,el)
14845  constituent = material_phasememberat(ipc,ip,el)
14846  sourceoffset = source_damage_isoductile_offset(phase)
14847  homog = material_homogenizationat(el)
14848  damageoffset = damagemapping(homog)%p(ip,el)
14849 
14850  associate(prm => param(source_damage_isoductile_instance(phase)))
14851  sourcestate(phase)%p(sourceoffset)%dotState(1,constituent) = &
14852  sum(plasticstate(phase)%slipRate(:,constituent))/(damage(homog)%p(damageoffset)**prm%N)/prm%critPlasticStrain
14853  end associate
14854 
14855 end subroutine source_damage_isoductile_dotstate
14856 
14857 
14858 !--------------------------------------------------------------------------------------------------
14860 !--------------------------------------------------------------------------------------------------
14861 subroutine source_damage_isoductile_getrateanditstangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
14863  integer, intent(in) :: &
14864  phase, &
14865  constituent
14866  real(preal), intent(in) :: &
14867  phi
14868  real(preal), intent(out) :: &
14869  localphidot, &
14870  dlocalphidot_dphi
14871 
14872  integer :: &
14873  sourceoffset
14874 
14875  sourceoffset = source_damage_isoductile_offset(phase)
14876 
14877  dlocalphidot_dphi = -sourcestate(phase)%p(sourceoffset)%state(1,constituent)
14878 
14879  localphidot = 1.0_preal &
14880  + dlocalphidot_dphi*phi
14881 
14883 
14884 
14885 !--------------------------------------------------------------------------------------------------
14887 !--------------------------------------------------------------------------------------------------
14888 subroutine source_damage_isoductile_results(phase,group)
14890  integer, intent(in) :: phase
14891  character(len=*), intent(in) :: group
14892 
14893  integer :: o
14894 
14895  associate(prm => param(source_damage_isoductile_instance(phase)), &
14896  stt => sourcestate(phase)%p(source_damage_isoductile_offset(phase))%state)
14897  outputsloop: do o = 1,size(prm%output)
14898  select case(trim(prm%output(o)))
14899  case ('isoductile_drivingforce')
14900  call results_writedataset(group,stt,'tbd','driving force','tbd')
14901  end select
14902  enddo outputsloop
14903  end associate
14904 
14905 end subroutine source_damage_isoductile_results
14906 
14907 end module source_damage_isoductile
14908 # 31 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
14909 
14910 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/source_damage_anisoBrittle.f90" 1
14911 !--------------------------------------------------------------------------------------------------
14916 !--------------------------------------------------------------------------------------------------
14918  use prec
14919  use debug
14920  use io
14921  use math
14922  use discretization
14923  use material
14924  use config
14925  use lattice
14926  use results
14927 
14928  implicit none
14929  private
14930 
14931  integer, dimension(:), allocatable :: &
14932  source_damage_anisobrittle_offset, & !< which source is my current source mechanism?
14934 
14935  type :: tparameters
14936  real(preal) :: &
14937  sdot_0, &
14938  n
14939  real(preal), dimension(:), allocatable :: &
14940  critdisp, &
14941  critload
14942  real(preal), dimension(:,:,:,:), allocatable :: &
14943  cleavage_systems
14944  integer :: &
14945  sum_n_cl
14946  character(len=pStringLen), allocatable, dimension(:) :: &
14947  output
14948  end type tparameters
14949 
14950  type(tparameters), dimension(:), allocatable :: param
14951 
14952 
14953  public :: &
14958 
14959 contains
14960 
14961 
14962 !--------------------------------------------------------------------------------------------------
14965 !--------------------------------------------------------------------------------------------------
14968  integer :: ninstance,sourceoffset,nipcmyphase,p
14969  integer, dimension(:), allocatable :: n_cl
14970  character(len=pStringLen) :: extmsg = ''
14971 
14972  write(6,'(/,a)') ' <<<+- source_'//source_damage_anisobrittle_label//' init -+>>>'; flush(6)
14973 
14974  ninstance = count(phase_source == source_damage_anisobrittle_id)
14976  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
14977 
14978  allocate(source_damage_anisobrittle_offset(size(config_phase)), source=0)
14979  allocate(source_damage_anisobrittle_instance(size(config_phase)), source=0)
14980  allocate(param(ninstance))
14981 
14982  do p = 1, size(config_phase)
14984  do sourceoffset = 1, phase_nsources(p)
14985  if (phase_source(sourceoffset,p) == source_damage_anisobrittle_id) then
14986  source_damage_anisobrittle_offset(p) = sourceoffset
14987  exit
14988  endif
14989  enddo
14990 
14991  if (all(phase_source(:,p) /= source_damage_anisobrittle_id)) cycle
14992  associate(prm => param(source_damage_anisobrittle_instance(p)), &
14993  config => config_phase(p))
14994 
14995  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
14996 
14997  n_cl = config%getInts('ncleavage',defaultval=emptyintarray)
14998  prm%sum_N_cl = sum(abs(n_cl))
14999 
15000  prm%n = config%getFloat('anisobrittle_ratesensitivity')
15001  prm%sdot_0 = config%getFloat('anisobrittle_sdot0')
15002 
15003  prm%critDisp = config%getFloats('anisobrittle_criticaldisplacement',requiredsize=size(n_cl))
15004  prm%critLoad = config%getFloats('anisobrittle_criticalload', requiredsize=size(n_cl))
15005 
15006  prm%cleavage_systems = lattice_schmidmatrix_cleavage(n_cl,config%getString('lattice_structure'),&
15007  config%getFloat('c/a',defaultval=0.0_preal))
15008 
15009  ! expand: family => system
15010  prm%critDisp = math_expand(prm%critDisp,n_cl)
15011  prm%critLoad = math_expand(prm%critLoad,n_cl)
15012 
15013  ! sanity checks
15014  if (prm%n <= 0.0_preal) extmsg = trim(extmsg)//' anisobrittle_n'
15015  if (prm%sdot_0 <= 0.0_preal) extmsg = trim(extmsg)//' anisobrittle_sdot0'
15016  if (any(prm%critLoad < 0.0_preal)) extmsg = trim(extmsg)//' anisobrittle_critLoad'
15017  if (any(prm%critDisp < 0.0_preal)) extmsg = trim(extmsg)//' anisobrittle_critDisp'
15018 
15019  nipcmyphase = count(material_phaseat==p) * discretization_nip
15020  call material_allocatesourcestate(p,sourceoffset,nipcmyphase,1,1,0)
15021  sourcestate(p)%p(sourceoffset)%atol = config%getFloat('anisobrittle_atol',defaultval=1.0e-3_preal)
15022  if(any(sourcestate(p)%p(sourceoffset)%atol < 0.0_preal)) extmsg = trim(extmsg)//' anisobrittle_atol'
15023 
15024  end associate
15025 
15026 !--------------------------------------------------------------------------------------------------
15027 ! exit if any parameter is out of range
15028  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//source_damage_anisobrittle_label//')')
15029 
15030 enddo
15031 
15032 end subroutine source_damage_anisobrittle_init
15033 
15034 
15035 !--------------------------------------------------------------------------------------------------
15037 !--------------------------------------------------------------------------------------------------
15038 subroutine source_damage_anisobrittle_dotstate(S, ipc, ip, el)
15040  integer, intent(in) :: &
15041  ipc, & !< component-ID of integration point
15042  ip, & !< integration point
15043  el
15044  real(preal), intent(in), dimension(3,3) :: &
15045  s
15046 
15047  integer :: &
15048  phase, &
15049  constituent, &
15050  sourceoffset, &
15051  damageoffset, &
15052  homog, &
15053  i
15054  real(preal) :: &
15055  traction_d, traction_t, traction_n, traction_crit
15056 
15057  phase = material_phaseat(ipc,el)
15058  constituent = material_phasememberat(ipc,ip,el)
15059  sourceoffset = source_damage_anisobrittle_offset(phase)
15060  homog = material_homogenizationat(el)
15061  damageoffset = damagemapping(homog)%p(ip,el)
15062 
15063  associate(prm => param(source_damage_anisobrittle_instance(phase)))
15064  sourcestate(phase)%p(sourceoffset)%dotState(1,constituent) = 0.0_preal
15065  do i = 1, prm%sum_N_cl
15066  traction_d = math_tensordot(s,prm%cleavage_systems(1:3,1:3,1,i))
15067  traction_t = math_tensordot(s,prm%cleavage_systems(1:3,1:3,2,i))
15068  traction_n = math_tensordot(s,prm%cleavage_systems(1:3,1:3,3,i))
15069 
15070  traction_crit = prm%critLoad(i)*damage(homog)%p(damageoffset)**2.0_preal
15071 
15072  sourcestate(phase)%p(sourceoffset)%dotState(1,constituent) &
15073  = sourcestate(phase)%p(sourceoffset)%dotState(1,constituent) &
15074  + prm%sdot_0 / prm%critDisp(i) &
15075  * ((max(0.0_preal, abs(traction_d) - traction_crit)/traction_crit)**prm%n + &
15076  (max(0.0_preal, abs(traction_t) - traction_crit)/traction_crit)**prm%n + &
15077  (max(0.0_preal, abs(traction_n) - traction_crit)/traction_crit)**prm%n)
15078  enddo
15079  end associate
15080 
15082 
15083 
15084 !--------------------------------------------------------------------------------------------------
15086 !--------------------------------------------------------------------------------------------------
15087 subroutine source_damage_anisobrittle_getrateanditstangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
15089  integer, intent(in) :: &
15090  phase, &
15091  constituent
15092  real(preal), intent(in) :: &
15093  phi
15094  real(preal), intent(out) :: &
15095  localphidot, &
15096  dlocalphidot_dphi
15097 
15098  integer :: &
15099  sourceoffset
15100 
15101  sourceoffset = source_damage_anisobrittle_offset(phase)
15102 
15103  dlocalphidot_dphi = -sourcestate(phase)%p(sourceoffset)%state(1,constituent)
15104 
15105  localphidot = 1.0_preal &
15106  + dlocalphidot_dphi*phi
15107 
15109 
15110 
15111 !--------------------------------------------------------------------------------------------------
15113 !--------------------------------------------------------------------------------------------------
15114 subroutine source_damage_anisobrittle_results(phase,group)
15116  integer, intent(in) :: phase
15117  character(len=*), intent(in) :: group
15118 
15119  integer :: o
15120 
15121  associate(prm => param(source_damage_anisobrittle_instance(phase)), &
15122  stt => sourcestate(phase)%p(source_damage_anisobrittle_offset(phase))%state)
15123  outputsloop: do o = 1,size(prm%output)
15124  select case(trim(prm%output(o)))
15125  case ('anisobrittle_drivingforce')
15126  call results_writedataset(group,stt,'tbd','driving force','tbd')
15127  end select
15128  enddo outputsloop
15129  end associate
15130 
15132 
15133 end module source_damage_anisobrittle
15134 # 32 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
15135 
15136 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/source_damage_anisoDuctile.f90" 1
15137 !--------------------------------------------------------------------------------------------------
15142 !--------------------------------------------------------------------------------------------------
15144  use prec
15145  use debug
15146  use io
15147  use math
15148  use discretization
15149  use material
15150  use config
15151  use results
15152 
15153  implicit none
15154  private
15155 
15156  integer, dimension(:), allocatable :: &
15157  source_damage_anisoductile_offset, & !< which source is my current damage mechanism?
15159 
15160  type, private :: tparameters
15161  real(preal) :: &
15162  n
15163  real(preal), dimension(:), allocatable :: &
15164  critplasticstrain
15165  character(len=pStringLen), allocatable, dimension(:) :: &
15166  output
15167  end type tparameters
15168 
15169  type(tparameters), dimension(:), allocatable, private :: param
15170 
15171 
15172  public :: &
15177 
15178 contains
15179 
15180 
15181 !--------------------------------------------------------------------------------------------------
15184 !--------------------------------------------------------------------------------------------------
15187  integer :: ninstance,sourceoffset,nipcmyphase,p
15188  integer, dimension(:), allocatable :: n_sl
15189  character(len=pStringLen) :: extmsg = ''
15190 
15191  write(6,'(/,a)') ' <<<+- source_'//source_damage_anisoductile_label//' init -+>>>'; flush(6)
15192 
15193  ninstance = count(phase_source == source_damage_anisoductile_id)
15195  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
15196 
15197  allocate(source_damage_anisoductile_offset(size(config_phase)), source=0)
15198  allocate(source_damage_anisoductile_instance(size(config_phase)), source=0)
15199  allocate(param(ninstance))
15200 
15201  do p = 1, size(config_phase)
15203  do sourceoffset = 1, phase_nsources(p)
15204  if (phase_source(sourceoffset,p) == source_damage_anisoductile_id) then
15205  source_damage_anisoductile_offset(p) = sourceoffset
15206  exit
15207  endif
15208  enddo
15209 
15210  if (all(phase_source(:,p) /= source_damage_anisoductile_id)) cycle
15211  associate(prm => param(source_damage_anisoductile_instance(p)), &
15212  config => config_phase(p))
15213 
15214  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
15215 
15216  n_sl = config%getInts('nslip',defaultval=emptyintarray)
15217  prm%n = config%getFloat('anisoductile_ratesensitivity')
15218  prm%critPlasticStrain = config%getFloats('anisoductile_criticalplasticstrain',requiredsize=size(n_sl))
15219 
15220  ! expand: family => system
15221  prm%critPlasticStrain = math_expand(prm%critPlasticStrain,n_sl)
15222 
15223  ! sanity checks
15224  if (prm%n <= 0.0_preal) extmsg = trim(extmsg)//' anisoductile_ratesensitivity'
15225  if (any(prm%critPlasticStrain < 0.0_preal)) extmsg = trim(extmsg)//' anisoductile_criticalplasticstrain'
15226 
15227  nipcmyphase=count(material_phaseat==p) * discretization_nip
15228  call material_allocatesourcestate(p,sourceoffset,nipcmyphase,1,1,0)
15229  sourcestate(p)%p(sourceoffset)%atol = config%getFloat('anisoductile_atol',defaultval=1.0e-3_preal)
15230  if(any(sourcestate(p)%p(sourceoffset)%atol < 0.0_preal)) extmsg = trim(extmsg)//' anisoductile_atol'
15231 
15232  end associate
15233 
15234 !--------------------------------------------------------------------------------------------------
15235 ! exit if any parameter is out of range
15236  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//source_damage_anisoductile_label//')')
15237 
15238 enddo
15239 
15240 end subroutine source_damage_anisoductile_init
15241 
15242 
15243 !--------------------------------------------------------------------------------------------------
15245 !--------------------------------------------------------------------------------------------------
15246 subroutine source_damage_anisoductile_dotstate(ipc, ip, el)
15248  integer, intent(in) :: &
15249  ipc, & !< component-ID of integration point
15250  ip, & !< integration point
15251  el
15252 
15253  integer :: &
15254  phase, &
15255  constituent, &
15256  sourceoffset, &
15257  damageoffset, &
15258  homog
15259 
15260  phase = material_phaseat(ipc,el)
15261  constituent = material_phasememberat(ipc,ip,el)
15262  sourceoffset = source_damage_anisoductile_offset(phase)
15263  homog = material_homogenizationat(el)
15264  damageoffset = damagemapping(homog)%p(ip,el)
15265 
15266  associate(prm => param(source_damage_anisoductile_instance(phase)))
15267  sourcestate(phase)%p(sourceoffset)%dotState(1,constituent) &
15268  = sum(plasticstate(phase)%slipRate(:,constituent)/(damage(homog)%p(damageoffset)**prm%n)/prm%critPlasticStrain)
15269  end associate
15270 
15272 
15273 
15274 !--------------------------------------------------------------------------------------------------
15276 !--------------------------------------------------------------------------------------------------
15277 subroutine source_damage_anisoductile_getrateanditstangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
15279  integer, intent(in) :: &
15280  phase, &
15281  constituent
15282  real(preal), intent(in) :: &
15283  phi
15284  real(preal), intent(out) :: &
15285  localphidot, &
15286  dlocalphidot_dphi
15287 
15288  integer :: &
15289  sourceoffset
15290 
15291  sourceoffset = source_damage_anisoductile_offset(phase)
15292 
15293  dlocalphidot_dphi = -sourcestate(phase)%p(sourceoffset)%state(1,constituent)
15294 
15295  localphidot = 1.0_preal &
15296  + dlocalphidot_dphi*phi
15297 
15299 
15300 
15301 !--------------------------------------------------------------------------------------------------
15303 !--------------------------------------------------------------------------------------------------
15304 subroutine source_damage_anisoductile_results(phase,group)
15306  integer, intent(in) :: phase
15307  character(len=*), intent(in) :: group
15308 
15309  integer :: o
15310 
15311  associate(prm => param(source_damage_anisoductile_instance(phase)), &
15312  stt => sourcestate(phase)%p(source_damage_anisoductile_offset(phase))%state)
15313  outputsloop: do o = 1,size(prm%output)
15314  select case(trim(prm%output(o)))
15315  case ('anisoductile_drivingforce')
15316  call results_writedataset(group,stt,'tbd','driving force','tbd')
15317  end select
15318  enddo outputsloop
15319  end associate
15320 
15322 
15323 end module source_damage_anisoductile
15324 # 33 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
15325 
15326 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/kinematics_cleavage_opening.f90" 1
15327 !--------------------------------------------------------------------------------------------------
15332 !--------------------------------------------------------------------------------------------------
15334  use prec
15335  use io
15336  use config
15337  use debug
15338  use math
15339  use lattice
15340  use material
15341 
15342  implicit none
15343  private
15344 
15345  integer, dimension(:), allocatable :: kinematics_cleavage_opening_instance
15346 
15347  type :: tparameters
15348  integer :: &
15349  sum_n_cl
15350  real(preal) :: &
15351  sdot0, &
15352  n
15353  real(preal), dimension(:), allocatable :: &
15354  critload
15355  real(preal), dimension(:,:,:,:), allocatable :: &
15356  cleavage_systems
15357  end type tparameters
15358 
15359  type(tparameters), dimension(:), allocatable :: param
15360 
15361  public :: &
15364 
15365 contains
15366 
15367 
15368 !--------------------------------------------------------------------------------------------------
15371 !--------------------------------------------------------------------------------------------------
15374  integer :: ninstance,p
15375  integer, dimension(:), allocatable :: n_cl
15376  character(len=pStringLen) :: extmsg = ''
15377 
15378  write(6,'(/,a)') ' <<<+- kinematics_'//kinematics_cleavage_opening_label//' init -+>>>'; flush(6)
15379 
15380  ninstance = count(phase_kinematics == kinematics_cleavage_opening_id)
15382  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
15383 
15384  allocate(kinematics_cleavage_opening_instance(size(config_phase)), source=0)
15385  allocate(param(ninstance))
15386 
15387  do p = 1, size(config_phase)
15389  if (all(phase_kinematics(:,p) /= kinematics_cleavage_opening_id)) cycle
15390 
15391  associate(prm => param(kinematics_cleavage_opening_instance(p)), &
15392  config => config_phase(p))
15393 
15394  n_cl = config%getInts('ncleavage')
15395  prm%sum_N_cl = sum(abs(n_cl))
15396 
15397  prm%n = config%getFloat('anisobrittle_ratesensitivity')
15398  prm%sdot0 = config%getFloat('anisobrittle_sdot0')
15399 
15400  prm%critLoad = config%getFloats('anisobrittle_criticalload',requiredsize=size(n_cl))
15401 
15402  prm%cleavage_systems = lattice_schmidmatrix_cleavage(n_cl,config%getString('lattice_structure'),&
15403  config%getFloat('c/a',defaultval=0.0_preal))
15404 
15405  ! expand: family => system
15406  prm%critLoad = math_expand(prm%critLoad,n_cl)
15407 
15408  ! sanity checks
15409  if (prm%n <= 0.0_preal) extmsg = trim(extmsg)//' anisobrittle_n'
15410  if (prm%sdot0 <= 0.0_preal) extmsg = trim(extmsg)//' anisobrittle_sdot0'
15411  if (any(prm%critLoad < 0.0_preal)) extmsg = trim(extmsg)//' anisobrittle_critLoad'
15412 
15413 !--------------------------------------------------------------------------------------------------
15414 ! exit if any parameter is out of range
15415  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//kinematics_cleavage_opening_label//')')
15416 
15417  end associate
15418  enddo
15419 
15420 end subroutine kinematics_cleavage_opening_init
15421 
15422 
15423 !--------------------------------------------------------------------------------------------------
15425 !--------------------------------------------------------------------------------------------------
15426 subroutine kinematics_cleavage_opening_lianditstangent(Ld, dLd_dTstar, S, ipc, ip, el)
15428  integer, intent(in) :: &
15429  ipc, & !< grain number
15430  ip, & !< integration point number
15431  el
15432  real(preal), intent(in), dimension(3,3) :: &
15433  s
15434  real(preal), intent(out), dimension(3,3) :: &
15435  ld
15436  real(preal), intent(out), dimension(3,3,3,3) :: &
15437  dld_dtstar
15438 
15439  integer :: &
15440  homog, damageoffset, &
15441  i, k, l, m, n
15442  real(preal) :: &
15443  traction_d, traction_t, traction_n, traction_crit, &
15444  udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
15445 
15446  homog = material_homogenizationat(el)
15447  damageoffset = damagemapping(homog)%p(ip,el)
15448 
15449  ld = 0.0_preal
15450  dld_dtstar = 0.0_preal
15451  associate(prm => param(kinematics_cleavage_opening_instance(material_phaseat(ipc,el))))
15452  do i = 1,prm%sum_N_cl
15453  traction_crit = prm%critLoad(i)* damage(homog)%p(damageoffset)**2.0_preal
15454 
15455  traction_d = math_tensordot(s,prm%cleavage_systems(1:3,1:3,1,i))
15456  if (abs(traction_d) > traction_crit + tol_math_check) then
15457  udotd = sign(1.0_preal,traction_d)* prm%sdot0 * ((abs(traction_d) - traction_crit)/traction_crit)**prm%n
15458  ld = ld + udotd*prm%cleavage_systems(1:3,1:3,1,i)
15459  dudotd_dt = sign(1.0_preal,traction_d)*udotd*prm%n / (abs(traction_d) - traction_crit)
15460  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
15461  dld_dtstar(k,l,m,n) = dld_dtstar(k,l,m,n) &
15462  + dudotd_dt*prm%cleavage_systems(k,l,1,i) * prm%cleavage_systems(m,n,1,i)
15463  endif
15464 
15465  traction_t = math_tensordot(s,prm%cleavage_systems(1:3,1:3,2,i))
15466  if (abs(traction_t) > traction_crit + tol_math_check) then
15467  udott = sign(1.0_preal,traction_t)* prm%sdot0 * ((abs(traction_t) - traction_crit)/traction_crit)**prm%n
15468  ld = ld + udott*prm%cleavage_systems(1:3,1:3,2,i)
15469  dudott_dt = sign(1.0_preal,traction_t)*udott*prm%n / (abs(traction_t) - traction_crit)
15470  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
15471  dld_dtstar(k,l,m,n) = dld_dtstar(k,l,m,n) &
15472  + dudott_dt*prm%cleavage_systems(k,l,2,i) * prm%cleavage_systems(m,n,2,i)
15473  endif
15474 
15475  traction_n = math_tensordot(s,prm%cleavage_systems(1:3,1:3,3,i))
15476  if (abs(traction_n) > traction_crit + tol_math_check) then
15477  udotn = sign(1.0_preal,traction_n)* prm%sdot0 * ((abs(traction_n) - traction_crit)/traction_crit)**prm%n
15478  ld = ld + udotn*prm%cleavage_systems(1:3,1:3,3,i)
15479  dudotn_dt = sign(1.0_preal,traction_n)*udotn*prm%n / (abs(traction_n) - traction_crit)
15480  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
15481  dld_dtstar(k,l,m,n) = dld_dtstar(k,l,m,n) &
15482  + dudotn_dt*prm%cleavage_systems(k,l,3,i) * prm%cleavage_systems(m,n,3,i)
15483  endif
15484  enddo
15485  end associate
15486 
15488 
15489 end module kinematics_cleavage_opening
15490 # 34 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
15491 
15492 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/kinematics_slipplane_opening.f90" 1
15493 !--------------------------------------------------------------------------------------------------
15498 !--------------------------------------------------------------------------------------------------
15500  use prec
15501  use config
15502  use io
15503  use debug
15504  use math
15505  use lattice
15506  use material
15507 
15508  implicit none
15509  private
15510 
15511  integer, dimension(:), allocatable :: kinematics_slipplane_opening_instance
15512 
15513  type :: tparameters
15514  integer :: &
15515  sum_n_sl
15516  real(preal) :: &
15517  sdot0, &
15518  n
15519  real(preal), dimension(:), allocatable :: &
15520  critload
15521  real(preal), dimension(:,:,:), allocatable :: &
15522  p_d, &
15523  p_t, &
15524  p_n
15525  end type tparameters
15526 
15527  type(tparameters), dimension(:), allocatable :: param
15528 
15529  public :: &
15532 
15533 contains
15534 
15535 
15536 !--------------------------------------------------------------------------------------------------
15539 !--------------------------------------------------------------------------------------------------
15542  integer :: ninstance,p,i
15543  character(len=pStringLen) :: extmsg = ''
15544  integer, dimension(:), allocatable :: n_sl
15545  real(preal), dimension(:,:), allocatable :: d,n,t
15546 
15547  write(6,'(/,a)') ' <<<+- kinematics_'//kinematics_slipplane_opening_label//' init -+>>>'; flush(6)
15548 
15551  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
15552 
15553  allocate(kinematics_slipplane_opening_instance(size(config_phase)), source=0)
15554  allocate(param(ninstance))
15555 
15556  do p = 1, size(config_phase)
15558  if (all(phase_kinematics(:,p) /= kinematics_slipplane_opening_id)) cycle
15559  associate(prm => param(kinematics_slipplane_opening_instance(p)), &
15560  config => config_phase(p))
15561 
15562  prm%sdot0 = config%getFloat('anisoductile_sdot0')
15563  prm%n = config%getFloat('anisoductile_ratesensitivity')
15564  n_sl = config%getInts('nslip')
15565  prm%sum_N_sl = sum(abs(n_sl))
15566 
15567  d = lattice_slip_direction(n_sl,config%getString('lattice_structure'),&
15568  config%getFloat('c/a',defaultval=0.0_preal))
15569  t = lattice_slip_transverse(n_sl,config%getString('lattice_structure'),&
15570  config%getFloat('c/a',defaultval=0.0_preal))
15571  n = lattice_slip_normal(n_sl,config%getString('lattice_structure'),&
15572  config%getFloat('c/a',defaultval=0.0_preal))
15573  allocate(prm%P_d(3,3,size(d,2)),prm%P_t(3,3,size(t,2)),prm%P_n(3,3,size(n,2)))
15574 
15575  do i=1, size(n,2)
15576  prm%P_d(1:3,1:3,i) = math_outer(d(1:3,i), n(1:3,i))
15577  prm%P_t(1:3,1:3,i) = math_outer(t(1:3,i), n(1:3,i))
15578  prm%P_n(1:3,1:3,i) = math_outer(n(1:3,i), n(1:3,i))
15579  enddo
15580 
15581  prm%critLoad = config%getFloats('anisoductile_criticalload',requiredsize=size(n_sl))
15582 
15583  ! expand: family => system
15584  prm%critLoad = math_expand(prm%critLoad,n_sl)
15585 
15586  ! sanity checks
15587  if (prm%n <= 0.0_preal) extmsg = trim(extmsg)//' anisoDuctile_n'
15588  if (prm%sdot0 <= 0.0_preal) extmsg = trim(extmsg)//' anisoDuctile_sdot0'
15589  if (any(prm%critLoad < 0.0_preal)) extmsg = trim(extmsg)//' anisoDuctile_critLoad'
15590 
15591 !--------------------------------------------------------------------------------------------------
15592 ! exit if any parameter is out of range
15593  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//kinematics_slipplane_opening_label//')')
15594 
15595  end associate
15596  enddo
15597 
15598 end subroutine kinematics_slipplane_opening_init
15599 
15600 
15601 !--------------------------------------------------------------------------------------------------
15603 !--------------------------------------------------------------------------------------------------
15604 subroutine kinematics_slipplane_opening_lianditstangent(Ld, dLd_dTstar, S, ipc, ip, el)
15606  integer, intent(in) :: &
15607  ipc, & !< grain number
15608  ip, & !< integration point number
15609  el
15610  real(preal), intent(in), dimension(3,3) :: &
15611  s
15612  real(preal), intent(out), dimension(3,3) :: &
15613  ld
15614  real(preal), intent(out), dimension(3,3,3,3) :: &
15615  dld_dtstar
15616 
15617  integer :: &
15618  instance, phase, &
15619  homog, damageoffset, &
15620  i, k, l, m, n
15621  real(preal) :: &
15622  traction_d, traction_t, traction_n, traction_crit, &
15623  udotd, dudotd_dt, udott, dudott_dt, udotn, dudotn_dt
15624 
15625  phase = material_phaseat(ipc,el)
15626  instance = kinematics_slipplane_opening_instance(phase)
15627  homog = material_homogenizationat(el)
15628  damageoffset = damagemapping(homog)%p(ip,el)
15629 
15630  associate(prm => param(instance))
15631  ld = 0.0_preal
15632  dld_dtstar = 0.0_preal
15633  do i = 1, prm%sum_N_sl
15634 
15635  traction_d = math_tensordot(s,prm%P_d(1:3,1:3,i))
15636  traction_t = math_tensordot(s,prm%P_t(1:3,1:3,i))
15637  traction_n = math_tensordot(s,prm%P_n(1:3,1:3,i))
15638 
15639  traction_crit = prm%critLoad(i)* damage(homog)%p(damageoffset) ! degrading critical load carrying capacity by damage
15640 
15641  udotd = sign(1.0_preal,traction_d)* prm%sdot0* ( abs(traction_d)/traction_crit &
15642  - abs(traction_d)/prm%critLoad(i))**prm%n
15643  udott = sign(1.0_preal,traction_t)* prm%sdot0* ( abs(traction_t)/traction_crit &
15644  - abs(traction_t)/prm%critLoad(i))**prm%n
15645  udotn = prm%sdot0* ( max(0.0_preal,traction_n)/traction_crit &
15646  - max(0.0_preal,traction_n)/prm%critLoad(i))**prm%n
15647 
15648  if (dneq0(traction_d)) then
15649  dudotd_dt = udotd*prm%n/traction_d
15650  else
15651  dudotd_dt = 0.0_preal
15652  endif
15653  if (dneq0(traction_t)) then
15654  dudott_dt = udott*prm%n/traction_t
15655  else
15656  dudott_dt = 0.0_preal
15657  endif
15658  if (dneq0(traction_n)) then
15659  dudotn_dt = udotn*prm%n/traction_n
15660  else
15661  dudotn_dt = 0.0_preal
15662  endif
15663 
15664  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
15665  dld_dtstar(k,l,m,n) = dld_dtstar(k,l,m,n) &
15666  + dudotd_dt*prm%P_d(k,l,i)*prm%P_d(m,n,i) &
15667  + dudott_dt*prm%P_t(k,l,i)*prm%P_t(m,n,i) &
15668  + dudotn_dt*prm%P_n(k,l,i)*prm%P_n(m,n,i)
15669 
15670  ld = ld &
15671  + udotd*prm%P_d(1:3,1:3,i) &
15672  + udott*prm%P_t(1:3,1:3,i) &
15673  + udotn*prm%P_n(1:3,1:3,i)
15674  enddo
15675 
15676  end associate
15677 
15679 
15681 # 35 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
15682 
15683 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/kinematics_thermal_expansion.f90" 1
15684 !--------------------------------------------------------------------------------------------------
15688 !--------------------------------------------------------------------------------------------------
15690  use prec
15691  use io
15692  use config
15693  use debug
15694  use math
15695  use lattice
15696  use material
15697 
15698  implicit none
15699  private
15700 
15701  integer, dimension(:), allocatable :: kinematics_thermal_expansion_instance
15702 
15703  type :: tparameters
15704  real(preal) :: &
15705  t_ref
15706  real(preal), dimension(3,3,3) :: &
15707  expansion = 0.0_preal
15708  end type tparameters
15709 
15710  type(tparameters), dimension(:), allocatable :: param
15711 
15712  public :: &
15716 
15717 contains
15718 
15719 
15720 !--------------------------------------------------------------------------------------------------
15723 !--------------------------------------------------------------------------------------------------
15726  integer :: ninstance,p,i
15727  real(preal), dimension(:), allocatable :: temp
15728 
15729  write(6,'(/,a)') ' <<<+- kinematics_'//kinematics_thermal_expansion_label//' init -+>>>'; flush(6)
15730 
15733  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
15734 
15735  allocate(kinematics_thermal_expansion_instance(size(config_phase)), source=0)
15736  allocate(param(ninstance))
15737 
15738  do p = 1, size(config_phase)
15740  if (all(phase_kinematics(:,p) /= kinematics_thermal_expansion_id)) cycle
15741 
15742  associate(prm => param(kinematics_thermal_expansion_instance(p)), &
15743  config => config_phase(p))
15744 
15745  prm%T_ref = config%getFloat('reference_temperature', defaultval=0.0_preal)
15746 
15747  ! read up to three parameters (constant, linear, quadratic with T)
15748  temp = config%getFloats('thermal_expansion11')
15749  prm%expansion(1,1,1:size(temp)) = temp
15750  temp = config%getFloats('thermal_expansion22',defaultval=[(0.0_preal, i=1,size(temp))],requiredsize=size(temp))
15751  prm%expansion(2,2,1:size(temp)) = temp
15752  temp = config%getFloats('thermal_expansion33',defaultval=[(0.0_preal, i=1,size(temp))],requiredsize=size(temp))
15753  prm%expansion(3,3,1:size(temp)) = temp
15754  do i=1, size(prm%expansion,3)
15755  prm%expansion(1:3,1:3,i) = lattice_applylatticesymmetry33(prm%expansion(1:3,1:3,i),config%getString('lattice_structure'))
15756  enddo
15757 
15758  end associate
15759  enddo
15760 
15761 end subroutine kinematics_thermal_expansion_init
15762 
15763 
15764 !--------------------------------------------------------------------------------------------------
15766 !--------------------------------------------------------------------------------------------------
15767 pure function kinematics_thermal_expansion_initialstrain(homog,phase,offset)
15769  integer, intent(in) :: &
15770  phase, &
15771  homog, &
15772  offset
15773 
15774  real(preal), dimension(3,3) :: &
15776 
15777  associate(prm => param(kinematics_thermal_expansion_instance(phase)))
15779  (temperature(homog)%p(offset) - prm%T_ref)**1 / 1. * prm%expansion(1:3,1:3,1) + & ! constant coefficient
15780  (temperature(homog)%p(offset) - prm%T_ref)**2 / 2. * prm%expansion(1:3,1:3,2) + & ! linear coefficient
15781  (temperature(homog)%p(offset) - prm%T_ref)**3 / 3. * prm%expansion(1:3,1:3,3) ! quadratic coefficient
15782  end associate
15783 
15785 
15786 
15787 !--------------------------------------------------------------------------------------------------
15789 !--------------------------------------------------------------------------------------------------
15790 subroutine kinematics_thermal_expansion_lianditstangent(Li, dLi_dTstar, ipc, ip, el)
15792  integer, intent(in) :: &
15793  ipc, & !< grain number
15794  ip, & !< integration point number
15795  el
15796  real(preal), intent(out), dimension(3,3) :: &
15797  li
15798  real(preal), intent(out), dimension(3,3,3,3) :: &
15799  dli_dtstar
15800 
15801  integer :: &
15802  phase, &
15803  homog
15804  real(preal) :: &
15805  t, tdot
15806 
15807  phase = material_phaseat(ipc,el)
15808  homog = material_homogenizationat(el)
15809  t = temperature(homog)%p(thermalmapping(homog)%p(ip,el))
15810  tdot = temperaturerate(homog)%p(thermalmapping(homog)%p(ip,el))
15811 
15812  associate(prm => param(kinematics_thermal_expansion_instance(phase)))
15813  li = tdot * ( &
15814  prm%expansion(1:3,1:3,1)*(t - prm%T_ref)**0 & ! constant coefficient
15815  + prm%expansion(1:3,1:3,2)*(t - prm%T_ref)**1 & ! linear coefficient
15816  + prm%expansion(1:3,1:3,3)*(t - prm%T_ref)**2 & ! quadratic coefficient
15817  ) / &
15818  (1.0_preal &
15819  + prm%expansion(1:3,1:3,1)*(t - prm%T_ref)**1 / 1. &
15820  + prm%expansion(1:3,1:3,2)*(t - prm%T_ref)**2 / 2. &
15821  + prm%expansion(1:3,1:3,3)*(t - prm%T_ref)**3 / 3. &
15822  )
15823  end associate
15824  dli_dtstar = 0.0_preal
15825 
15827 
15829 # 36 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
15830 
15831 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive.f90" 1
15832 !--------------------------------------------------------------------------------------------------
15836 !--------------------------------------------------------------------------------------------------
15838  use prec
15839  use math
15840  use rotations
15841  use debug
15842  use numerics
15843  use io
15844  use config
15845  use material
15846  use results
15847  use lattice
15848  use discretization
15859 
15860  implicit none
15861  private
15862 
15863  integer, public, protected :: &
15866 
15867  interface
15868 
15869  module subroutine plastic_none_init
15870  end subroutine plastic_none_init
15871 
15872  module subroutine plastic_isotropic_init
15873  end subroutine plastic_isotropic_init
15874 
15875  module subroutine plastic_phenopowerlaw_init
15876  end subroutine plastic_phenopowerlaw_init
15877 
15878  module subroutine plastic_kinehardening_init
15879  end subroutine plastic_kinehardening_init
15880 
15881  module subroutine plastic_dislotwin_init
15882  end subroutine plastic_dislotwin_init
15883 
15884  module subroutine plastic_disloucla_init
15885  end subroutine plastic_disloucla_init
15886 
15887  module subroutine plastic_nonlocal_init
15888  end subroutine plastic_nonlocal_init
15889 
15890 
15891  module subroutine plastic_isotropic_lpanditstangent(lp,dlp_dmp,mp,instance,of)
15892  real(preal), dimension(3,3), intent(out) :: &
15893  lp
15894  real(preal), dimension(3,3,3,3), intent(out) :: &
15895  dlp_dmp
15896 
15897  real(preal), dimension(3,3), intent(in) :: &
15898  mp
15899  integer, intent(in) :: &
15900  instance, &
15901  of
15902  end subroutine plastic_isotropic_lpanditstangent
15903 
15904  pure module subroutine plastic_phenopowerlaw_lpanditstangent(lp,dlp_dmp,mp,instance,of)
15905  real(preal), dimension(3,3), intent(out) :: &
15906  lp
15907  real(preal), dimension(3,3,3,3), intent(out) :: &
15908  dlp_dmp
15909 
15910  real(preal), dimension(3,3), intent(in) :: &
15911  mp
15912  integer, intent(in) :: &
15913  instance, &
15914  of
15915  end subroutine plastic_phenopowerlaw_lpanditstangent
15916 
15917  pure module subroutine plastic_kinehardening_lpanditstangent(lp,dlp_dmp,mp,instance,of)
15918  real(preal), dimension(3,3), intent(out) :: &
15919  lp
15920  real(preal), dimension(3,3,3,3), intent(out) :: &
15921  dlp_dmp
15922 
15923  real(preal), dimension(3,3), intent(in) :: &
15924  mp
15925  integer, intent(in) :: &
15926  instance, &
15927  of
15928  end subroutine plastic_kinehardening_lpanditstangent
15929 
15930  module subroutine plastic_dislotwin_lpanditstangent(lp,dlp_dmp,mp,t,instance,of)
15931  real(preal), dimension(3,3), intent(out) :: &
15932  lp
15933  real(preal), dimension(3,3,3,3), intent(out) :: &
15934  dlp_dmp
15935 
15936  real(preal), dimension(3,3), intent(in) :: &
15937  mp
15938  real(preal), intent(in) :: &
15939  t
15940  integer, intent(in) :: &
15941  instance, &
15942  of
15943  end subroutine plastic_dislotwin_lpanditstangent
15944 
15945  pure module subroutine plastic_disloucla_lpanditstangent(lp,dlp_dmp,mp,t,instance,of)
15946  real(preal), dimension(3,3), intent(out) :: &
15947  lp
15948  real(preal), dimension(3,3,3,3), intent(out) :: &
15949  dlp_dmp
15950 
15951  real(preal), dimension(3,3), intent(in) :: &
15952  mp
15953  real(preal), intent(in) :: &
15954  t
15955  integer, intent(in) :: &
15956  instance, &
15957  of
15958  end subroutine plastic_disloucla_lpanditstangent
15959 
15960  module subroutine plastic_nonlocal_lpanditstangent(lp,dlp_dmp, &
15961  mp,temperature,instance,of,ip,el)
15962  real(preal), dimension(3,3), intent(out) :: &
15963  lp
15964  real(preal), dimension(3,3,3,3), intent(out) :: &
15965  dlp_dmp
15966 
15967  real(preal), dimension(3,3), intent(in) :: &
15968  mp
15969  real(preal), intent(in) :: &
15970  temperature
15971  integer, intent(in) :: &
15972  instance, &
15973  of, &
15974  ip, & !< current integration point
15975  el
15976  end subroutine plastic_nonlocal_lpanditstangent
15977 
15978 
15979  module subroutine plastic_isotropic_lianditstangent(li,dli_dmi,mi,instance,of)
15980  real(preal), dimension(3,3), intent(out) :: &
15981  li
15982  real(preal), dimension(3,3,3,3), intent(out) :: &
15983  dli_dmi
15984 
15985  real(preal), dimension(3,3), intent(in) :: &
15986  mi
15987  integer, intent(in) :: &
15988  instance, &
15989  of
15990  end subroutine plastic_isotropic_lianditstangent
15991 
15992 
15993  module subroutine plastic_isotropic_dotstate(mp,instance,of)
15994  real(preal), dimension(3,3), intent(in) :: &
15995  mp
15996  integer, intent(in) :: &
15997  instance, &
15998  of
15999  end subroutine plastic_isotropic_dotstate
16000 
16001  module subroutine plastic_phenopowerlaw_dotstate(mp,instance,of)
16002  real(preal), dimension(3,3), intent(in) :: &
16003  mp
16004  integer, intent(in) :: &
16005  instance, &
16006  of
16007  end subroutine plastic_phenopowerlaw_dotstate
16008 
16009  module subroutine plastic_kinehardening_dotstate(mp,instance,of)
16010  real(preal), dimension(3,3), intent(in) :: &
16011  mp
16012  integer, intent(in) :: &
16013  instance, &
16014  of
16015  end subroutine plastic_kinehardening_dotstate
16016 
16017  module subroutine plastic_dislotwin_dotstate(mp,t,instance,of)
16018  real(preal), dimension(3,3), intent(in) :: &
16019  mp
16020  real(preal), intent(in) :: &
16021  t
16022  integer, intent(in) :: &
16023  instance, &
16024  of
16025  end subroutine plastic_dislotwin_dotstate
16026 
16027  module subroutine plastic_disloucla_dotstate(mp,t,instance,of)
16028  real(preal), dimension(3,3), intent(in) :: &
16029  mp
16030  real(preal), intent(in) :: &
16031  t
16032  integer, intent(in) :: &
16033  instance, &
16034  of
16035  end subroutine plastic_disloucla_dotstate
16036 
16037  module subroutine plastic_nonlocal_dotstate(mp, f, fp, temperature,timestep, &
16038  instance,of,ip,el)
16039  real(preal), dimension(3,3), intent(in) ::&
16040  mp
16041  real(preal), dimension(3,3,homogenization_maxNgrains,discretization_nIP,discretization_nElem), intent(in) :: &
16042  f, & !< deformation gradient
16043  fp
16044  real(preal), intent(in) :: &
16045  temperature, & !< temperature
16046  timestep
16047  integer, intent(in) :: &
16048  instance, &
16049  of, &
16050  ip, & !< current integration point
16051  el
16052  end subroutine plastic_nonlocal_dotstate
16053 
16054 
16055  module subroutine plastic_dislotwin_dependentstate(t,instance,of)
16056  integer, intent(in) :: &
16057  instance, &
16058  of
16059  real(preal), intent(in) :: &
16060  t
16061  end subroutine plastic_dislotwin_dependentstate
16062 
16063  module subroutine plastic_disloucla_dependentstate(instance,of)
16064  integer, intent(in) :: &
16065  instance, &
16066  of
16067  end subroutine plastic_disloucla_dependentstate
16068 
16069  module subroutine plastic_nonlocal_dependentstate(f, fp, instance, of, ip, el)
16070  real(preal), dimension(3,3), intent(in) :: &
16071  f, &
16072  fp
16073  integer, intent(in) :: &
16074  instance, &
16075  of, &
16076  ip, &
16077  el
16078  end subroutine plastic_nonlocal_dependentstate
16079 
16080 
16081  module subroutine plastic_kinehardening_deltastate(mp,instance,of)
16082  real(preal), dimension(3,3), intent(in) :: &
16083  mp
16084  integer, intent(in) :: &
16085  instance, &
16086  of
16087  end subroutine plastic_kinehardening_deltastate
16088 
16089  module subroutine plastic_nonlocal_deltastate(mp,instance,of,ip,el)
16090  real(preal), dimension(3,3), intent(in) :: &
16091  mp
16092  integer, intent(in) :: &
16093  instance, &
16094  of, &
16095  ip, &
16096  el
16097  end subroutine plastic_nonlocal_deltastate
16098 
16099 
16100  module function plastic_dislotwin_homogenizedc(ipc,ip,el) result(homogenizedc)
16101  real(preal), dimension(6,6) :: &
16102  homogenizedc
16103  integer, intent(in) :: &
16104  ipc, & !< component-ID of integration point
16105  ip, & !< integration point
16106  el
16107  end function plastic_dislotwin_homogenizedc
16108 
16109  module subroutine plastic_nonlocal_updatecompatibility(orientation,instance,i,e)
16110  integer, intent(in) :: &
16111  instance, &
16112  i, &
16113  e
16114  type(rotation), dimension(1,discretization_nIP,discretization_nElem), intent(in) :: &
16115  orientation
16116  end subroutine plastic_nonlocal_updatecompatibility
16117 
16118 
16119  module subroutine plastic_isotropic_results(instance,group)
16120  integer, intent(in) :: instance
16121  character(len=*), intent(in) :: group
16122  end subroutine plastic_isotropic_results
16123 
16124  module subroutine plastic_phenopowerlaw_results(instance,group)
16125  integer, intent(in) :: instance
16126  character(len=*), intent(in) :: group
16127  end subroutine plastic_phenopowerlaw_results
16128 
16129  module subroutine plastic_kinehardening_results(instance,group)
16130  integer, intent(in) :: instance
16131  character(len=*), intent(in) :: group
16132  end subroutine plastic_kinehardening_results
16133 
16134  module subroutine plastic_dislotwin_results(instance,group)
16135  integer, intent(in) :: instance
16136  character(len=*), intent(in) :: group
16137  end subroutine plastic_dislotwin_results
16138 
16139  module subroutine plastic_disloucla_results(instance,group)
16140  integer, intent(in) :: instance
16141  character(len=*), intent(in) :: group
16142  end subroutine plastic_disloucla_results
16143 
16144  module subroutine plastic_nonlocal_results(instance,group)
16145  integer, intent(in) :: instance
16146  character(len=*), intent(in) :: group
16147  end subroutine plastic_nonlocal_results
16148 
16149  end interface
16150 
16151  public :: &
16152  plastic_nonlocal_updatecompatibility, &
16153  constitutive_init, &
16154  constitutive_homogenizedc, &
16155  constitutive_dependentstate, &
16156  constitutive_lpanditstangents, &
16157  constitutive_lianditstangents, &
16158  constitutive_initialfi, &
16159  constitutive_sanditstangents, &
16160  constitutive_collectdotstate, &
16161  constitutive_collectdeltastate, &
16162  constitutive_results
16163 
16164 contains
16165 
16166 
16167 !--------------------------------------------------------------------------------------------------
16169 !--------------------------------------------------------------------------------------------------
16170 subroutine constitutive_init
16172  integer :: &
16173  ph, & !< counter in phase loop
16174  s
16175 
16176 !--------------------------------------------------------------------------------------------------
16177 ! initialized plasticity
16178  if (any(phase_plasticity == plasticity_none_id)) call plastic_none_init
16179  if (any(phase_plasticity == plasticity_isotropic_id)) call plastic_isotropic_init
16180  if (any(phase_plasticity == plasticity_phenopowerlaw_id)) call plastic_phenopowerlaw_init
16181  if (any(phase_plasticity == plasticity_kinehardening_id)) call plastic_kinehardening_init
16182  if (any(phase_plasticity == plasticity_dislotwin_id)) call plastic_dislotwin_init
16183  if (any(phase_plasticity == plasticity_disloucla_id)) call plastic_disloucla_init
16184  if (any(phase_plasticity == plasticity_nonlocal_id)) then
16185  call plastic_nonlocal_init
16186  else
16188  endif
16189 !--------------------------------------------------------------------------------------------------
16190 ! initialize source mechanisms
16197 
16198 !--------------------------------------------------------------------------------------------------
16199 ! initialize kinematic mechanisms
16203 
16204  write(6,'(/,a)') ' <<<+- constitutive init -+>>>'; flush(6)
16205 
16206  constitutive_source_maxsizedotstate = 0
16207  phaseloop2:do ph = 1,material_nphase
16208 !--------------------------------------------------------------------------------------------------
16209 ! partition and inititalize state
16210  plasticstate(ph)%partionedState0 = plasticstate(ph)%state0
16211  plasticstate(ph)%state = plasticstate(ph)%partionedState0
16212  forall(s = 1:phase_nsources(ph))
16213  sourcestate(ph)%p(s)%partionedState0 = sourcestate(ph)%p(s)%state0
16214  sourcestate(ph)%p(s)%state = sourcestate(ph)%p(s)%partionedState0
16215  end forall
16216 !--------------------------------------------------------------------------------------------------
16217 ! determine max size of source state
16218  constitutive_source_maxsizedotstate = max(constitutive_source_maxsizedotstate, &
16219  maxval(sourcestate(ph)%p%sizeDotState))
16220  enddo phaseloop2
16221  constitutive_plasticity_maxsizedotstate = maxval(plasticstate%sizeDotState)
16222 
16223 end subroutine constitutive_init
16224 
16225 
16226 !--------------------------------------------------------------------------------------------------
16229 !--------------------------------------------------------------------------------------------------
16230 function constitutive_homogenizedc(ipc,ip,el)
16232  real(preal), dimension(6,6) :: constitutive_homogenizedc
16233  integer, intent(in) :: &
16234  ipc, & !< component-ID of integration point
16235  ip, & !< integration point
16236  el
16237 
16238  plasticitytype: select case (phase_plasticity(material_phaseat(ipc,el)))
16239  case (plasticity_dislotwin_id) plasticitytype
16240  constitutive_homogenizedc = plastic_dislotwin_homogenizedc(ipc,ip,el)
16241  case default plasticitytype
16242  constitutive_homogenizedc = lattice_c66(1:6,1:6,material_phaseat(ipc,el))
16243  end select plasticitytype
16244 
16245 end function constitutive_homogenizedc
16246 
16247 
16248 !--------------------------------------------------------------------------------------------------
16250 !--------------------------------------------------------------------------------------------------
16251 subroutine constitutive_dependentstate(F, Fp, ipc, ip, el)
16253  integer, intent(in) :: &
16254  ipc, & !< component-ID of integration point
16255  ip, & !< integration point
16256  el
16257  real(preal), intent(in), dimension(3,3) :: &
16258  f, & !< elastic deformation gradient
16259  fp
16260  integer :: &
16261  ho, & !< homogenization
16262  tme, & !< thermal member position
16263  instance, of
16264 
16265  ho = material_homogenizationat(el)
16266  tme = thermalmapping(ho)%p(ip,el)
16267  of = material_phasememberat(ipc,ip,el)
16268  instance = phase_plasticityinstance(material_phaseat(ipc,el))
16269 
16270  plasticitytype: select case (phase_plasticity(material_phaseat(ipc,el)))
16271  case (plasticity_dislotwin_id) plasticitytype
16272  call plastic_dislotwin_dependentstate(temperature(ho)%p(tme),instance,of)
16273  case (plasticity_disloucla_id) plasticitytype
16274  call plastic_disloucla_dependentstate(instance,of)
16275  case (plasticity_nonlocal_id) plasticitytype
16276  call plastic_nonlocal_dependentstate (f,fp,instance,of,ip,el)
16277  end select plasticitytype
16278 
16279 end subroutine constitutive_dependentstate
16280 
16281 
16282 !--------------------------------------------------------------------------------------------------
16284 ! ToDo: Discuss wheter it makes sense if crystallite handles the configuration conversion, i.e.
16285 ! Mp in, dLp_dMp out
16286 !--------------------------------------------------------------------------------------------------
16287 subroutine constitutive_lpanditstangents(Lp, dLp_dS, dLp_dFi, &
16288  S, Fi, ipc, ip, el)
16289  integer, intent(in) :: &
16290  ipc, & !< component-ID of integration point
16291  ip, & !< integration point
16292  el
16293  real(preal), intent(in), dimension(3,3) :: &
16294  s, & !< 2nd Piola-Kirchhoff stress
16295  fi
16296  real(preal), intent(out), dimension(3,3) :: &
16297  lp
16298  real(preal), intent(out), dimension(3,3,3,3) :: &
16299  dlp_ds, &
16300  dlp_dfi
16301  real(preal), dimension(3,3,3,3) :: &
16302  dlp_dmp
16303  real(preal), dimension(3,3) :: &
16304  mp
16305  integer :: &
16306  ho, & !< homogenization
16307  tme
16308  integer :: &
16309  i, j, instance, of
16310 
16311  ho = material_homogenizationat(el)
16312  tme = thermalmapping(ho)%p(ip,el)
16313 
16314  mp = matmul(matmul(transpose(fi),fi),s)
16315  of = material_phasememberat(ipc,ip,el)
16316  instance = phase_plasticityinstance(material_phaseat(ipc,el))
16317 
16318  plasticitytype: select case (phase_plasticity(material_phaseat(ipc,el)))
16319 
16320  case (plasticity_none_id) plasticitytype
16321  lp = 0.0_preal
16322  dlp_dmp = 0.0_preal
16323 
16324  case (plasticity_isotropic_id) plasticitytype
16325  call plastic_isotropic_lpanditstangent (lp,dlp_dmp,mp,instance,of)
16326 
16327  case (plasticity_phenopowerlaw_id) plasticitytype
16328  call plastic_phenopowerlaw_lpanditstangent(lp,dlp_dmp,mp,instance,of)
16329 
16330  case (plasticity_kinehardening_id) plasticitytype
16331  call plastic_kinehardening_lpanditstangent(lp,dlp_dmp,mp,instance,of)
16332 
16333  case (plasticity_nonlocal_id) plasticitytype
16334  call plastic_nonlocal_lpanditstangent (lp,dlp_dmp,mp, temperature(ho)%p(tme),instance,of,ip,el)
16335 
16336  case (plasticity_dislotwin_id) plasticitytype
16337  call plastic_dislotwin_lpanditstangent (lp,dlp_dmp,mp,temperature(ho)%p(tme),instance,of)
16338 
16339  case (plasticity_disloucla_id) plasticitytype
16340  call plastic_disloucla_lpanditstangent (lp,dlp_dmp,mp,temperature(ho)%p(tme),instance,of)
16341 
16342  end select plasticitytype
16343 
16344  do i=1,3; do j=1,3
16345  dlp_dfi(i,j,1:3,1:3) = matmul(matmul(fi,s),transpose(dlp_dmp(i,j,1:3,1:3))) + &
16346  matmul(matmul(fi,dlp_dmp(i,j,1:3,1:3)),s)
16347  dlp_ds(i,j,1:3,1:3) = matmul(matmul(transpose(fi),fi),dlp_dmp(i,j,1:3,1:3)) ! ToDo: @PS: why not: dLp_dMp:(FiT Fi)
16348  enddo; enddo
16349 
16350 end subroutine constitutive_lpanditstangents
16351 
16352 
16353 !--------------------------------------------------------------------------------------------------
16355 ! ToDo: MD: S is Mi?
16356 !--------------------------------------------------------------------------------------------------
16357 subroutine constitutive_lianditstangents(Li, dLi_dS, dLi_dFi, &
16358  S, Fi, ipc, ip, el)
16360  integer, intent(in) :: &
16361  ipc, & !< component-ID of integration point
16362  ip, & !< integration point
16363  el
16364  real(preal), intent(in), dimension(3,3) :: &
16365  s
16366  real(preal), intent(in), dimension(3,3) :: &
16367  fi
16368  real(preal), intent(out), dimension(3,3) :: &
16369  li
16370  real(preal), intent(out), dimension(3,3,3,3) :: &
16371  dli_ds, & !< derivative of Li with respect to S
16372  dli_dfi
16373 
16374  real(preal), dimension(3,3) :: &
16375  my_li, & !< intermediate velocity gradient
16376  fiinv, &
16377  temp_33
16378  real(preal), dimension(3,3,3,3) :: &
16379  my_dli_ds
16380  real(preal) :: &
16381  detfi
16382  integer :: &
16383  k, i, j, &
16384  instance, of
16385 
16386  li = 0.0_preal
16387  dli_ds = 0.0_preal
16388  dli_dfi = 0.0_preal
16389 
16390  plasticitytype: select case (phase_plasticity(material_phaseat(ipc,el)))
16391  case (plasticity_isotropic_id) plasticitytype
16392  of = material_phasememberat(ipc,ip,el)
16393  instance = phase_plasticityinstance(material_phaseat(ipc,el))
16394  call plastic_isotropic_lianditstangent(my_li, my_dli_ds, s ,instance,of)
16395  case default plasticitytype
16396  my_li = 0.0_preal
16397  my_dli_ds = 0.0_preal
16398  end select plasticitytype
16399 
16400  li = li + my_li
16401  dli_ds = dli_ds + my_dli_ds
16402 
16403  kinematicsloop: do k = 1, phase_nkinematics(material_phaseat(ipc,el))
16404  kinematicstype: select case (phase_kinematics(k,material_phaseat(ipc,el)))
16405  case (kinematics_cleavage_opening_id) kinematicstype
16406  call kinematics_cleavage_opening_lianditstangent(my_li, my_dli_ds, s, ipc, ip, el)
16407  case (kinematics_slipplane_opening_id) kinematicstype
16408  call kinematics_slipplane_opening_lianditstangent(my_li, my_dli_ds, s, ipc, ip, el)
16409  case (kinematics_thermal_expansion_id) kinematicstype
16410  call kinematics_thermal_expansion_lianditstangent(my_li, my_dli_ds, ipc, ip, el)
16411  case default kinematicstype
16412  my_li = 0.0_preal
16413  my_dli_ds = 0.0_preal
16414  end select kinematicstype
16415  li = li + my_li
16416  dli_ds = dli_ds + my_dli_ds
16417  enddo kinematicsloop
16418 
16419  fiinv = math_inv33(fi)
16420  detfi = math_det33(fi)
16421  li = matmul(matmul(fi,li),fiinv)*detfi
16422  temp_33 = matmul(fiinv,li)
16423 
16424  do i = 1,3; do j = 1,3
16425  dli_ds(1:3,1:3,i,j) = matmul(matmul(fi,dli_ds(1:3,1:3,i,j)),fiinv)*detfi
16426  dli_dfi(1:3,1:3,i,j) = dli_dfi(1:3,1:3,i,j) + li*fiinv(j,i)
16427  dli_dfi(1:3,i,1:3,j) = dli_dfi(1:3,i,1:3,j) + math_i3*temp_33(j,i) + li*fiinv(j,i)
16428  enddo; enddo
16429 
16430 end subroutine constitutive_lianditstangents
16431 
16432 
16433 !--------------------------------------------------------------------------------------------------
16435 !--------------------------------------------------------------------------------------------------
16436 pure function constitutive_initialfi(ipc, ip, el)
16438  integer, intent(in) :: &
16439  ipc, & !< component-ID of integration point
16440  ip, & !< integration point
16441  el
16442  real(preal), dimension(3,3) :: &
16443  constitutive_initialfi
16444  integer :: &
16445  k
16446  integer :: &
16447  phase, &
16448  homog, offset
16449 
16450  constitutive_initialfi = math_i3
16451  phase = material_phaseat(ipc,el)
16452 
16453  kinematicsloop: do k = 1, phase_nkinematics(phase)
16454  kinematicstype: select case (phase_kinematics(k,phase))
16455  case (kinematics_thermal_expansion_id) kinematicstype
16456  homog = material_homogenizationat(el)
16457  offset = thermalmapping(homog)%p(ip,el)
16458  constitutive_initialfi = &
16459  constitutive_initialfi + kinematics_thermal_expansion_initialstrain(homog,phase,offset)
16460  end select kinematicstype
16461  enddo kinematicsloop
16462 
16463 end function constitutive_initialfi
16464 
16465 
16466 !--------------------------------------------------------------------------------------------------
16470 !--------------------------------------------------------------------------------------------------
16471 subroutine constitutive_sanditstangents(S, dS_dFe, dS_dFi, Fe, Fi, ipc, ip, el)
16473  integer, intent(in) :: &
16474  ipc, & !< component-ID of integration point
16475  ip, & !< integration point
16476  el
16477  real(preal), intent(in), dimension(3,3) :: &
16478  fe, & !< elastic deformation gradient
16479  fi
16480  real(preal), intent(out), dimension(3,3) :: &
16481  s
16482  real(preal), intent(out), dimension(3,3,3,3) :: &
16483  ds_dfe, & !< derivative of 2nd P-K stress with respect to elastic deformation gradient
16484  ds_dfi
16485 
16486  call constitutive_hooke_sanditstangents(s, ds_dfe, ds_dfi, fe, fi, ipc, ip, el)
16487 
16488 
16489 end subroutine constitutive_sanditstangents
16490 
16491 
16492 !--------------------------------------------------------------------------------------------------
16495 !--------------------------------------------------------------------------------------------------
16496 subroutine constitutive_hooke_sanditstangents(S, dS_dFe, dS_dFi, &
16497  Fe, Fi, ipc, ip, el)
16499  integer, intent(in) :: &
16500  ipc, & !< component-ID of integration point
16501  ip, & !< integration point
16502  el
16503  real(pReal), intent(in), dimension(3,3) :: &
16504  Fe, & !< elastic deformation gradient
16505  Fi
16506  real(pReal), intent(out), dimension(3,3) :: &
16507  S
16508  real(pReal), intent(out), dimension(3,3,3,3) :: &
16509  dS_dFe, & !< derivative of 2nd P-K stress with respect to elastic deformation gradient
16510  dS_dFi
16511  real(pReal), dimension(3,3) :: E
16512  real(pReal), dimension(3,3,3,3) :: C
16513  integer :: &
16514  ho, & !< homogenization
16515  d
16516  integer :: &
16517  i, j
16518 
16519  ho = material_homogenizationat(el)
16520  c = math_66tosym3333(constitutive_homogenizedc(ipc,ip,el))
16521 
16522  degradationloop: do d = 1, phase_nstiffnessdegradations(material_phaseat(ipc,el))
16523  degradationtype: select case(phase_stiffnessdegradation(d,material_phaseat(ipc,el)))
16524  case (stiffness_degradation_damage_id) degradationtype
16525  c = c * damage(ho)%p(damagemapping(ho)%p(ip,el))**2
16526  end select degradationtype
16527  enddo degradationloop
16528 
16529  e = 0.5_preal*(matmul(transpose(fe),fe)-math_i3)
16530  s = math_mul3333xx33(c,matmul(matmul(transpose(fi),e),fi))
16531 
16532  do i =1, 3;do j=1,3
16533  ds_dfe(i,j,1:3,1:3) = matmul(fe,matmul(matmul(fi,c(i,j,1:3,1:3)),transpose(fi)))
16534  ds_dfi(i,j,1:3,1:3) = 2.0_preal*matmul(matmul(e,fi),c(i,j,1:3,1:3))
16535  enddo; enddo
16536 
16537 end subroutine constitutive_hooke_sanditstangents
16538 
16539 
16540 !--------------------------------------------------------------------------------------------------
16542 !--------------------------------------------------------------------------------------------------
16543 subroutine constitutive_collectdotstate(S, FArray, Fi, FpArray, subdt, ipc, ip, el)
16545  integer, intent(in) :: &
16546  ipc, & !< component-ID of integration point
16547  ip, & !< integration point
16548  el
16549  real(preal), intent(in) :: &
16550  subdt
16551  real(preal), intent(in), dimension(3,3,homogenization_maxNgrains,discretization_nIP,discretization_nElem) :: &
16552  farray, & !< elastic deformation gradient
16553  fparray
16554  real(preal), intent(in), dimension(3,3) :: &
16555  fi
16556  real(preal), intent(in), dimension(3,3) :: &
16557  s
16558  real(preal), dimension(3,3) :: &
16559  mp
16560  integer :: &
16561  ho, & !< homogenization
16562  tme, & !< thermal member position
16563  i, & !< counter in source loop
16564  instance, of
16565 
16566  ho = material_homogenizationat(el)
16567  tme = thermalmapping(ho)%p(ip,el)
16568  of = material_phasememberat(ipc,ip,el)
16569  instance = phase_plasticityinstance(material_phaseat(ipc,el))
16570 
16571  mp = matmul(matmul(transpose(fi),fi),s)
16572 
16573  plasticitytype: select case (phase_plasticity(material_phaseat(ipc,el)))
16574 
16575  case (plasticity_isotropic_id) plasticitytype
16576  call plastic_isotropic_dotstate (mp,instance,of)
16577 
16578  case (plasticity_phenopowerlaw_id) plasticitytype
16579  call plastic_phenopowerlaw_dotstate(mp,instance,of)
16580 
16581  case (plasticity_kinehardening_id) plasticitytype
16582  call plastic_kinehardening_dotstate(mp,instance,of)
16583 
16584  case (plasticity_dislotwin_id) plasticitytype
16585  call plastic_dislotwin_dotstate (mp,temperature(ho)%p(tme),instance,of)
16586 
16587  case (plasticity_disloucla_id) plasticitytype
16588  call plastic_disloucla_dotstate (mp,temperature(ho)%p(tme),instance,of)
16589 
16590  case (plasticity_nonlocal_id) plasticitytype
16591  call plastic_nonlocal_dotstate (mp,farray,fparray,temperature(ho)%p(tme),subdt, &
16592  instance,of,ip,el)
16593  end select plasticitytype
16594 
16595  sourceloop: do i = 1, phase_nsources(material_phaseat(ipc,el))
16596 
16597  sourcetype: select case (phase_source(i,material_phaseat(ipc,el)))
16598 
16599  case (source_damage_anisobrittle_id) sourcetype
16600  call source_damage_anisobrittle_dotstate (s, ipc, ip, el)
16601 
16602  case (source_damage_isoductile_id) sourcetype
16603  call source_damage_isoductile_dotstate ( ipc, ip, el)
16604 
16605  case (source_damage_anisoductile_id) sourcetype
16606  call source_damage_anisoductile_dotstate ( ipc, ip, el)
16607 
16608  case (source_thermal_externalheat_id) sourcetype
16610 
16611  end select sourcetype
16612 
16613  enddo sourceloop
16614 
16615 end subroutine constitutive_collectdotstate
16616 
16617 
16618 !--------------------------------------------------------------------------------------------------
16621 !--------------------------------------------------------------------------------------------------
16622 subroutine constitutive_collectdeltastate(S, Fe, Fi, ipc, ip, el)
16624  integer, intent(in) :: &
16625  ipc, & !< component-ID of integration point
16626  ip, & !< integration point
16627  el
16628  real(preal), intent(in), dimension(3,3) :: &
16629  s, & !< 2nd Piola Kirchhoff stress
16630  fe, & !< elastic deformation gradient
16631  fi
16632  real(preal), dimension(3,3) :: &
16633  mp
16634  integer :: &
16635  i, &
16636  instance, of
16637 
16638  mp = matmul(matmul(transpose(fi),fi),s)
16639  of = material_phasememberat(ipc,ip,el)
16640  instance = phase_plasticityinstance(material_phaseat(ipc,el))
16641 
16642  plasticitytype: select case (phase_plasticity(material_phaseat(ipc,el)))
16643 
16644  case (plasticity_kinehardening_id) plasticitytype
16645  call plastic_kinehardening_deltastate(mp,instance,of)
16646 
16647  case (plasticity_nonlocal_id) plasticitytype
16648  call plastic_nonlocal_deltastate(mp,instance,of,ip,el)
16649 
16650  end select plasticitytype
16651 
16652  sourceloop: do i = 1, phase_nsources(material_phaseat(ipc,el))
16653 
16654  sourcetype: select case (phase_source(i,material_phaseat(ipc,el)))
16655 
16656  case (source_damage_isobrittle_id) sourcetype
16657  call source_damage_isobrittle_deltastate (constitutive_homogenizedc(ipc,ip,el), fe, &
16658  ipc, ip, el)
16659 
16660  end select sourcetype
16661 
16662  enddo sourceloop
16663 
16664 end subroutine constitutive_collectdeltastate
16665 
16666 
16667 !--------------------------------------------------------------------------------------------------
16669 !--------------------------------------------------------------------------------------------------
16670 subroutine constitutive_results
16672  integer :: p
16673  character(len=pStringLen) :: group
16674  do p=1,size(config_name_phase)
16675  group = trim('current/constituent')//'/'//trim(config_name_phase(p))
16677 
16678  group = trim(group)//'/plastic'
16679 
16681  select case(phase_plasticity(p))
16682 
16684  call plastic_isotropic_results(phase_plasticityinstance(p),group)
16685 
16687  call plastic_phenopowerlaw_results(phase_plasticityinstance(p),group)
16688 
16690  call plastic_kinehardening_results(phase_plasticityinstance(p),group)
16691 
16693  call plastic_dislotwin_results(phase_plasticityinstance(p),group)
16694 
16696  call plastic_disloucla_results(phase_plasticityinstance(p),group)
16697 
16699  call plastic_nonlocal_results(phase_plasticityinstance(p),group)
16700  end select
16701 
16702  enddo
16703 
16704 end subroutine constitutive_results
16705 
16706 end module constitutive
16707 # 37 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
16708 
16709 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_none.f90" 1
16710 !--------------------------------------------------------------------------------------------------
16715 !--------------------------------------------------------------------------------------------------
16716 submodule(constitutive) plastic_none
16717 
16718 contains
16719 
16720 !--------------------------------------------------------------------------------------------------
16723 !--------------------------------------------------------------------------------------------------
16724 module subroutine plastic_none_init
16725 
16726  integer :: &
16727  ninstance, &
16728  p, &
16729  nipcmyphase
16730 
16731  write(6,'(/,a)') ' <<<+- plastic_'//plasticity_none_label//' init -+>>>'; flush(6)
16732 
16733  ninstance = count(phase_plasticity == plasticity_none_id)
16734  if (iand(debug_level(debug_constitutive),debug_levelbasic) /= 0) &
16735  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
16736 
16737  do p = 1, size(phase_plasticity)
16738  if (phase_plasticity(p) /= plasticity_none_id) cycle
16739 
16740  nipcmyphase = count(material_phaseat == p) * discretization_nip
16741  call material_allocateplasticstate(p,nipcmyphase,0,0,0)
16742 
16743  enddo
16744 
16745 end subroutine plastic_none_init
16746 
16747 end submodule plastic_none
16748 # 38 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
16749 
16750 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_isotropic.f90" 1
16751 !--------------------------------------------------------------------------------------------------
16759 !--------------------------------------------------------------------------------------------------
16760 submodule(constitutive) plastic_isotropic
16761 
16762  type :: tparameters
16763  real(preal) :: &
16764  m, & !< Taylor factor
16765  dot_gamma_0, & !< reference strain rate
16766  n, & !< stress exponent
16767  h0, &
16768  h_ln, &
16769  xi_inf, & !< maximum critical stress
16770  a, &
16771  c_1, &
16772  c_4, &
16773  c_3, &
16774  c_2
16775  integer :: &
16776  of_debug = 0
16777  logical :: &
16778  dilatation
16779  character(len=pStringLen), allocatable, dimension(:) :: &
16780  output
16781  end type tparameters
16782 
16783  type :: tisotropicstate
16784  real(preal), pointer, dimension(:) :: &
16785  xi, &
16786  gamma
16787  end type tisotropicstate
16788 
16789 !--------------------------------------------------------------------------------------------------
16790 ! containers for parameters and state
16791  type(tparameters), allocatable, dimension(:) :: param
16792  type(tisotropicstate), allocatable, dimension(:) :: &
16793  dotstate, &
16794  state
16795 
16796 contains
16797 
16798 !--------------------------------------------------------------------------------------------------
16801 !--------------------------------------------------------------------------------------------------
16802 module subroutine plastic_isotropic_init
16803 
16804  integer :: &
16805  ninstance, &
16806  p, &
16807  nipcmyphase, &
16808  sizestate, sizedotstate
16809  real(preal) :: &
16810  xi_0
16811  character(len=pStringLen) :: &
16812  extmsg = ''
16813 
16814  write(6,'(/,a)') ' <<<+- plastic_'//plasticity_isotropic_label//' init -+>>>'; flush(6)
16815 
16816  write(6,'(/,a)') ' Maiti and Eisenlohr, Scripta Materialia 145:37–40, 2018'
16817  write(6,'(a)') ' https://doi.org/10.1016/j.scriptamat.2017.09.047'
16818 
16819  ninstance = count(phase_plasticity == plasticity_isotropic_id)
16820  if (iand(debug_level(debug_constitutive),debug_levelbasic) /= 0) &
16821  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
16822 
16823  allocate(param(ninstance))
16824  allocate(state(ninstance))
16825  allocate(dotstate(ninstance))
16826 
16827  do p = 1, size(phase_plasticity)
16828  if (phase_plasticity(p) /= plasticity_isotropic_id) cycle
16829  associate(prm => param(phase_plasticityinstance(p)), &
16830  dot => dotstate(phase_plasticityinstance(p)), &
16831  stt => state(phase_plasticityinstance(p)), &
16832  config => config_phase(p))
16833 
16834  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
16835 
16836 
16837 
16838 
16839 
16840 
16841  xi_0 = config%getFloat('tau0')
16842  prm%xi_inf = config%getFloat('tausat')
16843  prm%dot_gamma_0 = config%getFloat('gdot0')
16844  prm%n = config%getFloat('n')
16845  prm%h0 = config%getFloat('h0')
16846  prm%M = config%getFloat('m')
16847  prm%h_ln = config%getFloat('h0_slopelnrate', defaultval=0.0_preal)
16848  prm%c_1 = config%getFloat('tausat_sinhfita',defaultval=0.0_preal)
16849  prm%c_4 = config%getFloat('tausat_sinhfitb',defaultval=0.0_preal)
16850  prm%c_3 = config%getFloat('tausat_sinhfitc',defaultval=0.0_preal)
16851  prm%c_2 = config%getFloat('tausat_sinhfitd',defaultval=0.0_preal)
16852  prm%a = config%getFloat('a')
16853 
16854  prm%dilatation = config%keyExists('/dilatation/')
16855 
16856 !--------------------------------------------------------------------------------------------------
16857 ! sanity checks
16858  if (xi_0 < 0.0_preal) extmsg = trim(extmsg)//' xi_0'
16859  if (prm%dot_gamma_0 <= 0.0_preal) extmsg = trim(extmsg)//' dot_gamma_0'
16860  if (prm%n <= 0.0_preal) extmsg = trim(extmsg)//' n'
16861  if (prm%a <= 0.0_preal) extmsg = trim(extmsg)//' a'
16862  if (prm%M <= 0.0_preal) extmsg = trim(extmsg)//' M'
16863 
16864 !--------------------------------------------------------------------------------------------------
16865 ! allocate state arrays
16866  nipcmyphase = count(material_phaseat == p) * discretization_nip
16867  sizedotstate = size(['xi ','accumulated_shear'])
16868  sizestate = sizedotstate
16869 
16870  call material_allocateplasticstate(p,nipcmyphase,sizestate,sizedotstate,0)
16871 
16872 !--------------------------------------------------------------------------------------------------
16873 ! state aliases and initialization
16874  stt%xi => plasticstate(p)%state (1,:)
16875  stt%xi = xi_0
16876  dot%xi => plasticstate(p)%dotState(1,:)
16877  plasticstate(p)%atol(1) = config%getFloat('atol_xi',defaultval=1.0_preal)
16878  if (plasticstate(p)%atol(1) < 0.0_preal) extmsg = trim(extmsg)//' atol_xi'
16879 
16880  stt%gamma => plasticstate(p)%state (2,:)
16881  dot%gamma => plasticstate(p)%dotState(2,:)
16882  plasticstate(p)%atol(2) = config%getFloat('atol_gamma',defaultval=1.0e-6_preal)
16883  if (plasticstate(p)%atol(2) < 0.0_preal) extmsg = trim(extmsg)//' atol_gamma'
16884  ! global alias
16885  plasticstate(p)%slipRate => plasticstate(p)%dotState(2:2,:)
16886 
16887  plasticstate(p)%state0 = plasticstate(p)%state ! ToDo: this could be done centrally
16888 
16889  end associate
16890 
16891 !--------------------------------------------------------------------------------------------------
16892 ! exit if any parameter is out of range
16893  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//plasticity_isotropic_label//')')
16894 
16895  enddo
16896 
16897 end subroutine plastic_isotropic_init
16898 
16899 
16900 !--------------------------------------------------------------------------------------------------
16902 !--------------------------------------------------------------------------------------------------
16903 module subroutine plastic_isotropic_lpanditstangent(lp,dlp_dmp,mp,instance,of)
16904 
16905  real(preal), dimension(3,3), intent(out) :: &
16906  lp
16907  real(preal), dimension(3,3,3,3), intent(out) :: &
16908  dlp_dmp
16909 
16910  real(preal), dimension(3,3), intent(in) :: &
16911  mp
16912  integer, intent(in) :: &
16913  instance, &
16914  of
16915 
16916  real(preal), dimension(3,3) :: &
16917  mp_dev
16918  real(preal) :: &
16919  dot_gamma, & !< strainrate
16920  norm_mp_dev, & !< norm of the deviatoric part of the Mandel stress
16921  squarenorm_mp_dev
16922  integer :: &
16923  k, l, m, n
16924 
16925  associate(prm => param(instance), stt => state(instance))
16926 
16927  mp_dev = math_deviatoric33(mp)
16928  squarenorm_mp_dev = math_tensordot(mp_dev,mp_dev)
16929  norm_mp_dev = sqrt(squarenorm_mp_dev)
16930 
16931  if (norm_mp_dev > 0.0_preal) then
16932  dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_preal) * norm_mp_dev/(prm%M*stt%xi(of))) **prm%n
16933 
16934  lp = dot_gamma/prm%M * mp_dev/norm_mp_dev
16935 # 194 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_isotropic.f90"
16936  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
16937  dlp_dmp(k,l,m,n) = (prm%n-1.0_preal) * mp_dev(k,l)*mp_dev(m,n) / squarenorm_mp_dev
16938  forall (k=1:3,l=1:3) &
16939  dlp_dmp(k,l,k,l) = dlp_dmp(k,l,k,l) + 1.0_preal
16940  forall (k=1:3,m=1:3) &
16941  dlp_dmp(k,k,m,m) = dlp_dmp(k,k,m,m) - 1.0_preal/3.0_preal
16942  dlp_dmp = dot_gamma / prm%M * dlp_dmp / norm_mp_dev
16943  else
16944  lp = 0.0_preal
16945  dlp_dmp = 0.0_preal
16946  end if
16947 
16948  end associate
16949 
16950 end subroutine plastic_isotropic_lpanditstangent
16951 
16952 
16953 !--------------------------------------------------------------------------------------------------
16955 !--------------------------------------------------------------------------------------------------
16956 module subroutine plastic_isotropic_lianditstangent(li,dli_dmi,mi,instance,of)
16957 
16958  real(preal), dimension(3,3), intent(out) :: &
16959  li
16960  real(preal), dimension(3,3,3,3), intent(out) :: &
16961  dli_dmi
16962 
16963  real(preal), dimension(3,3), intent(in) :: &
16964  mi
16965  integer, intent(in) :: &
16966  instance, &
16967  of
16968 
16969  real(preal) :: &
16970  tr
16971  integer :: &
16972  k, l, m, n
16973 
16974  associate(prm => param(instance), stt => state(instance))
16975 
16976  tr=math_trace33(math_spherical33(mi))
16977 
16978  if (prm%dilatation .and. abs(tr) > 0.0_preal) then ! no stress or J2 plasticity --> Li and its derivative are zero
16979  li = math_i3 &
16980  * prm%dot_gamma_0/prm%M * (3.0_preal*prm%M*stt%xi(of))**(-prm%n) &
16981  * tr * abs(tr)**(prm%n-1.0_preal)
16982 
16983 # 249 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_isotropic.f90"
16984 
16985  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
16986  dli_dmi(k,l,m,n) = prm%n / tr * li(k,l) * math_i3(m,n)
16987 
16988  else
16989  li = 0.0_preal
16990  dli_dmi = 0.0_preal
16991  endif
16992 
16993  end associate
16994 
16995  end subroutine plastic_isotropic_lianditstangent
16996 
16997 
16998 !--------------------------------------------------------------------------------------------------
17000 !--------------------------------------------------------------------------------------------------
17001 module subroutine plastic_isotropic_dotstate(mp,instance,of)
17002 
17003  real(preal), dimension(3,3), intent(in) :: &
17004  mp
17005  integer, intent(in) :: &
17006  instance, &
17007  of
17008 
17009  real(preal) :: &
17010  dot_gamma, & !< strainrate
17011  xi_inf_star, & !< saturation xi
17012  norm_mp
17013 
17014  associate(prm => param(instance), stt => state(instance), dot => dotstate(instance))
17015 
17016  if (prm%dilatation) then
17017  norm_mp = sqrt(math_tensordot(mp,mp))
17018  else
17019  norm_mp = sqrt(math_tensordot(math_deviatoric33(mp),math_deviatoric33(mp)))
17020  endif
17021 
17022  dot_gamma = prm%dot_gamma_0 * (sqrt(1.5_preal) * norm_mp /(prm%M*stt%xi(of))) **prm%n
17023 
17024  if (dot_gamma > 1e-12_preal) then
17025  if (deq0(prm%c_1)) then
17026  xi_inf_star = prm%xi_inf
17027  else
17028  xi_inf_star = prm%xi_inf &
17029  + asinh( (dot_gamma / prm%c_1)**(1.0_preal / prm%c_2))**(1.0_preal / prm%c_3) &
17030  / prm%c_4 * (dot_gamma / prm%dot_gamma_0)**(1.0_preal / prm%n)
17031  endif
17032  dot%xi(of) = dot_gamma &
17033  * ( prm%h0 + prm%h_ln * log(dot_gamma) ) &
17034  * abs( 1.0_preal - stt%xi(of)/xi_inf_star )**prm%a &
17035  * sign(1.0_preal, 1.0_preal - stt%xi(of)/xi_inf_star)
17036  else
17037  dot%xi(of) = 0.0_preal
17038  endif
17039 
17040  dot%gamma(of) = dot_gamma ! ToDo: not really used
17041 
17042  end associate
17043 
17044 end subroutine plastic_isotropic_dotstate
17045 
17046 
17047 !--------------------------------------------------------------------------------------------------
17049 !--------------------------------------------------------------------------------------------------
17050 module subroutine plastic_isotropic_results(instance,group)
17051 
17052  integer, intent(in) :: instance
17053  character(len=*), intent(in) :: group
17054 
17055  integer :: o
17056 
17057  associate(prm => param(instance), stt => state(instance))
17058  outputsloop: do o = 1,size(prm%output)
17059  select case(trim(prm%output(o)))
17060  case ('flowstress') ! ToDo: should be 'xi'
17061  call results_writedataset(group,stt%xi,'xi','resistance against plastic flow','Pa')
17062  end select
17063  enddo outputsloop
17064  end associate
17065 
17066 end subroutine plastic_isotropic_results
17067 
17068 
17069 end submodule plastic_isotropic
17070 # 39 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
17071 
17072 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_phenopowerlaw.f90" 1
17073 !--------------------------------------------------------------------------------------------------
17078 !--------------------------------------------------------------------------------------------------
17079 submodule(constitutive) plastic_phenopowerlaw
17080 
17081  type :: tparameters
17082  real(preal) :: &
17083  gdot0_slip = 1.0_preal, &
17084  gdot0_twin = 1.0_preal, &
17085  n_slip = 1.0_preal, &
17086  n_twin = 1.0_preal, &
17087  spr = 1.0_preal, &
17088  c_1 = 1.0_preal, &
17089  c_2 = 1.0_preal, &
17090  c_3 = 1.0_preal, &
17091  c_4 = 1.0_preal, &
17092  h0_slipslip = 1.0_preal, &
17093  h0_twinslip = 1.0_preal, &
17094  h0_twintwin = 1.0_preal, &
17095  a_slip = 1.0_preal
17096  real(preal), allocatable, dimension(:) :: &
17097  xi_slip_sat, & !< maximum critical shear stress for slip
17098  h_int, & !< per family hardening activity (optional)
17099  gamma_twin_char
17100  real(preal), allocatable, dimension(:,:) :: &
17101  interaction_slipslip, & !< slip resistance from slip activity
17102  interaction_sliptwin, & !< slip resistance from twin activity
17103  interaction_twinslip, & !< twin resistance from slip activity
17104  interaction_twintwin
17105  real(preal), allocatable, dimension(:,:,:) :: &
17106  p_sl, &
17107  p_tw, &
17108  nonschmid_pos, &
17109  nonschmid_neg
17110  integer :: &
17111  sum_n_sl, & !< total number of active slip system
17112  sum_n_tw
17113  logical :: &
17114  nonschmidactive = .false.
17115  character(len=pStringLen), allocatable, dimension(:) :: &
17116  output
17117  end type tparameters
17118 
17119  type :: tphenopowerlawstate
17120  real(preal), pointer, dimension(:,:) :: &
17121  xi_slip, &
17122  xi_twin, &
17123  gamma_slip, &
17124  gamma_twin
17125  end type tphenopowerlawstate
17126 
17127 !--------------------------------------------------------------------------------------------------
17128 ! containers for parameters and state
17129  type(tparameters), allocatable, dimension(:) :: param
17130  type(tphenopowerlawstate), allocatable, dimension(:) :: &
17131  dotstate, &
17132  state
17133 
17134 contains
17135 
17136 
17137 !--------------------------------------------------------------------------------------------------
17140 !--------------------------------------------------------------------------------------------------
17141 module subroutine plastic_phenopowerlaw_init
17142 
17143  integer :: &
17144  ninstance, &
17145  p, i, &
17146  nipcmyphase, &
17147  sizestate, sizedotstate, &
17148  startindex, endindex
17149  integer, dimension(:), allocatable :: &
17150  n_sl, n_tw
17151  real(preal), dimension(:), allocatable :: &
17152  xi_slip_0, & !< initial critical shear stress for slip
17153  xi_twin_0, & !< initial critical shear stress for twin
17154  a
17155  character(len=pStringLen) :: &
17156  extmsg = ''
17157 
17158  write(6,'(/,a)') ' <<<+- plastic_'//plasticity_phenopowerlaw_label//' init -+>>>'; flush(6)
17159 
17160  ninstance = count(phase_plasticity == plasticity_phenopowerlaw_id)
17161  if (iand(debug_level(debug_constitutive),debug_levelbasic) /= 0) &
17162  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
17163 
17164  allocate(param(ninstance))
17165  allocate(state(ninstance))
17166  allocate(dotstate(ninstance))
17167 
17168  do p = 1, size(phase_plasticity)
17169  if (phase_plasticity(p) /= plasticity_phenopowerlaw_id) cycle
17170  associate(prm => param(phase_plasticityinstance(p)), &
17171  dot => dotstate(phase_plasticityinstance(p)), &
17172  stt => state(phase_plasticityinstance(p)), &
17173  config => config_phase(p))
17174 
17175 !--------------------------------------------------------------------------------------------------
17176 ! slip related parameters
17177  n_sl = config%getInts('nslip',defaultval=emptyintarray)
17178  prm%sum_N_sl = sum(abs(n_sl))
17179  slipactive: if (prm%sum_N_sl > 0) then
17180  prm%P_sl = lattice_schmidmatrix_slip(n_sl,config%getString('lattice_structure'),&
17181  config%getFloat('c/a',defaultval=0.0_preal))
17182 
17183  if(trim(config%getString('lattice_structure')) == 'bcc') then
17184  a = config%getFloats('nonschmid_coefficients',defaultval = emptyrealarray)
17185  if(size(a) > 0) prm%nonSchmidActive = .true.
17186  prm%nonSchmid_pos = lattice_nonschmidmatrix(n_sl,a,+1)
17187  prm%nonSchmid_neg = lattice_nonschmidmatrix(n_sl,a,-1)
17188  else
17189  prm%nonSchmid_pos = prm%P_sl
17190  prm%nonSchmid_neg = prm%P_sl
17191  endif
17192  prm%interaction_SlipSlip = lattice_interaction_slipbyslip(n_sl, &
17193  config%getFloats('interaction_slipslip'), &
17194  config%getString('lattice_structure'))
17195 
17196  xi_slip_0 = config%getFloats('tau0_slip', requiredsize=size(n_sl))
17197  prm%xi_slip_sat = config%getFloats('tausat_slip', requiredsize=size(n_sl))
17198  prm%H_int = config%getFloats('h_int', requiredsize=size(n_sl), &
17199  defaultval=[(0.0_preal,i=1,size(n_sl))])
17200 
17201  prm%gdot0_slip = config%getFloat('gdot0_slip')
17202  prm%n_slip = config%getFloat('n_slip')
17203  prm%a_slip = config%getFloat('a_slip')
17204  prm%h0_SlipSlip = config%getFloat('h0_slipslip')
17205 
17206  ! expand: family => system
17207  xi_slip_0 = math_expand(xi_slip_0, n_sl)
17208  prm%xi_slip_sat = math_expand(prm%xi_slip_sat,n_sl)
17209  prm%H_int = math_expand(prm%H_int, n_sl)
17210 
17211  ! sanity checks
17212  if ( prm%gdot0_slip <= 0.0_preal) extmsg = trim(extmsg)//' gdot0_slip'
17213  if ( prm%a_slip <= 0.0_preal) extmsg = trim(extmsg)//' a_slip'
17214  if ( prm%n_slip <= 0.0_preal) extmsg = trim(extmsg)//' n_slip'
17215  if (any(xi_slip_0 <= 0.0_preal)) extmsg = trim(extmsg)//' xi_slip_0'
17216  if (any(prm%xi_slip_sat <= 0.0_preal)) extmsg = trim(extmsg)//' xi_slip_sat'
17217 
17218  else slipactive
17219  xi_slip_0 = emptyrealarray
17220  allocate(prm%xi_slip_sat,prm%H_int,source=emptyrealarray)
17221  allocate(prm%interaction_SlipSlip(0,0))
17222  endif slipactive
17223 
17224 !--------------------------------------------------------------------------------------------------
17225 ! twin related parameters
17226  n_tw = config%getInts('ntwin', defaultval=emptyintarray)
17227  prm%sum_N_tw = sum(abs(n_tw))
17228  twinactive: if (prm%sum_N_tw > 0) then
17229  prm%P_tw = lattice_schmidmatrix_twin(n_tw,config%getString('lattice_structure'),&
17230  config%getFloat('c/a',defaultval=0.0_preal))
17231  prm%interaction_TwinTwin = lattice_interaction_twinbytwin(n_tw,&
17232  config%getFloats('interaction_twintwin'), &
17233  config%getString('lattice_structure'))
17234  prm%gamma_twin_char = lattice_characteristicshear_twin(n_tw,config%getString('lattice_structure'),&
17235  config%getFloat('c/a'))
17236 
17237  xi_twin_0 = config%getFloats('tau0_twin',requiredsize=size(n_tw))
17238 
17239  prm%c_1 = config%getFloat('twin_c',defaultval=0.0_preal)
17240  prm%c_2 = config%getFloat('twin_b',defaultval=1.0_preal)
17241  prm%c_3 = config%getFloat('twin_e',defaultval=0.0_preal)
17242  prm%c_4 = config%getFloat('twin_d',defaultval=0.0_preal)
17243  prm%gdot0_twin = config%getFloat('gdot0_twin')
17244  prm%n_twin = config%getFloat('n_twin')
17245  prm%spr = config%getFloat('s_pr')
17246  prm%h0_TwinTwin = config%getFloat('h0_twintwin')
17247 
17248  ! expand: family => system
17249  xi_twin_0 = math_expand(xi_twin_0,n_tw)
17250 
17251  ! sanity checks
17252  if (prm%gdot0_twin <= 0.0_preal) extmsg = trim(extmsg)//' gdot0_twin'
17253  if (prm%n_twin <= 0.0_preal) extmsg = trim(extmsg)//' n_twin'
17254 
17255  else twinactive
17256  xi_twin_0 = emptyrealarray
17257  allocate(prm%gamma_twin_char,source=emptyrealarray)
17258  allocate(prm%interaction_TwinTwin(0,0))
17259  endif twinactive
17260 
17261 !--------------------------------------------------------------------------------------------------
17262 ! slip-twin related parameters
17263  slipandtwinactive: if (prm%sum_N_sl > 0 .and. prm%sum_N_tw > 0) then
17264  prm%h0_TwinSlip = config%getFloat('h0_twinslip')
17265  prm%interaction_SlipTwin = lattice_interaction_slipbytwin(n_sl,n_tw,&
17266  config%getFloats('interaction_sliptwin'), &
17267  config%getString('lattice_structure'))
17268  prm%interaction_TwinSlip = lattice_interaction_twinbyslip(n_tw,n_sl,&
17269  config%getFloats('interaction_twinslip'), &
17270  config%getString('lattice_structure'))
17271  else slipandtwinactive
17272  allocate(prm%interaction_SlipTwin(prm%sum_N_sl,prm%sum_N_tw)) ! at least one dimension is 0
17273  allocate(prm%interaction_TwinSlip(prm%sum_N_tw,prm%sum_N_sl)) ! at least one dimension is 0
17274  prm%h0_TwinSlip = 0.0_preal
17275  endif slipandtwinactive
17276 
17277 !--------------------------------------------------------------------------------------------------
17278 ! output pararameters
17279  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
17280 
17281 !--------------------------------------------------------------------------------------------------
17282 ! allocate state arrays
17283  nipcmyphase = count(material_phaseat == p) * discretization_nip
17284  sizedotstate = size(['xi_sl ','gamma_sl']) * prm%sum_N_sl &
17285  + size(['xi_tw ','gamma_tw']) * prm%sum_N_tw
17286  sizestate = sizedotstate
17287 
17288  call material_allocateplasticstate(p,nipcmyphase,sizestate,sizedotstate,0)
17289 
17290 !--------------------------------------------------------------------------------------------------
17291 ! state aliases and initialization
17292  startindex = 1
17293  endindex = prm%sum_N_sl
17294  stt%xi_slip => plasticstate(p)%state (startindex:endindex,:)
17295  stt%xi_slip = spread(xi_slip_0, 2, nipcmyphase)
17296  dot%xi_slip => plasticstate(p)%dotState(startindex:endindex,:)
17297  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_xi',defaultval=1.0_preal)
17298  if(any(plasticstate(p)%atol(startindex:endindex) < 0.0_preal)) extmsg = trim(extmsg)//' atol_xi'
17299 
17300  startindex = endindex + 1
17301  endindex = endindex + prm%sum_N_tw
17302  stt%xi_twin => plasticstate(p)%state (startindex:endindex,:)
17303  stt%xi_twin = spread(xi_twin_0, 2, nipcmyphase)
17304  dot%xi_twin => plasticstate(p)%dotState(startindex:endindex,:)
17305  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_xi',defaultval=1.0_preal)
17306  if(any(plasticstate(p)%atol(startindex:endindex) < 0.0_preal)) extmsg = trim(extmsg)//' atol_xi'
17307 
17308  startindex = endindex + 1
17309  endindex = endindex + prm%sum_N_sl
17310  stt%gamma_slip => plasticstate(p)%state (startindex:endindex,:)
17311  dot%gamma_slip => plasticstate(p)%dotState(startindex:endindex,:)
17312  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_gamma',defaultval=1.0e-6_preal)
17313  if(any(plasticstate(p)%atol(startindex:endindex) < 0.0_preal)) extmsg = trim(extmsg)//' atol_gamma'
17314  ! global alias
17315  plasticstate(p)%slipRate => plasticstate(p)%dotState(startindex:endindex,:)
17316 
17317  startindex = endindex + 1
17318  endindex = endindex + prm%sum_N_tw
17319  stt%gamma_twin => plasticstate(p)%state (startindex:endindex,:)
17320  dot%gamma_twin => plasticstate(p)%dotState(startindex:endindex,:)
17321  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_gamma',defaultval=1.0e-6_preal)
17322  if(any(plasticstate(p)%atol(startindex:endindex) < 0.0_preal)) extmsg = trim(extmsg)//' atol_gamma'
17323 
17324  plasticstate(p)%state0 = plasticstate(p)%state ! ToDo: this could be done centrally
17325 
17326  end associate
17327 
17328 !--------------------------------------------------------------------------------------------------
17329 ! exit if any parameter is out of range
17330  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//plasticity_phenopowerlaw_label//')')
17331 
17332  enddo
17333 
17334 end subroutine plastic_phenopowerlaw_init
17335 
17336 
17337 !--------------------------------------------------------------------------------------------------
17340 ! equally (Taylor assumption). Twinning happens only in untwinned volume
17341 !--------------------------------------------------------------------------------------------------
17342 pure module subroutine plastic_phenopowerlaw_lpanditstangent(lp,dlp_dmp,mp,instance,of)
17343 
17344  real(preal), dimension(3,3), intent(out) :: &
17345  lp
17346  real(preal), dimension(3,3,3,3), intent(out) :: &
17347  dlp_dmp
17348 
17349  real(preal), dimension(3,3), intent(in) :: &
17350  mp
17351  integer, intent(in) :: &
17352  instance, &
17353  of
17354 
17355  integer :: &
17356  i,k,l,m,n
17357  real(preal), dimension(param(instance)%sum_N_sl) :: &
17358  gdot_slip_pos,gdot_slip_neg, &
17359  dgdot_dtauslip_pos,dgdot_dtauslip_neg
17360  real(preal), dimension(param(instance)%sum_N_tw) :: &
17361  gdot_twin,dgdot_dtautwin
17362 
17363  lp = 0.0_preal
17364  dlp_dmp = 0.0_preal
17365 
17366  associate(prm => param(instance))
17367 
17368  call kinetics_slip(mp,instance,of,gdot_slip_pos,gdot_slip_neg,dgdot_dtauslip_pos,dgdot_dtauslip_neg)
17369  slipsystems: do i = 1, prm%sum_N_sl
17370  lp = lp + (gdot_slip_pos(i)+gdot_slip_neg(i))*prm%P_sl(1:3,1:3,i)
17371  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
17372  dlp_dmp(k,l,m,n) = dlp_dmp(k,l,m,n) &
17373  + dgdot_dtauslip_pos(i) * prm%P_sl(k,l,i) * prm%nonSchmid_pos(m,n,i) &
17374  + dgdot_dtauslip_neg(i) * prm%P_sl(k,l,i) * prm%nonSchmid_neg(m,n,i)
17375  enddo slipsystems
17376 
17377  call kinetics_twin(mp,instance,of,gdot_twin,dgdot_dtautwin)
17378  twinsystems: do i = 1, prm%sum_N_tw
17379  lp = lp + gdot_twin(i)*prm%P_tw(1:3,1:3,i)
17380  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
17381  dlp_dmp(k,l,m,n) = dlp_dmp(k,l,m,n) &
17382  + dgdot_dtautwin(i)*prm%P_tw(k,l,i)*prm%P_tw(m,n,i)
17383  enddo twinsystems
17384 
17385  end associate
17386 
17387 end subroutine plastic_phenopowerlaw_lpanditstangent
17388 
17389 
17390 !--------------------------------------------------------------------------------------------------
17392 !--------------------------------------------------------------------------------------------------
17393 module subroutine plastic_phenopowerlaw_dotstate(mp,instance,of)
17394 
17395  real(preal), dimension(3,3), intent(in) :: &
17396  mp
17397  integer, intent(in) :: &
17398  instance, &
17399  of
17400 
17401  real(preal) :: &
17402  c_slipslip,c_twinslip,c_twintwin, &
17403  xi_slip_sat_offset,&
17404  sumgamma,sumf
17405  real(preal), dimension(param(instance)%sum_N_sl) :: &
17406  left_slipslip,right_slipslip, &
17407  gdot_slip_pos,gdot_slip_neg
17408 
17409  associate(prm => param(instance), stt => state(instance), dot => dotstate(instance))
17410 
17411  sumgamma = sum(stt%gamma_slip(:,of))
17412  sumf = sum(stt%gamma_twin(:,of)/prm%gamma_twin_char)
17413 
17414 !--------------------------------------------------------------------------------------------------
17415 ! system-independent (nonlinear) prefactors to M_Xx (X influenced by x) matrices
17416  c_slipslip = prm%h0_slipslip * (1.0_preal + prm%c_1*sumf** prm%c_2)
17417  c_twinslip = prm%h0_TwinSlip * sumgamma**prm%c_3
17418  c_twintwin = prm%h0_TwinTwin * sumf**prm%c_4
17419 
17420 !--------------------------------------------------------------------------------------------------
17421 ! calculate left and right vectors
17422  left_slipslip = 1.0_preal + prm%H_int
17423  xi_slip_sat_offset = prm%spr*sqrt(sumf)
17424  right_slipslip = abs(1.0_preal-stt%xi_slip(:,of) / (prm%xi_slip_sat+xi_slip_sat_offset)) **prm%a_slip &
17425  * sign(1.0_preal,1.0_preal-stt%xi_slip(:,of) / (prm%xi_slip_sat+xi_slip_sat_offset))
17426 
17427 !--------------------------------------------------------------------------------------------------
17428 ! shear rates
17429  call kinetics_slip(mp,instance,of,gdot_slip_pos,gdot_slip_neg)
17430  dot%gamma_slip(:,of) = abs(gdot_slip_pos+gdot_slip_neg)
17431  call kinetics_twin(mp,instance,of,dot%gamma_twin(:,of))
17432 
17433 !--------------------------------------------------------------------------------------------------
17434 ! hardening
17435  dot%xi_slip(:,of) = c_slipslip * left_slipslip * &
17436  matmul(prm%interaction_SlipSlip,dot%gamma_slip(:,of)*right_slipslip) &
17437  + matmul(prm%interaction_SlipTwin,dot%gamma_twin(:,of))
17438 
17439  dot%xi_twin(:,of) = c_twinslip * matmul(prm%interaction_TwinSlip,dot%gamma_slip(:,of)) &
17440  + c_twintwin * matmul(prm%interaction_TwinTwin,dot%gamma_twin(:,of))
17441  end associate
17442 
17443 end subroutine plastic_phenopowerlaw_dotstate
17444 
17445 
17446 !--------------------------------------------------------------------------------------------------
17448 !--------------------------------------------------------------------------------------------------
17449 module subroutine plastic_phenopowerlaw_results(instance,group)
17450 
17451  integer, intent(in) :: instance
17452  character(len=*), intent(in) :: group
17453 
17454  integer :: o
17455 
17456  associate(prm => param(instance), stt => state(instance))
17457  outputsloop: do o = 1,size(prm%output)
17458  select case(trim(prm%output(o)))
17459 
17460  case('resistance_slip')
17461  if(prm%sum_N_sl>0) call results_writedataset(group,stt%xi_slip, 'xi_sl', &
17462  'resistance against plastic slip','Pa')
17463  case('accumulatedshear_slip')
17464  if(prm%sum_N_sl>0) call results_writedataset(group,stt%gamma_slip,'gamma_sl', &
17465  'plastic shear','1')
17466 
17467  case('resistance_twin')
17468  if(prm%sum_N_tw>0) call results_writedataset(group,stt%xi_twin, 'xi_tw', &
17469  'resistance against twinning','Pa')
17470  case('accumulatedshear_twin')
17471  if(prm%sum_N_tw>0) call results_writedataset(group,stt%gamma_twin,'gamma_tw', &
17472  'twinning shear','1')
17473 
17474  end select
17475  enddo outputsloop
17476  end associate
17477 
17478 end subroutine plastic_phenopowerlaw_results
17479 
17480 
17481 !--------------------------------------------------------------------------------------------------
17483 ! stress.
17485 ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
17486 ! have the optional arguments at the end.
17487 !--------------------------------------------------------------------------------------------------
17488 pure subroutine kinetics_slip(Mp,instance,of, &
17489  gdot_slip_pos,gdot_slip_neg,dgdot_dtau_slip_pos,dgdot_dtau_slip_neg)
17491  real(preal), dimension(3,3), intent(in) :: &
17492  mp
17493  integer, intent(in) :: &
17494  instance, &
17495  of
17496 
17497  real(preal), intent(out), dimension(param(instance)%sum_N_sl) :: &
17498  gdot_slip_pos, &
17499  gdot_slip_neg
17500  real(preal), intent(out), optional, dimension(param(instance)%sum_N_sl) :: &
17501  dgdot_dtau_slip_pos, &
17502  dgdot_dtau_slip_neg
17503 
17504  real(preal), dimension(param(instance)%sum_N_sl) :: &
17505  tau_slip_pos, &
17506  tau_slip_neg
17507  integer :: i
17508 
17509  associate(prm => param(instance), stt => state(instance))
17510 
17511  do i = 1, prm%sum_N_sl
17512  tau_slip_pos(i) = math_tensordot(mp,prm%nonSchmid_pos(1:3,1:3,i))
17513  tau_slip_neg(i) = merge(math_tensordot(mp,prm%nonSchmid_neg(1:3,1:3,i)), &
17514  0.0_preal, prm%nonSchmidActive)
17515  enddo
17516 
17517  where(dneq0(tau_slip_pos))
17518  gdot_slip_pos = prm%gdot0_slip * merge(0.5_preal,1.0_preal, prm%nonSchmidActive) & ! 1/2 if non-Schmid active
17519  * sign(abs(tau_slip_pos/stt%xi_slip(:,of))**prm%n_slip, tau_slip_pos)
17520  else where
17521  gdot_slip_pos = 0.0_preal
17522  end where
17523 
17524  where(dneq0(tau_slip_neg))
17525  gdot_slip_neg = prm%gdot0_slip * 0.5_preal & ! only used if non-Schmid active, always 1/2
17526  * sign(abs(tau_slip_neg/stt%xi_slip(:,of))**prm%n_slip, tau_slip_neg)
17527  else where
17528  gdot_slip_neg = 0.0_preal
17529  end where
17530 
17531  if (present(dgdot_dtau_slip_pos)) then
17532  where(dneq0(gdot_slip_pos))
17533  dgdot_dtau_slip_pos = gdot_slip_pos*prm%n_slip/tau_slip_pos
17534  else where
17535  dgdot_dtau_slip_pos = 0.0_preal
17536  end where
17537  endif
17538  if (present(dgdot_dtau_slip_neg)) then
17539  where(dneq0(gdot_slip_neg))
17540  dgdot_dtau_slip_neg = gdot_slip_neg*prm%n_slip/tau_slip_neg
17541  else where
17542  dgdot_dtau_slip_neg = 0.0_preal
17543  end where
17544  endif
17545  end associate
17546 
17547 end subroutine kinetics_slip
17548 
17549 
17550 !--------------------------------------------------------------------------------------------------
17552 ! stress. Twinning is assumed to take place only in untwinned volume.
17554 ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
17555 ! have the optional arguments at the end.
17556 !--------------------------------------------------------------------------------------------------
17557 pure subroutine kinetics_twin(Mp,instance,of,&
17558  gdot_twin,dgdot_dtau_twin)
17560  real(preal), dimension(3,3), intent(in) :: &
17561  mp
17562  integer, intent(in) :: &
17563  instance, &
17564  of
17565 
17566  real(preal), dimension(param(instance)%sum_N_tw), intent(out) :: &
17567  gdot_twin
17568  real(preal), dimension(param(instance)%sum_N_tw), intent(out), optional :: &
17569  dgdot_dtau_twin
17570 
17571  real(preal), dimension(param(instance)%sum_N_tw) :: &
17572  tau_twin
17573  integer :: i
17574 
17575  associate(prm => param(instance), stt => state(instance))
17576 
17577  do i = 1, prm%sum_N_tw
17578  tau_twin(i) = math_tensordot(mp,prm%P_tw(1:3,1:3,i))
17579  enddo
17580 
17581  where(tau_twin > 0.0_preal)
17582  gdot_twin = (1.0_preal-sum(stt%gamma_twin(:,of)/prm%gamma_twin_char)) & ! only twin in untwinned volume fraction
17583  * prm%gdot0_twin*(abs(tau_twin)/stt%xi_twin(:,of))**prm%n_twin
17584  else where
17585  gdot_twin = 0.0_preal
17586  end where
17587 
17588  if (present(dgdot_dtau_twin)) then
17589  where(dneq0(gdot_twin))
17590  dgdot_dtau_twin = gdot_twin*prm%n_twin/tau_twin
17591  else where
17592  dgdot_dtau_twin = 0.0_preal
17593  end where
17594  endif
17595 
17596  end associate
17597 
17598 end subroutine kinetics_twin
17599 
17600 end submodule plastic_phenopowerlaw
17601 # 40 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
17602 
17603 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_kinehardening.f90" 1
17604 !--------------------------------------------------------------------------------------------------
17610 !--------------------------------------------------------------------------------------------------
17611 submodule(constitutive) plastic_kinehardening
17612 
17613  type :: tparameters
17614  real(preal) :: &
17615  gdot0 = 1.0_preal, &
17616  n = 1.0_preal
17617  real(preal), allocatable, dimension(:) :: &
17618  theta0, & !< initial hardening rate of forward stress for each slip
17619  theta1, & !< asymptotic hardening rate of forward stress for each slip
17620  theta0_b, & !< initial hardening rate of back stress for each slip
17621  theta1_b, & !< asymptotic hardening rate of back stress for each slip
17622  tau1, &
17623  tau1_b
17624  real(preal), allocatable, dimension(:,:) :: &
17625  interaction_slipslip
17626  real(preal), allocatable, dimension(:,:,:) :: &
17627  p, &
17628  nonschmid_pos, &
17629  nonschmid_neg
17630  integer :: &
17631  sum_n_sl, & !< total number of active slip system
17632  of_debug = 0
17633  logical :: &
17634  nonschmidactive = .false.
17635  character(len=pStringLen), allocatable, dimension(:) :: &
17636  output
17637  end type tparameters
17638 
17639  type :: tkinehardeningstate
17640  real(preal), pointer, dimension(:,:) :: & !< vectors along NipcMyInstance
17641  crss, & !< critical resolved stress
17642  crss_back, & !< critical resolved back stress
17643  sense, & !< sense of acting shear stress (-1 or +1)
17644  chi0, & !< backstress at last switch of stress sense
17645  gamma0, & !< accumulated shear at last switch of stress sense
17646  accshear
17647  end type tkinehardeningstate
17648 
17649 !--------------------------------------------------------------------------------------------------
17650 ! containers for parameters and state
17651  type(tparameters), allocatable, dimension(:) :: param
17652  type(tkinehardeningstate), allocatable, dimension(:) :: &
17653  dotstate, &
17654  deltastate, &
17655  state
17656 
17657 contains
17658 
17659 
17660 !--------------------------------------------------------------------------------------------------
17663 !--------------------------------------------------------------------------------------------------
17664 module subroutine plastic_kinehardening_init
17665 
17666  integer :: &
17667  ninstance, &
17668  p, o, &
17669  nipcmyphase, &
17670  sizestate, sizedeltastate, sizedotstate, &
17671  startindex, endindex
17672  integer, dimension(:), allocatable :: &
17673  n_sl
17674  real(preal), dimension(:), allocatable :: &
17675  xi_0, & !< initial resistance against plastic flow
17676  a
17677  character(len=pStringLen) :: &
17678  extmsg = ''
17679 
17680  write(6,'(/,a)') ' <<<+- plastic_'//plasticity_kinehardening_label//' init -+>>>'; flush(6)
17681 
17682  ninstance = count(phase_plasticity == plasticity_kinehardening_id)
17683  if (iand(debug_level(debug_constitutive),debug_levelbasic) /= 0) &
17684  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
17685 
17686  allocate(param(ninstance))
17687  allocate(state(ninstance))
17688  allocate(dotstate(ninstance))
17689  allocate(deltastate(ninstance))
17690 
17691  do p = 1, size(phase_plasticityinstance)
17692  if (phase_plasticity(p) /= plasticity_kinehardening_id) cycle
17693  associate(prm => param(phase_plasticityinstance(p)), &
17694  dot => dotstate(phase_plasticityinstance(p)), &
17695  dlt => deltastate(phase_plasticityinstance(p)), &
17696  stt => state(phase_plasticityinstance(p)),&
17697  config => config_phase(p))
17698 
17699  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
17700 
17701 
17702 
17703 
17704 
17705 
17706 
17707 !--------------------------------------------------------------------------------------------------
17708 ! slip related parameters
17709  n_sl = config%getInts('nslip',defaultval=emptyintarray)
17710  prm%sum_N_sl = sum(abs(n_sl))
17711  slipactive: if (prm%sum_N_sl > 0) then
17712  prm%P = lattice_schmidmatrix_slip(n_sl,config%getString('lattice_structure'),&
17713  config%getFloat('c/a',defaultval=0.0_preal))
17714 
17715  if(trim(config%getString('lattice_structure')) == 'bcc') then
17716  a = config%getFloats('nonschmid_coefficients',defaultval = emptyrealarray)
17717  if(size(a) > 0) prm%nonSchmidActive = .true.
17718  prm%nonSchmid_pos = lattice_nonschmidmatrix(n_sl,a,+1)
17719  prm%nonSchmid_neg = lattice_nonschmidmatrix(n_sl,a,-1)
17720  else
17721  prm%nonSchmid_pos = prm%P
17722  prm%nonSchmid_neg = prm%P
17723  endif
17724  prm%interaction_SlipSlip = lattice_interaction_slipbyslip(n_sl, &
17725  config%getFloats('interaction_slipslip'), &
17726  config%getString('lattice_structure'))
17727 
17728  xi_0 = config%getFloats('crss0', requiredsize=size(n_sl))
17729  prm%tau1 = config%getFloats('tau1', requiredsize=size(n_sl))
17730  prm%tau1_b = config%getFloats('tau1_b', requiredsize=size(n_sl))
17731  prm%theta0 = config%getFloats('theta0', requiredsize=size(n_sl))
17732  prm%theta1 = config%getFloats('theta1', requiredsize=size(n_sl))
17733  prm%theta0_b = config%getFloats('theta0_b', requiredsize=size(n_sl))
17734  prm%theta1_b = config%getFloats('theta1_b', requiredsize=size(n_sl))
17735 
17736  prm%gdot0 = config%getFloat('gdot0')
17737  prm%n = config%getFloat('n_slip')
17738 
17739  ! expand: family => system
17740  xi_0 = math_expand(xi_0, n_sl)
17741  prm%tau1 = math_expand(prm%tau1, n_sl)
17742  prm%tau1_b = math_expand(prm%tau1_b, n_sl)
17743  prm%theta0 = math_expand(prm%theta0, n_sl)
17744  prm%theta1 = math_expand(prm%theta1, n_sl)
17745  prm%theta0_b = math_expand(prm%theta0_b,n_sl)
17746  prm%theta1_b = math_expand(prm%theta1_b,n_sl)
17747 
17748 !--------------------------------------------------------------------------------------------------
17749 ! sanity checks
17750  if ( prm%gdot0 <= 0.0_preal) extmsg = trim(extmsg)//' gdot0'
17751  if ( prm%n <= 0.0_preal) extmsg = trim(extmsg)//' n_slip'
17752  if (any(xi_0 <= 0.0_preal)) extmsg = trim(extmsg)//' crss0'
17753  if (any(prm%tau1 <= 0.0_preal)) extmsg = trim(extmsg)//' tau1'
17754  if (any(prm%tau1_b <= 0.0_preal)) extmsg = trim(extmsg)//' tau1_b'
17755 
17756  !ToDo: Any sensible checks for theta?
17757  else slipactive
17758  xi_0 = emptyrealarray
17759  allocate(prm%tau1,prm%tau1_b,prm%theta0,prm%theta1,prm%theta0_b,prm%theta1_b,source=emptyrealarray)
17760  allocate(prm%interaction_SlipSlip(0,0))
17761  endif slipactive
17762 
17763 !--------------------------------------------------------------------------------------------------
17764 ! allocate state arrays
17765  nipcmyphase = count(material_phaseat == p) * discretization_nip
17766  sizedotstate = size(['crss ','crss_back', 'accshear ']) * prm%sum_N_sl
17767  sizedeltastate = size(['sense ', 'chi0 ', 'gamma0' ]) * prm%sum_N_sl
17768  sizestate = sizedotstate + sizedeltastate
17769 
17770  call material_allocateplasticstate(p,nipcmyphase,sizestate,sizedotstate,sizedeltastate)
17771 
17772 !--------------------------------------------------------------------------------------------------
17773 ! state aliases and initialization
17774  startindex = 1
17775  endindex = prm%sum_N_sl
17776  stt%crss => plasticstate(p)%state (startindex:endindex,:)
17777  stt%crss = spread(xi_0, 2, nipcmyphase)
17778  dot%crss => plasticstate(p)%dotState(startindex:endindex,:)
17779  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_xi',defaultval=1.0_preal)
17780  if(any(plasticstate(p)%atol(startindex:endindex) < 0.0_preal)) extmsg = trim(extmsg)//' atol_xi'
17781 
17782  startindex = endindex + 1
17783  endindex = endindex + prm%sum_N_sl
17784  stt%crss_back => plasticstate(p)%state (startindex:endindex,:)
17785  dot%crss_back => plasticstate(p)%dotState(startindex:endindex,:)
17786  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_xi',defaultval=1.0_preal)
17787 
17788  startindex = endindex + 1
17789  endindex = endindex + prm%sum_N_sl
17790  stt%accshear => plasticstate(p)%state (startindex:endindex,:)
17791  dot%accshear => plasticstate(p)%dotState(startindex:endindex,:)
17792  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_gamma',defaultval=1.0e-6_preal)
17793  if(any(plasticstate(p)%atol(startindex:endindex) < 0.0_preal)) extmsg = trim(extmsg)//' atol_gamma'
17794  ! global alias
17795  plasticstate(p)%slipRate => plasticstate(p)%dotState(startindex:endindex,:)
17796 
17797  o = plasticstate(p)%offsetDeltaState
17798  startindex = endindex + 1
17799  endindex = endindex + prm%sum_N_sl
17800  stt%sense => plasticstate(p)%state (startindex :endindex ,:)
17801  dlt%sense => plasticstate(p)%deltaState(startindex-o:endindex-o,:)
17802 
17803  startindex = endindex + 1
17804  endindex = endindex + prm%sum_N_sl
17805  stt%chi0 => plasticstate(p)%state (startindex :endindex ,:)
17806  dlt%chi0 => plasticstate(p)%deltaState(startindex-o:endindex-o,:)
17807 
17808  startindex = endindex + 1
17809  endindex = endindex + prm%sum_N_sl
17810  stt%gamma0 => plasticstate(p)%state (startindex :endindex ,:)
17811  dlt%gamma0 => plasticstate(p)%deltaState(startindex-o:endindex-o,:)
17812 
17813  plasticstate(p)%state0 = plasticstate(p)%state ! ToDo: this could be done centrally
17814 
17815  end associate
17816 
17817 !--------------------------------------------------------------------------------------------------
17818 ! exit if any parameter is out of range
17819  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//plasticity_kinehardening_label//')')
17820 
17821  enddo
17822 
17823 
17824 end subroutine plastic_kinehardening_init
17825 
17826 
17827 !--------------------------------------------------------------------------------------------------
17829 !--------------------------------------------------------------------------------------------------
17830 pure module subroutine plastic_kinehardening_lpanditstangent(lp,dlp_dmp,mp,instance,of)
17831 
17832  real(preal), dimension(3,3), intent(out) :: &
17833  lp
17834  real(preal), dimension(3,3,3,3), intent(out) :: &
17835  dlp_dmp
17836 
17837  real(preal), dimension(3,3), intent(in) :: &
17838  mp
17839  integer, intent(in) :: &
17840  instance, &
17841  of
17842 
17843  integer :: &
17844  i,k,l,m,n
17845  real(preal), dimension(param(instance)%sum_N_sl) :: &
17846  gdot_pos,gdot_neg, &
17847  dgdot_dtau_pos,dgdot_dtau_neg
17848 
17849  lp = 0.0_preal
17850  dlp_dmp = 0.0_preal
17851 
17852  associate(prm => param(instance))
17853 
17854  call kinetics(mp,instance,of,gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg)
17855 
17856  do i = 1, prm%sum_N_sl
17857  lp = lp + (gdot_pos(i)+gdot_neg(i))*prm%P(1:3,1:3,i)
17858  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
17859  dlp_dmp(k,l,m,n) = dlp_dmp(k,l,m,n) &
17860  + dgdot_dtau_pos(i) * prm%P(k,l,i) * prm%nonSchmid_pos(m,n,i) &
17861  + dgdot_dtau_neg(i) * prm%P(k,l,i) * prm%nonSchmid_neg(m,n,i)
17862  enddo
17863 
17864  end associate
17865 
17866 end subroutine plastic_kinehardening_lpanditstangent
17867 
17868 
17869 !--------------------------------------------------------------------------------------------------
17871 !--------------------------------------------------------------------------------------------------
17872 module subroutine plastic_kinehardening_dotstate(mp,instance,of)
17873 
17874  real(preal), dimension(3,3), intent(in) :: &
17875  mp
17876  integer, intent(in) :: &
17877  instance, &
17878  of
17879 
17880  real(preal) :: &
17881  sumgamma
17882  real(preal), dimension(param(instance)%sum_N_sl) :: &
17883  gdot_pos,gdot_neg
17884 
17885 
17886  associate(prm => param(instance), stt => state(instance), dot => dotstate(instance))
17887 
17888  call kinetics(mp,instance,of,gdot_pos,gdot_neg)
17889  dot%accshear(:,of) = abs(gdot_pos+gdot_neg)
17890  sumgamma = sum(stt%accshear(:,of))
17891 
17892 
17893  dot%crss(:,of) = matmul(prm%interaction_SlipSlip,dot%accshear(:,of)) &
17894  * ( prm%theta1 &
17895  + (prm%theta0 - prm%theta1 + prm%theta0*prm%theta1*sumgamma/prm%tau1) &
17896  * exp(-sumgamma*prm%theta0/prm%tau1) &
17897  )
17898 
17899  dot%crss_back(:,of) = stt%sense(:,of)*dot%accshear(:,of) * &
17900  ( prm%theta1_b + &
17901  (prm%theta0_b - prm%theta1_b &
17902  + prm%theta0_b*prm%theta1_b/(prm%tau1_b+stt%chi0(:,of))*(stt%accshear(:,of)-stt%gamma0(:,of))&
17903  ) *exp(-(stt%accshear(:,of)-stt%gamma0(:,of)) *prm%theta0_b/(prm%tau1_b+stt%chi0(:,of))) &
17904  )
17905 
17906  end associate
17907 
17908 end subroutine plastic_kinehardening_dotstate
17909 
17910 
17911 !--------------------------------------------------------------------------------------------------
17913 !--------------------------------------------------------------------------------------------------
17914 module subroutine plastic_kinehardening_deltastate(mp,instance,of)
17915 
17916  real(preal), dimension(3,3), intent(in) :: &
17917  mp
17918  integer, intent(in) :: &
17919  instance, &
17920  of
17921 
17922  real(preal), dimension(param(instance)%sum_N_sl) :: &
17923  gdot_pos,gdot_neg, &
17924  sense
17925 
17926  associate(prm => param(instance), stt => state(instance), dlt => deltastate(instance))
17927 
17928  call kinetics(mp,instance,of,gdot_pos,gdot_neg)
17929  sense = merge(state(instance)%sense(:,of), & ! keep existing...
17930  sign(1.0_preal,gdot_pos+gdot_neg), & ! ...or have a defined
17931  deq0(gdot_pos+gdot_neg,1e-10_preal)) ! current sense of shear direction
17932 
17933 # 338 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_kinehardening.f90"
17934 
17935 !--------------------------------------------------------------------------------------------------
17936 ! switch in sense of shear?
17937  where(dneq(sense,stt%sense(:,of),0.1_preal))
17938  dlt%sense (:,of) = sense - stt%sense(:,of) ! switch sense
17939  dlt%chi0 (:,of) = abs(stt%crss_back(:,of)) - stt%chi0(:,of) ! remember current backstress magnitude
17940  dlt%gamma0(:,of) = stt%accshear(:,of) - stt%gamma0(:,of) ! remember current accumulated shear
17941  else where
17942  dlt%sense (:,of) = 0.0_preal
17943  dlt%chi0 (:,of) = 0.0_preal
17944  dlt%gamma0(:,of) = 0.0_preal
17945  end where
17946 
17947  end associate
17948 
17949 end subroutine plastic_kinehardening_deltastate
17950 
17951 
17952 !--------------------------------------------------------------------------------------------------
17954 !--------------------------------------------------------------------------------------------------
17955 module subroutine plastic_kinehardening_results(instance,group)
17956 
17957  integer, intent(in) :: instance
17958  character(len=*), intent(in) :: group
17959 
17960  integer :: o
17961 
17962  associate(prm => param(instance), stt => state(instance))
17963  outputsloop: do o = 1,size(prm%output)
17964  select case(trim(prm%output(o)))
17965  case('resistance')
17966  if(prm%sum_N_sl>0) call results_writedataset(group,stt%crss,'xi_sl', &
17967  'resistance against plastic slip','Pa')
17968  case('backstress') ! ToDo: should be 'tau_back'
17969  if(prm%sum_N_sl>0) call results_writedataset(group,stt%crss_back,'tau_back', &
17970  'back stress against plastic slip','Pa')
17971  case ('sense')
17972  if(prm%sum_N_sl>0) call results_writedataset(group,stt%sense,'sense_of_shear', &
17973  'tbd','1')
17974  case ('chi0')
17975  if(prm%sum_N_sl>0) call results_writedataset(group,stt%chi0,'chi0', &
17976  'tbd','Pa')
17977  case ('gamma0')
17978  if(prm%sum_N_sl>0) call results_writedataset(group,stt%gamma0,'gamma0', &
17979  'tbd','1')
17980  case ('accumulatedshear')
17981  if(prm%sum_N_sl>0) call results_writedataset(group,stt%accshear,'gamma_sl', &
17982  'plastic shear','1')
17983  end select
17984  enddo outputsloop
17985  end associate
17986 
17987 end subroutine plastic_kinehardening_results
17988 
17989 
17990 !--------------------------------------------------------------------------------------------------
17992 ! stress.
17994 ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
17995 ! have the optional arguments at the end.
17996 !--------------------------------------------------------------------------------------------------
17997 pure subroutine kinetics(Mp,instance,of, &
17998  gdot_pos,gdot_neg,dgdot_dtau_pos,dgdot_dtau_neg)
18000  real(preal), dimension(3,3), intent(in) :: &
18001  mp
18002  integer, intent(in) :: &
18003  instance, &
18004  of
18005 
18006  real(preal), intent(out), dimension(param(instance)%sum_N_sl) :: &
18007  gdot_pos, &
18008  gdot_neg
18009  real(preal), intent(out), optional, dimension(param(instance)%sum_N_sl) :: &
18010  dgdot_dtau_pos, &
18011  dgdot_dtau_neg
18012 
18013  real(preal), dimension(param(instance)%sum_N_sl) :: &
18014  tau_pos, &
18015  tau_neg
18016  integer :: i
18017 
18018  associate(prm => param(instance), stt => state(instance))
18019 
18020  do i = 1, prm%sum_N_sl
18021  tau_pos(i) = math_tensordot(mp,prm%nonSchmid_pos(1:3,1:3,i)) - stt%crss_back(i,of)
18022  tau_neg(i) = merge(math_tensordot(mp,prm%nonSchmid_neg(1:3,1:3,i)) - stt%crss_back(i,of), &
18023  0.0_preal, prm%nonSchmidActive)
18024  enddo
18025 
18026  where(dneq0(tau_pos))
18027  gdot_pos = prm%gdot0 * merge(0.5_preal,1.0_preal, prm%nonSchmidActive) & ! 1/2 if non-Schmid active
18028  * sign(abs(tau_pos/stt%crss(:,of))**prm%n, tau_pos)
18029  else where
18030  gdot_pos = 0.0_preal
18031  end where
18032 
18033  where(dneq0(tau_neg))
18034  gdot_neg = prm%gdot0 * 0.5_preal & ! only used if non-Schmid active, always 1/2
18035  * sign(abs(tau_neg/stt%crss(:,of))**prm%n, tau_neg)
18036  else where
18037  gdot_neg = 0.0_preal
18038  end where
18039 
18040  if (present(dgdot_dtau_pos)) then
18041  where(dneq0(gdot_pos))
18042  dgdot_dtau_pos = gdot_pos*prm%n/tau_pos
18043  else where
18044  dgdot_dtau_pos = 0.0_preal
18045  end where
18046  endif
18047  if (present(dgdot_dtau_neg)) then
18048  where(dneq0(gdot_neg))
18049  dgdot_dtau_neg = gdot_neg*prm%n/tau_neg
18050  else where
18051  dgdot_dtau_neg = 0.0_preal
18052  end where
18053  endif
18054  end associate
18055 
18056 end subroutine kinetics
18057 
18058 end submodule plastic_kinehardening
18059 # 41 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
18060 
18061 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_dislotwin.f90" 1
18062 !--------------------------------------------------------------------------------------------------
18070 !--------------------------------------------------------------------------------------------------
18071 submodule(constitutive) plastic_dislotwin
18072 
18073  real(preal), parameter :: &
18074  kb = 1.38e-23_preal
18075 
18076  type :: tparameters
18077  real(preal) :: &
18078  mu = 1.0_preal, &
18079  nu = 1.0_preal, &
18080  d0 = 1.0_preal, &
18081  qsd = 1.0_preal, &
18082  omega = 1.0_preal, &
18083  d = 1.0_preal, &
18084  p_sb = 1.0_preal, &
18085  q_sb = 1.0_preal, &
18086  cedgedipmindistance = 1.0_preal, &
18087  i_tw = 1.0_preal, &
18088  tau_0 = 1.0_preal, &
18089  l_tw = 1.0_preal, &
18090  l_tr = 1.0_preal, &
18091  xc_twin = 1.0_preal, &
18092  xc_trans = 1.0_preal, &
18093  v_cs = 1.0_preal, &
18094  sbresistance = 1.0_preal, &
18095  sbvelocity = 1.0_preal, &
18096  e_sb = 1.0_preal, &
18097  sfe_0k = 1.0_preal, &
18098  dsfe_dt = 1.0_preal, &
18099  gamma_fcc_hex = 1.0_preal, &
18100  i_tr = 1.0_preal, &
18101  h = 1.0_preal
18102  real(preal), allocatable, dimension(:) :: &
18103  b_sl, & !< absolute length of burgers vector [m] for each slip system
18104  b_tw, & !< absolute length of burgers vector [m] for each twin system
18105  b_tr, & !< absolute length of burgers vector [m] for each transformation system
18106  delta_f,& !< activation energy for glide [J] for each slip system
18107  v0, & !< dislocation velocity prefactor [m/s] for each slip system
18108  dot_n_0_tw, & !< twin nucleation rate [1/m�s] for each twin system dot_N_0_tr, & !< trans nucleation rate [1/m³s] for each trans system t_tw, & !< twin thickness [m] for each twin system CLambdaSlip, & !< Adj. parameter for distance between 2 forest dislocations for each slip system t_tr, & !< martensite lamellar thickness [m] for each trans system and instance p, & !< p-exponent in glide velocity q, & !< q-exponent in glide velocity r, & !< r-exponent in twin nucleation rate s, & !< s-exponent in trans nucleation rate gamma_char, & !< characteristic shear for twins B !< drag coefficient real(pReal), allocatable, dimension(:,:) :: & h_sl_sl, & !< h_sl_tw, & !< h_tw_tw, & !< h_sl_tr, & !< h_tr_tr, & !< n0_sl, & !< slip system normal forestProjection, & C66 real(pReal), allocatable, dimension(:,:,:) :: & P_sl, & P_tw, & P_tr, & C66_tw, & C66_tr integer :: & sum_N_sl, & !< total number of active slip system sum_N_tw, & !< total number of active twin system sum_N_tr !< total number of active transformation system integer, allocatable, dimension(:,:) :: & fcc_twinNucleationSlipPair ! ToDo: Better name? Is also use for trans character(len=pStringLen), allocatable, dimension(:) :: & output logical :: & ExtendedDislocations, & !< consider split into partials for climb calculation fccTwinTransNucleation, & !< twinning and transformation models are for fcc dipoleFormation !< flag indicating consideration of dipole formation end type !< container type for internal constitutive parameters type :: tDislotwinState real(pReal), dimension(:,:), pointer :: & rho_mob, & rho_dip, & gamma_sl, & f_tw, & f_tr end type tDislotwinState type :: tDislotwinMicrostructure real(pReal), dimension(:,:), allocatable :: & Lambda_sl, & !< mean free path between 2 obstacles seen by a moving dislocation Lambda_tw, & !< mean free path between 2 obstacles seen by a growing twin Lambda_tr, & !< mean free path between 2 obstacles seen by a growing martensite tau_pass, & tau_hat_tw, & tau_hat_tr, & V_tw, & !< volume of a new twin V_tr, & !< volume of a new martensite disc tau_r_tw, & !< stress to bring partials close together (twin) tau_r_tr !< stress to bring partials close together (trans) end type tDislotwinMicrostructure !-------------------------------------------------------------------------------------------------- ! containers for parameters and state type(tParameters), allocatable, dimension(:) :: param type(tDislotwinState), allocatable, dimension(:) :: & dotState, & state type(tDislotwinMicrostructure), allocatable, dimension(:) :: dependentState contains !-------------------------------------------------------------------------------------------------- !> @brief Perform module initialization. !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- module subroutine plastic_dislotwin_init integer :: & Ninstance, & p, i, & NipcMyPhase, & sizeState, sizeDotState, & startIndex, endIndex integer, dimension(:), allocatable :: & N_sl, N_tw, N_tr real(pReal), allocatable, dimension(:) :: & rho_mob_0, & !< initial unipolar dislocation density per slip system rho_dip_0 !< initial dipole dislocation density per slip system character(len=pStringLen) :: & extmsg = '' write(6,'(/,a)') ' <<<+- constitutive_'//PLASTICITY_DISLOTWIN_LABEL//' init -+>>>'; flush(6) write(6,'(/,a)') ' Ma and Roters, Acta Materialia 52(12):3603–3612, 2004' write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2004.04.012' write(6,'(/,a)') ' Roters et al., Computational Materials Science 39:91–95, 2007' write(6,'(a)') ' https://doi.org/10.1016/j.commatsci.2006.04.014' write(6,'(/,a)') ' Wong et al., Acta Materialia 118:140–151, 2016' write(6,'(a,/)') ' https://doi.org/10.1016/j.actamat.2016.07.032' Ninstance = count(phase_plasticity == PLASTICITY_DISLOTWIN_ID) if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & write(6,'(a16,1x,i5,/)') '# instances:',Ninstance allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(dotState(Ninstance)) allocate(dependentState(Ninstance)) do p = 1, size(phase_plasticity) if (phase_plasticity(p) /= PLASTICITY_DISLOTWIN_ID) cycle associate(prm => param(phase_plasticityInstance(p)), & dot => dotState(phase_plasticityInstance(p)), & stt => state(phase_plasticityInstance(p)), & dst => dependentState(phase_plasticityInstance(p)), & config => config_phase(p)) prm%output = config%getStrings('(output)', defaultVal=emptyStringArray) ! This data is read in already in lattice prm%mu = lattice_mu(p) prm%nu = lattice_nu(p) prm%C66 = lattice_C66(1:6,1:6,p) !-------------------------------------------------------------------------------------------------- ! slip related parameters N_sl = config%getInts('nslip',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%P_sl = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,config%getFloats('interaction_slipslip'), & config%getString('lattice_structure')) prm%forestProjection = lattice_forestProjection_edge(N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%forestProjection = transpose(prm%forestProjection) prm%n0_sl = lattice_slip_normal(N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%fccTwinTransNucleation = merge(.true., .false., lattice_structure(p) == lattice_FCC_ID) & .and. (N_sl(1) == 12) if(prm%fccTwinTransNucleation) prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(N_sl)) rho_dip_0 = config%getFloats('rhoedgedip0',requiredSize=size(N_sl)) prm%v0 = config%getFloats('v0', requiredSize=size(N_sl)) prm%b_sl = config%getFloats('slipburgers',requiredSize=size(N_sl)) prm%Delta_F = config%getFloats('qedge', requiredSize=size(N_sl)) prm%CLambdaSlip = config%getFloats('clambdaslip',requiredSize=size(N_sl)) prm%p = config%getFloats('p_slip', requiredSize=size(N_sl)) prm%q = config%getFloats('q_slip', requiredSize=size(N_sl)) prm%B = config%getFloats('b', requiredSize=size(N_sl), & defaultVal=[(0.0_pReal, i=1,size(N_sl))]) prm%tau_0 = config%getFloat('solidsolutionstrength') prm%CEdgeDipMinDistance = config%getFloat('cedgedipmindistance') prm%D0 = config%getFloat('d0') prm%Qsd = config%getFloat('qsd') prm%ExtendedDislocations = config%keyExists('/extend_dislocations/') if (prm%ExtendedDislocations) then prm%SFE_0K = config%getFloat('sfe_0k') prm%dSFE_dT = config%getFloat('dsfe_dt') endif prm%dipoleformation = .not. config%keyExists('/nodipoleformation/') ! multiplication factor according to crystal structure (nearest neighbors bcc vs fcc/hex) ! details: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981 prm%omega = config%getFloat('omega', defaultVal = 1000.0_pReal) & * merge(12.0_pReal,8.0_pReal,any(lattice_structure(p) == [lattice_FCC_ID,lattice_HEX_ID])) ! expand: family => system rho_mob_0 = math_expand(rho_mob_0, N_sl) rho_dip_0 = math_expand(rho_dip_0, N_sl) prm%v0 = math_expand(prm%v0, N_sl) prm%b_sl = math_expand(prm%b_sl, N_sl) prm%Delta_F = math_expand(prm%Delta_F, N_sl) prm%CLambdaSlip = math_expand(prm%CLambdaSlip, N_sl) prm%p = math_expand(prm%p, N_sl) prm%q = math_expand(prm%q, N_sl) prm%B = math_expand(prm%B, N_sl) ! sanity checks if ( prm%D0 <= 0.0_pReal) extmsg = trim(extmsg)//' D0' if ( prm%Qsd <= 0.0_pReal) extmsg = trim(extmsg)//' Qsd' if (any(rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_mob_0' if (any(rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_dip_0' if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v0' if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl' if (any(prm%Delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' Delta_F' if (any(prm%CLambdaSlip <= 0.0_pReal)) extmsg = trim(extmsg)//' CLambdaSlip' if (any(prm%B < 0.0_pReal)) extmsg = trim(extmsg)//' B' if (any(prm%p<=0.0_pReal .or. prm%p>1.0_pReal)) extmsg = trim(extmsg)//' p' if (any(prm%q< 1.0_pReal .or. prm%q>2.0_pReal)) extmsg = trim(extmsg)//' q' else slipActive rho_mob_0 = emptyRealArray; rho_dip_0 = emptyRealArray allocate(prm%b_sl,prm%Delta_F,prm%v0,prm%CLambdaSlip,prm%p,prm%q,prm%B,source=emptyRealArray) allocate(prm%forestProjection(0,0),prm%h_sl_sl(0,0)) endif slipActive !-------------------------------------------------------------------------------------------------- ! twin related parameters N_tw = config%getInts('ntwin', defaultVal=emptyIntArray) prm%sum_N_tw = sum(abs(N_tw)) twinActive: if (prm%sum_N_tw > 0) then prm%P_tw = lattice_SchmidMatrix_twin(N_tw,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%h_tw_tw = lattice_interaction_TwinByTwin(N_tw,& config%getFloats('interaction_twintwin'), & config%getString('lattice_structure')) prm%b_tw = config%getFloats('twinburgers', requiredSize=size(N_tw)) prm%t_tw = config%getFloats('twinsize', requiredSize=size(N_tw)) prm%r = config%getFloats('r_twin', requiredSize=size(N_tw)) prm%xc_twin = config%getFloat('xc_twin') prm%L_tw = config%getFloat('l0_twin') prm%i_tw = config%getFloat('cmfptwin') prm%gamma_char= lattice_characteristicShear_Twin(N_tw,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%C66_tw = lattice_C66_twin(N_tw,prm%C66,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) if (.not. prm%fccTwinTransNucleation) then prm%dot_N_0_tw = config%getFloats('ndot0_twin') prm%dot_N_0_tw = math_expand(prm%dot_N_0_tw,N_tw) endif ! expand: family => system prm%b_tw = math_expand(prm%b_tw,N_tw) prm%t_tw = math_expand(prm%t_tw,N_tw) prm%r = math_expand(prm%r,N_tw) ! sanity checks if ( prm%xc_twin < 0.0_pReal) extmsg = trim(extmsg)//' xc_twin' if ( prm%L_tw < 0.0_pReal) extmsg = trim(extmsg)//' L_tw' if ( prm%i_tw < 0.0_pReal) extmsg = trim(extmsg)//' i_tw' if (any(prm%b_tw < 0.0_pReal)) extmsg = trim(extmsg)//' b_tw' if (any(prm%t_tw < 0.0_pReal)) extmsg = trim(extmsg)//' t_tw' if (any(prm%r < 0.0_pReal)) extmsg = trim(extmsg)//' r' if (.not. prm%fccTwinTransNucleation) then if (any(prm%dot_N_0_tw < 0.0_pReal)) extmsg = trim(extmsg)//' dot_N_0_tw' endif else twinActive allocate(prm%gamma_char,prm%b_tw,prm%dot_N_0_tw,prm%t_tw,prm%r,source=emptyRealArray) allocate(prm%h_tw_tw(0,0)) endif twinActive !-------------------------------------------------------------------------------------------------- ! transformation related parameters N_tr = config%getInts('ntrans', defaultVal=emptyIntArray) prm%sum_N_tr = sum(abs(N_tr)) transActive: if (prm%sum_N_tr > 0) then prm%b_tr = config%getFloats('transburgers') prm%b_tr = math_expand(prm%b_tr,N_tr) prm%h = config%getFloat('transstackheight', defaultVal=0.0_pReal) ! ToDo: How to handle that??? prm%i_tr = config%getFloat('cmfptrans', defaultVal=0.0_pReal) ! ToDo: How to handle that??? prm%gamma_fcc_hex = config%getFloat('deltag') prm%xc_trans = config%getFloat('xc_trans', defaultVal=0.0_pReal) ! ToDo: How to handle that??? prm%L_tr = config%getFloat('l0_trans') prm%h_tr_tr = lattice_interaction_TransByTrans(N_tr,config%getFloats('interaction_transtrans'), & config%getString('lattice_structure')) prm%C66_tr = lattice_C66_trans(N_tr,prm%C66,config%getString('trans_lattice_structure'), & 0.0_pReal, & config%getFloat('a_bcc', defaultVal=0.0_pReal), & config%getFloat('a_fcc', defaultVal=0.0_pReal)) prm%P_tr = lattice_SchmidMatrix_trans(N_tr,config%getString('trans_lattice_structure'), & 0.0_pReal, & config%getFloat('a_bcc', defaultVal=0.0_pReal), & config%getFloat('a_fcc', defaultVal=0.0_pReal)) if (lattice_structure(p) /= lattice_FCC_ID) then prm%dot_N_0_tr = config%getFloats('ndot0_trans') prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,N_tr) endif prm%t_tr = config%getFloats('lamellarsize') prm%t_tr = math_expand(prm%t_tr,N_tr) prm%s = config%getFloats('s_trans',defaultVal=[0.0_pReal]) prm%s = math_expand(prm%s,N_tr) ! sanity checks if ( prm%xc_trans < 0.0_pReal) extmsg = trim(extmsg)//' xc_trans' if ( prm%L_tr < 0.0_pReal) extmsg = trim(extmsg)//' L_tr' if ( prm%i_tr < 0.0_pReal) extmsg = trim(extmsg)//' i_tr' if (any(prm%t_tr < 0.0_pReal)) extmsg = trim(extmsg)//' t_tr' if (any(prm%s < 0.0_pReal)) extmsg = trim(extmsg)//' s' if (lattice_structure(p) /= lattice_FCC_ID) then if (any(prm%dot_N_0_tr < 0.0_pReal)) extmsg = trim(extmsg)//' dot_N_0_tr' endif else transActive allocate(prm%s,prm%b_tr,prm%t_tr,prm%dot_N_0_tr,source=emptyRealArray) allocate(prm%h_tr_tr(0,0)) endif transActive !-------------------------------------------------------------------------------------------------- ! shearband related parameters prm%sbVelocity = config%getFloat('shearbandvelocity',defaultVal=0.0_pReal) if (prm%sbVelocity > 0.0_pReal) then prm%sbResistance = config%getFloat('shearbandresistance') prm%E_sb = config%getFloat('qedgepersbsystem') prm%p_sb = config%getFloat('p_shearband') prm%q_sb = config%getFloat('q_shearband') ! sanity checks if (prm%sbResistance < 0.0_pReal) extmsg = trim(extmsg)//' shearbandresistance' if (prm%E_sb < 0.0_pReal) extmsg = trim(extmsg)//' qedgepersbsystem' if (prm%p_sb <= 0.0_pReal) extmsg = trim(extmsg)//' p_shearband' if (prm%q_sb <= 0.0_pReal) extmsg = trim(extmsg)//' q_shearband' endif !-------------------------------------------------------------------------------------------------- ! parameters required for several mechanisms and their interactions if(prm%sum_N_sl + prm%sum_N_tw + prm%sum_N_tw > 0) & prm%D = config%getFloat('grainsize') twinOrSlipActive: if (prm%sum_N_tw + prm%sum_N_tr > 0) then prm%SFE_0K = config%getFloat('sfe_0k') prm%dSFE_dT = config%getFloat('dsfe_dt') prm%V_cs = config%getFloat('vcrossslip') endif twinOrSlipActive slipAndTwinActive: if (prm%sum_N_sl * prm%sum_N_tw > 0) then prm%h_sl_tw = lattice_interaction_SlipByTwin(N_sl,N_tw,& config%getFloats('interaction_sliptwin'), & config%getString('lattice_structure')) if (prm%fccTwinTransNucleation .and. size(N_tw) /= 1) extmsg = trim(extmsg)//' interaction_sliptwin' endif slipAndTwinActive slipAndTransActive: if (prm%sum_N_sl * prm%sum_N_tr > 0) then prm%h_sl_tr = lattice_interaction_SlipByTrans(N_sl,N_tr,& config%getFloats('interaction_sliptrans'), & config%getString('lattice_structure')) if (prm%fccTwinTransNucleation .and. size(N_tr) /= 1) extmsg = trim(extmsg)//' interaction_sliptrans' endif slipAndTransActive !-------------------------------------------------------------------------------------------------- ! allocate state arrays NipcMyPhase = count(material_phaseAt == p) * discretization_nIP sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl & + size(['f_tw']) * prm%sum_N_tw & + size(['f_tr']) * prm%sum_N_tr sizeState = sizeDotState call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0) !-------------------------------------------------------------------------------------------------- ! locally defined state aliases and initialization of state0 and atol startIndex = 1 endIndex = prm%sum_N_sl stt%rho_mob=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_mob= spread(rho_mob_0,2,NipcMyPhase) dot%rho_mob=>plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%rho_dip=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_dip= spread(rho_dip_0,2,NipcMyPhase) dot%rho_dip=>plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%gamma_sl=>plasticState(p)%state(startIndex:endIndex,:) dot%gamma_sl=>plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = 1.0e-2_pReal ! global alias plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_tw stt%f_tw=>plasticState(p)%state(startIndex:endIndex,:) dot%f_tw=>plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('f_twin',defaultVal=1.0e-7_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_twin' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_tr stt%f_tr=>plasticState(p)%state(startIndex:endIndex,:) dot%f_tr=>plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('f_trans',defaultVal=1.0e-6_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_trans' allocate(dst%Lambda_sl (prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_pass (prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) allocate(dst%Lambda_tw (prm%sum_N_tw,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_hat_tw (prm%sum_N_tw,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_r_tw (prm%sum_N_tw,NipcMyPhase),source=0.0_pReal) allocate(dst%V_tw (prm%sum_N_tw,NipcMyPhase),source=0.0_pReal) allocate(dst%Lambda_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_hat_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_r_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal) allocate(dst%V_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal) plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally end associate !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOTWIN_LABEL//')') enddo end subroutine plastic_dislotwin_init !-------------------------------------------------------------------------------------------------- !> @brief Return the homogenized elasticity matrix. !-------------------------------------------------------------------------------------------------- module function plastic_dislotwin_homogenizedC(ipc,ip,el) result(homogenizedC) real(pReal), dimension(6,6) :: & homogenizedC integer, intent(in) :: & ipc, & !< component-ID of integration point ip, & !< integration point el !< element integer :: i, & of real(pReal) :: f_unrotated of = material_phasememberAt(ipc,ip,el) associate(prm => param(phase_plasticityInstance(material_phaseAt(ipc,el))),& stt => state(phase_plasticityInstance(material_phaseAT(ipc,el)))) f_unrotated = 1.0_pReal & - sum(stt%f_tw(1:prm%sum_N_tw,of)) & - sum(stt%f_tr(1:prm%sum_N_tr,of)) homogenizedC = f_unrotated * prm%C66 do i=1,prm%sum_N_tw homogenizedC = homogenizedC & + stt%f_tw(i,of)*prm%C66_tw(1:6,1:6,i) enddo do i=1,prm%sum_N_tr homogenizedC = homogenizedC & + stt%f_tr(i,of)*prm%C66_tr(1:6,1:6,i) enddo end associate end function plastic_dislotwin_homogenizedC !-------------------------------------------------------------------------------------------------- !> @brief Calculate plastic velocity gradient and its tangent. !-------------------------------------------------------------------------------------------------- module subroutine plastic_dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,instance,of) real(pReal), dimension(3,3), intent(out) :: Lp real(pReal), dimension(3,3,3,3), intent(out) :: dLp_dMp real(pReal), dimension(3,3), intent(in) :: Mp integer, intent(in) :: instance,of real(pReal), intent(in) :: T integer :: i,k,l,m,n real(pReal) :: & f_unrotated,StressRatio_p,& BoltzmannRatio, & ddot_gamma_dtau, & tau real(pReal), dimension(param(instance)%sum_N_sl) :: & dot_gamma_sl,ddot_gamma_dtau_slip real(pReal), dimension(param(instance)%sum_N_tw) :: & dot_gamma_twin,ddot_gamma_dtau_twin real(pReal), dimension(param(instance)%sum_N_tr) :: & dot_gamma_tr,ddot_gamma_dtau_trans real(pReal):: dot_gamma_sb real(pReal), dimension(3,3) :: eigVectors, P_sb real(pReal), dimension(3) :: eigValues real(pReal), dimension(3,6), parameter :: & sb_sComposition = & reshape(real([& 1, 0, 1, & 1, 0,-1, & 1, 1, 0, & 1,-1, 0, & 0, 1, 1, & 0, 1,-1 & ],pReal),[ 3,6]), & sb_mComposition = & reshape(real([& 1, 0,-1, & 1, 0,+1, & 1,-1, 0, & 1, 1, 0, & 0, 1,-1, & 0, 1, 1 & ],pReal),[ 3,6]) associate(prm => param(instance), stt => state(instance)) f_unrotated = 1.0_pReal & - sum(stt%f_tw(1:prm%sum_N_tw,of)) & - sum(stt%f_tr(1:prm%sum_N_tr,of)) Lp = 0.0_pReal dLp_dMp = 0.0_pReal call kinetics_slip(Mp,T,instance,of,dot_gamma_sl,ddot_gamma_dtau_slip) slipContribution: do i = 1, prm%sum_N_sl Lp = Lp + dot_gamma_sl(i)*prm%P_sl(1:3,1:3,i) forall (k=1:3,l=1:3,m=1:3,n=1:3) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & + ddot_gamma_dtau_slip(i) * prm%P_sl(k,l,i) * prm%P_sl(m,n,i) enddo slipContribution !ToDo: Why do this before shear banding? Lp = Lp * f_unrotated dLp_dMp = dLp_dMp * f_unrotated shearBandingContribution: if(dNeq0(prm%sbVelocity)) then BoltzmannRatio = prm%E_sb/(kB*T) call math_eigh33(Mp,eigValues,eigVectors) ! is Mp symmetric by design? do i = 1,6 P_sb = 0.5_pReal * math_outer(matmul(eigVectors,sb_sComposition(1:3,i)),& matmul(eigVectors,sb_mComposition(1:3,i))) tau = math_tensordot(Mp,P_sb) significantShearBandStress: if (abs(tau) > tol_math_check) then StressRatio_p = (abs(tau)/prm%sbResistance)**prm%p_sb dot_gamma_sb = sign(prm%sbVelocity*exp(-BoltzmannRatio*(1-StressRatio_p)**prm%q_sb), tau) ddot_gamma_dtau = abs(dot_gamma_sb)*BoltzmannRatio* prm%p_sb*prm%q_sb/ prm%sbResistance & * (abs(tau)/prm%sbResistance)**(prm%p_sb-1.0_pReal) & * (1.0_pReal-StressRatio_p)**(prm%q_sb-1.0_pReal) Lp = Lp + dot_gamma_sb * P_sb forall (k=1:3,l=1:3,m=1:3,n=1:3) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & + ddot_gamma_dtau * P_sb(k,l) * P_sb(m,n) endif significantShearBandStress enddo endif shearBandingContribution call kinetics_twin(Mp,T,dot_gamma_sl,instance,of,dot_gamma_twin,ddot_gamma_dtau_twin) twinContibution: do i = 1, prm%sum_N_tw Lp = Lp + dot_gamma_twin(i)*prm%P_tw(1:3,1:3,i) * f_unrotated forall (k=1:3,l=1:3,m=1:3,n=1:3) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & + ddot_gamma_dtau_twin(i)* prm%P_tw(k,l,i)*prm%P_tw(m,n,i) * f_unrotated enddo twinContibution call kinetics_trans(Mp,T,dot_gamma_sl,instance,of,dot_gamma_tr,ddot_gamma_dtau_trans) transContibution: do i = 1, prm%sum_N_tr Lp = Lp + dot_gamma_tr(i)*prm%P_tr(1:3,1:3,i) * f_unrotated forall (k=1:3,l=1:3,m=1:3,n=1:3) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & + ddot_gamma_dtau_trans(i)* prm%P_tr(k,l,i)*prm%P_tr(m,n,i) * f_unrotated enddo transContibution end associate end subroutine plastic_dislotwin_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief Calculate the rate of change of microstructure. !-------------------------------------------------------------------------------------------------- module subroutine plastic_dislotwin_dotState(Mp,T,instance,of) real(pReal), dimension(3,3), intent(in):: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature at integration point integer, intent(in) :: & instance, & of integer :: i real(pReal) :: & f_unrotated, & rho_dip_distance, & v_cl, & !< climb velocity Gamma, & !< stacking fault energy tau, & sigma_cl, & !< climb stress b_d !< ratio of burgers vector to stacking fault width real(pReal), dimension(param(instance)%sum_N_sl) :: & dot_rho_dip_formation, & dot_rho_dip_climb, & rho_dip_distance_min, & dot_gamma_sl real(pReal), dimension(param(instance)%sum_N_tw) :: & dot_gamma_twin real(pReal), dimension(param(instance)%sum_N_tr) :: & dot_gamma_tr associate(prm => param(instance), stt => state(instance), & dot => dotState(instance), dst => dependentState(instance)) f_unrotated = 1.0_pReal & - sum(stt%f_tw(1:prm%sum_N_tw,of)) & - sum(stt%f_tr(1:prm%sum_N_tr,of)) call kinetics_slip(Mp,T,instance,of,dot_gamma_sl) dot%gamma_sl(:,of) = abs(dot_gamma_sl) rho_dip_distance_min = prm%CEdgeDipMinDistance*prm%b_sl slipState: do i = 1, prm%sum_N_sl tau = math_tensordot(Mp,prm%P_sl(1:3,1:3,i)) significantSlipStress: if (dEq0(tau)) then dot_rho_dip_formation(i) = 0.0_pReal dot_rho_dip_climb(i) = 0.0_pReal else significantSlipStress rho_dip_distance = 3.0_pReal*prm%mu*prm%b_sl(i)/(16.0_pReal*PI*abs(tau)) rho_dip_distance = math_clip(rho_dip_distance, right = dst%Lambda_sl(i,of)) rho_dip_distance = math_clip(rho_dip_distance, left = rho_dip_distance_min(i)) if (prm%dipoleFormation) then dot_rho_dip_formation(i) = 2.0_pReal*(rho_dip_distance-rho_dip_distance_min(i))/prm%b_sl(i) & * stt%rho_mob(i,of)*abs(dot_gamma_sl(i)) else dot_rho_dip_formation(i) = 0.0_pReal endif if (dEq(rho_dip_distance,rho_dip_distance_min(i))) then dot_rho_dip_climb(i) = 0.0_pReal else !@details: Refer: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981 sigma_cl = dot_product(prm%n0_sl(1:3,i),matmul(Mp,prm%n0_sl(1:3,i))) if (prm%ExtendedDislocations) then Gamma = prm%SFE_0K + prm%dSFE_dT * T b_d = 24.0_pReal*PI*(1.0_pReal - prm%nu)/(2.0_pReal + prm%nu)* Gamma/(prm%mu*prm%b_sl(i)) else b_d = 1.0_pReal endif v_cl = 2.0_pReal*prm%omega*b_d**2.0_pReal*exp(-prm%Qsd/(kB*T)) & * (exp(abs(sigma_cl)*prm%b_sl(i)**3.0_pReal/(kB*T)) - 1.0_pReal) dot_rho_dip_climb(i) = 4.0_pReal*v_cl*stt%rho_dip(i,of) & / (rho_dip_distance-rho_dip_distance_min(i)) endif endif significantSlipStress enddo slipState dot%rho_mob(:,of) = abs(dot_gamma_sl)/(prm%b_sl*dst%Lambda_sl(:,of)) & - dot_rho_dip_formation & - 2.0_pReal*rho_dip_distance_min/prm%b_sl * stt%rho_mob(:,of)*abs(dot_gamma_sl) dot%rho_dip(:,of) = dot_rho_dip_formation & - 2.0_pReal*rho_dip_distance_min/prm%b_sl * stt%rho_dip(:,of)*abs(dot_gamma_sl) & - dot_rho_dip_climb call kinetics_twin(Mp,T,dot_gamma_sl,instance,of,dot_gamma_twin) dot%f_tw(:,of) = f_unrotated*dot_gamma_twin/prm%gamma_char call kinetics_trans(Mp,T,dot_gamma_sl,instance,of,dot_gamma_tr) dot%f_tr(:,of) = f_unrotated*dot_gamma_tr end associate end subroutine plastic_dislotwin_dotState !-------------------------------------------------------------------------------------------------- !> @brief Calculate derived quantities from state. !-------------------------------------------------------------------------------------------------- module subroutine plastic_dislotwin_dependentState(T,instance,of) integer, intent(in) :: & instance, & of real(pReal), intent(in) :: & T real(pReal) :: & sumf_twin,Gamma,sumf_trans real(pReal), dimension(param(instance)%sum_N_sl) :: & inv_lambda_sl_sl, & !< 1/mean free distance between 2 forest dislocations seen by a moving dislocation inv_lambda_sl_tw, & !< 1/mean free distance between 2 twin stacks from different systems seen by a moving dislocation inv_lambda_sl_tr !< 1/mean free distance between 2 martensite lamellar from different systems seen by a moving dislocation real(pReal), dimension(param(instance)%sum_N_tw) :: & inv_lambda_tw_tw, & !< 1/mean free distance between 2 twin stacks from different systems seen by a growing twin f_over_t_tw real(pReal), dimension(param(instance)%sum_N_tr) :: & inv_lambda_tr_tr, & !< 1/mean free distance between 2 martensite stacks from different systems seen by a growing martensite f_over_t_tr real(pReal), dimension(:), allocatable :: & x0 associate(prm => param(instance),& stt => state(instance),& dst => dependentState(instance)) sumf_twin = sum(stt%f_tw(1:prm%sum_N_tw,of)) sumf_trans = sum(stt%f_tr(1:prm%sum_N_tr,of)) Gamma = prm%SFE_0K + prm%dSFE_dT * T !* rescaled volume fraction for topology f_over_t_tw = stt%f_tw(1:prm%sum_N_tw,of)/prm%t_tw ! this is per system ... f_over_t_tr = sumf_trans/prm%t_tr ! but this not ! ToDo ...Physically correct, but naming could be adjusted inv_lambda_sl_sl = sqrt(matmul(prm%forestProjection, & stt%rho_mob(:,of)+stt%rho_dip(:,of)))/prm%CLambdaSlip if (prm%sum_N_tw > 0 .and. prm%sum_N_sl > 0) & inv_lambda_sl_tw = matmul(prm%h_sl_tw,f_over_t_tw)/(1.0_pReal-sumf_twin) inv_lambda_tw_tw = matmul(prm%h_tw_tw,f_over_t_tw)/(1.0_pReal-sumf_twin) if (prm%sum_N_tr > 0 .and. prm%sum_N_sl > 0) & inv_lambda_sl_tr = matmul(prm%h_sl_tr,f_over_t_tr)/(1.0_pReal-sumf_trans) inv_lambda_tr_tr = matmul(prm%h_tr_tr,f_over_t_tr)/(1.0_pReal-sumf_trans) if ((prm%sum_N_tw > 0) .or. (prm%sum_N_tr > 0)) then ! ToDo: better logic needed here dst%Lambda_sl(:,of) = prm%D & / (1.0_pReal+prm%D*(inv_lambda_sl_sl + inv_lambda_sl_tw + inv_lambda_sl_tr)) else dst%Lambda_sl(:,of) = prm%D & / (1.0_pReal+prm%D*inv_lambda_sl_sl) !!!!!! correct? endif dst%Lambda_tw(:,of) = prm%i_tw*prm%D/(1.0_pReal+prm%D*inv_lambda_tw_tw) dst%Lambda_tr(:,of) = prm%i_tr*prm%D/(1.0_pReal+prm%D*inv_lambda_tr_tr) !* threshold stress for dislocation motion dst%tau_pass(:,of) = prm%mu*prm%b_sl* sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of))) !* threshold stress for growing twin/martensite if(prm%sum_N_tw == prm%sum_N_sl) & dst%tau_hat_tw(:,of) = Gamma/(3.0_pReal*prm%b_tw) & + 3.0_pReal*prm%b_tw*prm%mu/(prm%L_tw*prm%b_sl) ! slip burgers here correct? if(prm%sum_N_tr == prm%sum_N_sl) & dst%tau_hat_tr(:,of) = Gamma/(3.0_pReal*prm%b_tr) & + 3.0_pReal*prm%b_tr*prm%mu/(prm%L_tr*prm%b_sl) & ! slip burgers here correct? + prm%h*prm%gamma_fcc_hex/ (3.0_pReal*prm%b_tr) dst%V_tw(:,of) = (PI/4.0_pReal)*prm%t_tw*dst%Lambda_tw(:,of)**2.0_pReal dst%V_tr(:,of) = (PI/4.0_pReal)*prm%t_tr*dst%Lambda_tr(:,of)**2.0_pReal x0 = prm%mu*prm%b_tw**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip and is the same for twin and trans dst%tau_r_tw(:,of) = prm%mu*prm%b_tw/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%xc_twin)+cos(pi/3.0_pReal)/x0) x0 = prm%mu*prm%b_tr**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip dst%tau_r_tr(:,of) = prm%mu*prm%b_tr/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%xc_trans)+cos(pi/3.0_pReal)/x0) end associate end subroutine plastic_dislotwin_dependentState !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- module subroutine plastic_dislotwin_results(instance,group) integer, intent(in) :: instance character(len=*), intent(in) :: group integer :: o associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) case('rho_mob') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_mob,'rho_mob',& 'mobile dislocation density','1/m²') case('rho_dip') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,'rho_dip',& 'dislocation dipole density''1/m²') case('gamma_sl') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,'gamma_sl',& 'plastic shear','1') case('lambda_sl') if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,'Lambda_sl',& 'mean free path for slip','m') case('tau_pass') if(prm%sum_N_sl>0) call results_writeDataset(group,dst%tau_pass,'tau_pass',& 'passing stress for slip','Pa') case('f_tw') if(prm%sum_N_tw>0) call results_writeDataset(group,stt%f_tw,'f_tw',& 'twinned volume fraction','m³/m³') case('lambda_tw') if(prm%sum_N_tw>0) call results_writeDataset(group,dst%Lambda_tw,'Lambda_tw',& 'mean free path for twinning','m') case('tau_hat_tw') if(prm%sum_N_tw>0) call results_writeDataset(group,dst%tau_hat_tw,'tau_hat_tw',& 'threshold stress for twinning','Pa') case('f_tr') if(prm%sum_N_tr>0) call results_writeDataset(group,stt%f_tr,'f_tr',& 'martensite volume fraction','m³/m³') end select enddo outputsLoop end associate end subroutine plastic_dislotwin_results !-------------------------------------------------------------------------------------------------- !> @brief Calculate shear rates on slip systems, their derivatives with respect to resolved ! stress, and the resolved stress. !> @details Derivatives and resolved stress are calculated only optionally. ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end !-------------------------------------------------------------------------------------------------- pure subroutine kinetics_slip(Mp,T,instance,of, & dot_gamma_sl,ddot_gamma_dtau_slip,tau_slip) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of real(pReal), dimension(param(instance)%sum_N_sl), intent(out) :: & dot_gamma_sl real(pReal), dimension(param(instance)%sum_N_sl), optional, intent(out) :: & ddot_gamma_dtau_slip, & tau_slip real(pReal), dimension(param(instance)%sum_N_sl) :: & ddot_gamma_dtau real(pReal), dimension(param(instance)%sum_N_sl) :: & tau, & stressRatio, & StressRatio_p, & BoltzmannRatio, & v_wait_inverse, & !< inverse of the effective velocity of a dislocation waiting at obstacles (unsigned) v_run_inverse, & !< inverse of the velocity of a free moving dislocation (unsigned) dV_wait_inverse_dTau, & dV_run_inverse_dTau, & dV_dTau, & tau_eff !< effective resolved stress integer :: i associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) do i = 1, prm%sum_N_sl tau(i) = math_tensordot(Mp,prm%P_sl(1:3,1:3,i)) enddo tau_eff = abs(tau)-dst%tau_pass(:,of) significantStress: where(tau_eff > tol_math_check) stressRatio = tau_eff/prm%tau_0 StressRatio_p = stressRatio** prm%p BoltzmannRatio = prm%Delta_F/(kB*T) v_wait_inverse = prm%v0**(-1.0_pReal) * exp(BoltzmannRatio*(1.0_pReal-StressRatio_p)** prm%q) v_run_inverse = prm%B/(tau_eff*prm%b_sl) dot_gamma_sl = sign(stt%rho_mob(:,of)*prm%b_sl/(v_wait_inverse+v_run_inverse),tau) dV_wait_inverse_dTau = -1.0_pReal * v_wait_inverse * prm%p * prm%q * BoltzmannRatio & * (stressRatio**(prm%p-1.0_pReal)) & * (1.0_pReal-StressRatio_p)**(prm%q-1.0_pReal) & / prm%tau_0 dV_run_inverse_dTau = -1.0_pReal * v_run_inverse/tau_eff dV_dTau = -1.0_pReal * (dV_wait_inverse_dTau+dV_run_inverse_dTau) & / (v_wait_inverse+v_run_inverse)**2.0_pReal ddot_gamma_dtau = dV_dTau*stt%rho_mob(:,of)*prm%b_sl else where significantStress dot_gamma_sl = 0.0_pReal ddot_gamma_dtau = 0.0_pReal end where significantStress end associate if(present(ddot_gamma_dtau_slip)) ddot_gamma_dtau_slip = ddot_gamma_dtau if(present(tau_slip)) tau_slip = tau end subroutine kinetics_slip !-------------------------------------------------------------------------------------------------- !> @brief Calculate shear rates on twin systems and their derivatives with respect to resolved ! stress. !> @details Derivatives are calculated only optionally. ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end. !-------------------------------------------------------------------------------------------------- pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,instance,of,& dot_gamma_twin,ddot_gamma_dtau_twin) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of real(pReal), dimension(param(instance)%sum_N_sl), intent(in) :: & dot_gamma_sl real(pReal), dimension(param(instance)%sum_N_tw), intent(out) :: & dot_gamma_twin real(pReal), dimension(param(instance)%sum_N_tw), optional, intent(out) :: & ddot_gamma_dtau_twin real, dimension(param(instance)%sum_N_tw) :: & tau, & Ndot0, & stressRatio_r, & ddot_gamma_dtau integer :: i,s1,s2 associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) do i = 1, prm%sum_N_tw tau(i) = math_tensordot(Mp,prm%P_tw(1:3,1:3,i)) isFCC: if (prm%fccTwinTransNucleation) then s1=prm%fcc_twinNucleationSlipPair(1,i) s2=prm%fcc_twinNucleationSlipPair(2,i) if (tau(i) < dst%tau_r_tw(i,of)) then ! ToDo: correct? Ndot0=(abs(dot_gamma_sl(s1))*(stt%rho_mob(s2,of)+stt%rho_dip(s2,of))+& abs(dot_gamma_sl(s2))*(stt%rho_mob(s1,of)+stt%rho_dip(s1,of)))/& ! ToDo: MD: it would be more consistent to use shearrates from state (prm%L_tw*prm%b_sl(i))*& (1.0_pReal-exp(-prm%V_cs/(kB*T)*(dst%tau_r_tw(i,of)-tau(i)))) ! P_ncs else Ndot0=0.0_pReal end if else isFCC Ndot0=prm%dot_N_0_tw(i) endif isFCC enddo significantStress: where(tau > tol_math_check) StressRatio_r = (dst%tau_hat_tw(:,of)/tau)**prm%r dot_gamma_twin = prm%gamma_char * dst%V_tw(:,of) * Ndot0*exp(-StressRatio_r) ddot_gamma_dtau = (dot_gamma_twin*prm%r/tau)*StressRatio_r else where significantStress dot_gamma_twin = 0.0_pReal ddot_gamma_dtau = 0.0_pReal end where significantStress end associate if(present(ddot_gamma_dtau_twin)) ddot_gamma_dtau_twin = ddot_gamma_dtau end subroutine kinetics_twin !-------------------------------------------------------------------------------------------------- !> @brief Calculate shear rates on transformation systems and their derivatives with respect to ! resolved stress. !> @details Derivatives are calculated only optionally. ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end. !-------------------------------------------------------------------------------------------------- pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,instance,of,& dot_gamma_tr,ddot_gamma_dtau_trans) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of real(pReal), dimension(param(instance)%sum_N_sl), intent(in) :: & dot_gamma_sl real(pReal), dimension(param(instance)%sum_N_tr), intent(out) :: & dot_gamma_tr real(pReal), dimension(param(instance)%sum_N_tr), optional, intent(out) :: & ddot_gamma_dtau_trans real, dimension(param(instance)%sum_N_tr) :: & tau, & Ndot0, & stressRatio_s, & ddot_gamma_dtau integer :: i,s1,s2 associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) do i = 1, prm%sum_N_tr tau(i) = math_tensordot(Mp,prm%P_tr(1:3,1:3,i)) isFCC: if (prm%fccTwinTransNucleation) then s1=prm%fcc_twinNucleationSlipPair(1,i) s2=prm%fcc_twinNucleationSlipPair(2,i) if (tau(i) < dst%tau_r_tr(i,of)) then ! ToDo: correct? Ndot0=(abs(dot_gamma_sl(s1))*(stt%rho_mob(s2,of)+stt%rho_dip(s2,of))+& abs(dot_gamma_sl(s2))*(stt%rho_mob(s1,of)+stt%rho_dip(s1,of)))/& ! ToDo: MD: it would be more consistent to use shearrates from state (prm%L_tr*prm%b_sl(i))*& (1.0_pReal-exp(-prm%V_cs/(kB*T)*(dst%tau_r_tr(i,of)-tau(i)))) ! P_ncs else Ndot0=0.0_pReal end if else isFCC Ndot0=prm%dot_N_0_tr(i) endif isFCC enddo significantStress: where(tau > tol_math_check) StressRatio_s = (dst%tau_hat_tr(:,of)/tau)**prm%s dot_gamma_tr = dst%V_tr(:,of) * Ndot0*exp(-StressRatio_s) ddot_gamma_dtau = (dot_gamma_tr*prm%s/tau)*StressRatio_s else where significantStress dot_gamma_tr = 0.0_pReal ddot_gamma_dtau = 0.0_pReal end where significantStress end associate if(present(ddot_gamma_dtau_trans)) ddot_gamma_dtau_trans = ddot_gamma_dtau end subroutine kinetics_trans end submodule plastic_dislotwin # 42 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_disloUCLA.f90" 1 !-------------------------------------------------------------------------------------------------- !> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @author David Cereceda, Lawrence Livermore National Laboratory !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH !> @brief crystal plasticity model for bcc metals, especially Tungsten !-------------------------------------------------------------------------------------------------- submodule(constitutive) plastic_disloUCLA real(pReal), parameter :: & kB = 1.38e-23_pReal !< Boltzmann constant in J/Kelvin type :: tParameters real(pReal) :: & D = 1.0_pReal, & !< grain size mu = 1.0_pReal, & !< equivalent shear modulus D_0 = 1.0_pReal, & !< prefactor for self-diffusion coefficient Q_cl = 1.0_pReal !< activation energy for dislocation climb real(pReal), allocatable, dimension(:) :: & b_sl, & !< magnitude of burgers vector [m] D_a, & i_sl, & !< Adj. parameter for distance between 2 forest dislocations atomicVolume, & tau_0, & !* mobility law parameters delta_F, & !< activation energy for glide [J] v0, & !< dislocation velocity prefactor [m/s] p, & !< p-exponent in glide velocity q, & !< q-exponent in glide velocity B, & !< friction coefficient kink_height, & !< height of the kink pair w, & !< width of the kink pair omega !< attempt frequency for kink pair nucleation real(pReal), allocatable, dimension(:,:) :: & h_sl_sl, & !< slip resistance from slip activity forestProjection real(pReal), allocatable, dimension(:,:,:) :: & P_sl, & nonSchmid_pos, & nonSchmid_neg integer :: & sum_N_sl !< total number of active slip system character(len=pStringLen), allocatable, dimension(:) :: & output logical :: & dipoleFormation !< flag indicating consideration of dipole formation end type !< container type for internal constitutive parameters type :: tDisloUCLAState real(pReal), dimension(:,:), pointer :: & rho_mob, & rho_dip, & gamma_sl end type tDisloUCLAState type :: tDisloUCLAdependentState real(pReal), dimension(:,:), allocatable :: & Lambda_sl, & threshold_stress end type tDisloUCLAdependentState !-------------------------------------------------------------------------------------------------- ! containers for parameters and state type(tParameters), allocatable, dimension(:) :: param type(tDisloUCLAState), allocatable, dimension(:) :: & dotState, & state type(tDisloUCLAdependentState), allocatable, dimension(:) :: dependentState contains !-------------------------------------------------------------------------------------------------- !> @brief Perform module initialization. !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- module subroutine plastic_disloUCLA_init integer :: & Ninstance, & p, i, & NipcMyPhase, & sizeState, sizeDotState, & startIndex, endIndex integer, dimension(:), allocatable :: & N_sl real(pReal),dimension(:), allocatable :: & rho_mob_0, & !< initial dislocation density rho_dip_0, & !< initial dipole density a !< non-Schmid coefficients character(len=pStringLen) :: & extmsg = '' write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_DISLOUCLA_LABEL//' init -+>>>'; flush(6) write(6,'(/,a)') ' Cereceda et al., International Journal of Plasticity 78:242–256, 2016' write(6,'(a)') ' https://dx.doi.org/10.1016/j.ijplas.2015.09.002' Ninstance = count(phase_plasticity == PLASTICITY_DISLOUCLA_ID) if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & write(6,'(a16,1x,i5,/)') '# instances:',Ninstance allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(dotState(Ninstance)) allocate(dependentState(Ninstance)) do p = 1, size(phase_plasticity) if (phase_plasticity(p) /= PLASTICITY_DISLOUCLA_ID) cycle associate(prm => param(phase_plasticityInstance(p)), & dot => dotState(phase_plasticityInstance(p)), & stt => state(phase_plasticityInstance(p)), & dst => dependentState(phase_plasticityInstance(p)), & config => config_phase(p)) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) ! This data is read in already in lattice prm%mu = lattice_mu(p) !-------------------------------------------------------------------------------------------------- ! slip related parameters N_sl = config%getInts('nslip',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%P_sl = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) if(trim(config%getString('lattice_structure')) == 'bcc') then a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray) prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1) else prm%nonSchmid_pos = prm%P_sl prm%nonSchmid_neg = prm%P_sl endif prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,config%getFloats('interaction_slipslip'), & config%getString('lattice_structure')) prm%forestProjection = lattice_forestProjection_edge(N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%forestProjection = transpose(prm%forestProjection) rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(N_sl)) rho_dip_0 = config%getFloats('rhoedgedip0', requiredSize=size(N_sl)) prm%v0 = config%getFloats('v0', requiredSize=size(N_sl)) prm%b_sl = config%getFloats('slipburgers', requiredSize=size(N_sl)) prm%delta_F = config%getFloats('qedge', requiredSize=size(N_sl)) prm%i_sl = config%getFloats('clambdaslip', requiredSize=size(N_sl)) prm%tau_0 = config%getFloats('tau_peierls', requiredSize=size(N_sl)) prm%p = config%getFloats('p_slip', requiredSize=size(N_sl), & defaultVal=[(1.0_pReal,i=1,size(N_sl))]) prm%q = config%getFloats('q_slip', requiredSize=size(N_sl), & defaultVal=[(1.0_pReal,i=1,size(N_sl))]) prm%kink_height = config%getFloats('kink_height', requiredSize=size(N_sl)) prm%w = config%getFloats('kink_width', requiredSize=size(N_sl)) prm%omega = config%getFloats('omega', requiredSize=size(N_sl)) prm%B = config%getFloats('friction_coeff', requiredSize=size(N_sl)) prm%D = config%getFloat('grainsize') prm%D_0 = config%getFloat('d0') prm%Q_cl = config%getFloat('qsd') prm%atomicVolume = config%getFloat('catomicvolume') * prm%b_sl**3.0_pReal prm%D_a = config%getFloat('cedgedipmindistance') * prm%b_sl prm%dipoleformation = config%getFloat('dipoleformationfactor') > 0.0_pReal !should be on by default, ToDo: change to /key/-type key ! expand: family => system rho_mob_0 = math_expand(rho_mob_0, N_sl) rho_dip_0 = math_expand(rho_dip_0, N_sl) prm%q = math_expand(prm%q, N_sl) prm%p = math_expand(prm%p, N_sl) prm%delta_F = math_expand(prm%delta_F, N_sl) prm%b_sl = math_expand(prm%b_sl, N_sl) prm%kink_height = math_expand(prm%kink_height, N_sl) prm%w = math_expand(prm%w, N_sl) prm%omega = math_expand(prm%omega, N_sl) prm%tau_0 = math_expand(prm%tau_0, N_sl) prm%v0 = math_expand(prm%v0, N_sl) prm%B = math_expand(prm%B, N_sl) prm%i_sl = math_expand(prm%i_sl, N_sl) prm%atomicVolume = math_expand(prm%atomicVolume, N_sl) prm%D_a = math_expand(prm%D_a, N_sl) ! sanity checks if ( prm%D_0 <= 0.0_pReal) extmsg = trim(extmsg)//' D_0' if ( prm%Q_cl <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl' if (any(rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedge0' if (any(rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedgedip0' if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v0' if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl' if (any(prm%delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' qedge' if (any(prm%tau_0 < 0.0_pReal)) extmsg = trim(extmsg)//' tau_0' if (any(prm%D_a <= 0.0_pReal)) extmsg = trim(extmsg)//' cedgedipmindistance or b_sl' if (any(prm%atomicVolume <= 0.0_pReal)) extmsg = trim(extmsg)//' catomicvolume or b_sl' else slipActive rho_mob_0= emptyRealArray; rho_dip_0 = emptyRealArray allocate(prm%b_sl,prm%D_a,prm%i_sl,prm%atomicVolume,prm%tau_0, & prm%delta_F,prm%v0,prm%p,prm%q,prm%B,prm%kink_height,prm%w,prm%omega, & source = emptyRealArray) allocate(prm%forestProjection(0,0)) allocate(prm%h_sl_sl (0,0)) endif slipActive !-------------------------------------------------------------------------------------------------- ! allocate state arrays NipcMyPhase = count(material_phaseAt == p) * discretization_nIP sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl sizeState = sizeDotState call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0) !-------------------------------------------------------------------------------------------------- ! state aliases and initialization startIndex = 1 endIndex = prm%sum_N_sl stt%rho_mob => plasticState(p)%state(startIndex:endIndex,:) stt%rho_mob = spread(rho_mob_0,2,NipcMyPhase) dot%rho_mob => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%rho_dip => plasticState(p)%state(startIndex:endIndex,:) stt%rho_dip = spread(rho_dip_0,2,NipcMyPhase) dot%rho_dip => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%gamma_sl => plasticState(p)%state(startIndex:endIndex,:) dot%gamma_sl => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = 1.0e-2_pReal ! global alias plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) allocate(dst%Lambda_sl(prm%sum_N_sl,NipcMyPhase), source=0.0_pReal) allocate(dst%threshold_stress(prm%sum_N_sl,NipcMyPhase), source=0.0_pReal) plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally end associate !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOUCLA_LABEL//')') enddo end subroutine plastic_disloUCLA_init !-------------------------------------------------------------------------------------------------- !> @brief Calculate plastic velocity gradient and its tangent. !-------------------------------------------------------------------------------------------------- pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, & Mp,T,instance,of) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient real(pReal), dimension(3,3,3,3), intent(out) :: & dLp_dMp !< derivative of Lp with respect to the Mandel stress real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of integer :: & i,k,l,m,n real(pReal), dimension(param(instance)%sum_N_sl) :: & dot_gamma_pos,dot_gamma_neg, & ddot_gamma_dtau_pos,ddot_gamma_dtau_neg Lp = 0.0_pReal dLp_dMp = 0.0_pReal associate(prm => param(instance)) call kinetics(Mp,T,instance,of,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg) do i = 1, prm%sum_N_sl Lp = Lp + (dot_gamma_pos(i)+dot_gamma_neg(i))*prm%P_sl(1:3,1:3,i) forall (k=1:3,l=1:3,m=1:3,n=1:3) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & + ddot_gamma_dtau_pos(i) * prm%P_sl(k,l,i) * prm%nonSchmid_pos(m,n,i) & + ddot_gamma_dtau_neg(i) * prm%P_sl(k,l,i) * prm%nonSchmid_neg(m,n,i) enddo end associate end subroutine plastic_disloUCLA_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief Calculate the rate of change of microstructure. !-------------------------------------------------------------------------------------------------- module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of real(pReal) :: & VacancyDiffusion real(pReal), dimension(param(instance)%sum_N_sl) :: & gdot_pos, gdot_neg,& tau_pos,& tau_neg, & v_cl, & dot_rho_dip_formation, & dot_rho_dip_climb, & dip_distance associate(prm => param(instance), stt => state(instance),dot => dotState(instance), dst => dependentState(instance)) call kinetics(Mp,T,instance,of,& gdot_pos,gdot_neg, & tau_pos_out = tau_pos,tau_neg_out = tau_neg) dot%gamma_sl(:,of) = (gdot_pos+gdot_neg) ! ToDo: needs to be abs VacancyDiffusion = prm%D_0*exp(-prm%Q_cl/(kB*T)) where(dEq0(tau_pos)) ! ToDo: use avg of pos and neg dot_rho_dip_formation = 0.0_pReal dot_rho_dip_climb = 0.0_pReal else where dip_distance = math_clip(3.0_pReal*prm%mu*prm%b_sl/(16.0_pReal*PI*abs(tau_pos)), & prm%D_a, & ! lower limit dst%Lambda_sl(:,of)) ! upper limit dot_rho_dip_formation = merge(2.0_pReal*dip_distance* stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of))/prm%b_sl, & ! ToDo: ignore region of spontaneous annihilation 0.0_pReal, & prm%dipoleformation) v_cl = (3.0_pReal*prm%mu*VacancyDiffusion*prm%atomicVolume/(2.0_pReal*pi*kB*T)) & * (1.0_pReal/(dip_distance+prm%D_a)) dot_rho_dip_climb = (4.0_pReal*v_cl*stt%rho_dip(:,of))/(dip_distance-prm%D_a) ! ToDo: Discuss with Franz: Stress dependency? end where dot%rho_mob(:,of) = abs(dot%gamma_sl(:,of))/(prm%b_sl*dst%Lambda_sl(:,of)) & ! multiplication - dot_rho_dip_formation & - (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of)) ! Spontaneous annihilation of 2 single edge dislocations dot%rho_dip(:,of) = dot_rho_dip_formation & - (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_dip(:,of)*abs(dot%gamma_sl(:,of)) & ! Spontaneous annihilation of a single edge dislocation with a dipole constituent - dot_rho_dip_climb end associate end subroutine plastic_disloUCLA_dotState !-------------------------------------------------------------------------------------------------- !> @brief Calculate derived quantities from state. !-------------------------------------------------------------------------------------------------- module subroutine plastic_disloUCLA_dependentState(instance,of) integer, intent(in) :: & instance, & of real(pReal), dimension(param(instance)%sum_N_sl) :: & dislocationSpacing associate(prm => param(instance), stt => state(instance),dst => dependentState(instance)) dislocationSpacing = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,of)+stt%rho_dip(:,of))) dst%threshold_stress(:,of) = prm%mu*prm%b_sl & * sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of))) dst%Lambda_sl(:,of) = prm%D/(1.0_pReal+prm%D*dislocationSpacing/prm%i_sl) end associate end subroutine plastic_disloUCLA_dependentState !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- module subroutine plastic_disloUCLA_results(instance,group) integer, intent(in) :: instance character(len=*), intent(in) :: group integer :: o associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) case('edge_density') ! ToDo: should be rho_mob if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_mob,'rho_mob',& 'mobile dislocation density','1/m²') case('dipole_density') ! ToDo: should be rho_dip if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,'rho_dip',& 'dislocation dipole density''1/m²') case('shear_rate_slip') ! should be gamma if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,'dot_gamma_sl',& ! this is not dot!! 'plastic shear','1') case('mfp_slip') !ToDo: should be Lambda if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,'Lambda_sl',& 'mean free path for slip','m') case('threshold_stress_slip') !ToDo: should be tau_pass if(prm%sum_N_sl>0) call results_writeDataset(group,dst%threshold_stress,'tau_pass',& 'threshold stress for slip','Pa') end select enddo outputsLoop end associate end subroutine plastic_disloUCLA_results !-------------------------------------------------------------------------------------------------- !> @brief Calculate shear rates on slip systems, their derivatives with respect to resolved ! stress, and the resolved stress. !> @details Derivatives and resolved stress are calculated only optionally. ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end !-------------------------------------------------------------------------------------------------- pure subroutine kinetics(Mp,T,instance,of, & dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg,tau_pos_out,tau_neg_out) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of real(pReal), intent(out), dimension(param(instance)%sum_N_sl) :: & dot_gamma_pos, & dot_gamma_neg real(pReal), intent(out), optional, dimension(param(instance)%sum_N_sl) :: & ddot_gamma_dtau_pos, & ddot_gamma_dtau_neg, & tau_pos_out, & tau_neg_out real(pReal), dimension(param(instance)%sum_N_sl) :: & StressRatio, & StressRatio_p,StressRatio_pminus1, & dvel, vel, & tau_pos,tau_neg, & t_n, t_k, dtk,dtn, & needsGoodName ! ToDo: @Karo: any idea? integer :: j associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) do j = 1, prm%sum_N_sl tau_pos(j) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,j)) tau_neg(j) = math_tensordot(Mp,prm%nonSchmid_neg(1:3,1:3,j)) enddo if (present(tau_pos_out)) tau_pos_out = tau_pos if (present(tau_neg_out)) tau_neg_out = tau_neg associate(BoltzmannRatio => prm%delta_F/(kB*T), & dot_gamma_0 => stt%rho_mob(:,of)*prm%b_sl*prm%v0, & effectiveLength => dst%Lambda_sl(:,of) - prm%w) significantPositiveTau: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check) StressRatio = (abs(tau_pos)-dst%threshold_stress(:,of))/prm%tau_0 StressRatio_p = StressRatio** prm%p StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal) needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q) t_n = prm%b_sl/(needsGoodName*prm%omega*effectiveLength) t_k = effectiveLength * prm%B /(2.0_pReal*prm%b_sl*tau_pos) vel = prm%kink_height/(t_n + t_k) dot_gamma_pos = dot_gamma_0 * sign(vel,tau_pos) * 0.5_pReal else where significantPositiveTau dot_gamma_pos = 0.0_pReal end where significantPositiveTau if (present(ddot_gamma_dtau_pos)) then significantPositiveTau2: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check) dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) & * (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_0 dtk = -1.0_pReal * t_k / tau_pos dvel = -1.0_pReal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_pReal ddot_gamma_dtau_pos = dot_gamma_0 * dvel* 0.5_pReal else where significantPositiveTau2 ddot_gamma_dtau_pos = 0.0_pReal end where significantPositiveTau2 endif significantNegativeTau: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check) StressRatio = (abs(tau_neg)-dst%threshold_stress(:,of))/prm%tau_0 StressRatio_p = StressRatio** prm%p StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal) needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q) t_n = prm%b_sl/(needsGoodName*prm%omega*effectiveLength) t_k = effectiveLength * prm%B /(2.0_pReal*prm%b_sl*tau_pos) vel = prm%kink_height/(t_n + t_k) dot_gamma_neg = dot_gamma_0 * sign(vel,tau_neg) * 0.5_pReal else where significantNegativeTau dot_gamma_neg = 0.0_pReal end where significantNegativeTau if (present(ddot_gamma_dtau_neg)) then significantNegativeTau2: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check) dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) & * (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_0 dtk = -1.0_pReal * t_k / tau_neg dvel = -1.0_pReal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_pReal ddot_gamma_dtau_neg = dot_gamma_0 * dvel * 0.5_pReal else where significantNegativeTau2 ddot_gamma_dtau_neg = 0.0_pReal end where significantNegativeTau2 end if end associate end associate end subroutine kinetics end submodule plastic_disloUCLA # 43 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" 1 !-------------------------------------------------------------------------------------------------- !> @author Christoph Kords, Max-Planck-Institut für Eisenforschung GmbH !> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @brief material subroutine for plasticity including dislocation flux !-------------------------------------------------------------------------------------------------- submodule(constitutive) plastic_nonlocal use geometry_plastic_nonlocal, only: & nIPneighbors => geometry_plastic_nonlocal_nIPneighbors, & IPneighborhood => geometry_plastic_nonlocal_IPneighborhood, & IPvolume => geometry_plastic_nonlocal_IPvolume0, & IParea => geometry_plastic_nonlocal_IParea0, & IPareaNormal => geometry_plastic_nonlocal_IPareaNormal0 real(pReal), parameter :: & kB = 1.38e-23_pReal !< Boltzmann constant in J/Kelvin ! storage order of dislocation types integer, dimension(8), parameter :: & sgl = [1,2,3,4,5,6,7,8] !< signed (single) integer, dimension(5), parameter :: & edg = [1,2,5,6,9], & !< edge scr = [3,4,7,8,10] !< screw integer, dimension(4), parameter :: & mob = [1,2,3,4], & !< mobile imm = [5,6,7,8] !< immobile (blocked) integer, dimension(2), parameter :: & dip = [9,10], & !< dipole imm_edg = imm(1:2), & !< immobile edge imm_scr = imm(3:4) !< immobile screw integer, parameter :: & mob_edg_pos = 1, & !< mobile edge positive mob_edg_neg = 2, & !< mobile edge negative mob_scr_pos = 3, & !< mobile screw positive mob_scr_neg = 4 !< mobile screw positive ! BEGIN DEPRECATED integer, dimension(:,:,:), allocatable :: & iRhoU, & !< state indices for unblocked density iV, & !< state indices for dislcation velocities iD !< state indices for stable dipole height !END DEPRECATED real(pReal), dimension(:,:,:,:,:,:), allocatable :: & compatibility !< slip system compatibility between me and my neighbors type :: tInitialParameters !< container type for internal constitutive parameters real(pReal) :: & rhoSglScatter, & !< standard deviation of scatter in initial dislocation density rhoSglRandom, & rhoSglRandomBinning real(pReal), dimension(:), allocatable :: & rhoSglEdgePos0, & !< initial edge_pos dislocation density rhoSglEdgeNeg0, & !< initial edge_neg dislocation density rhoSglScrewPos0, & !< initial screw_pos dislocation density rhoSglScrewNeg0, & !< initial screw_neg dislocation density rhoDipEdge0, & !< initial edge dipole dislocation density rhoDipScrew0 !< initial screw dipole dislocation density integer, dimension(:) ,allocatable :: & N_sl end type tInitialParameters type :: tParameters !< container type for internal constitutive parameters real(pReal) :: & atomicVolume, & !< atomic volume Dsd0, & !< prefactor for self-diffusion coefficient selfDiffusionEnergy, & !< activation enthalpy for diffusion atol_rho, & !< absolute tolerance for dislocation density in state integration significantRho, & !< density considered significant significantN, & !< number of dislocations considered significant doublekinkwidth, & !< width of a doubkle kink in multiples of the burgers vector length b solidSolutionEnergy, & !< activation energy for solid solution in J solidSolutionSize, & !< solid solution obstacle size in multiples of the burgers vector length solidSolutionConcentration, & !< concentration of solid solution in atomic parts p, & !< parameter for kinetic law (Kocks,Argon,Ashby) q, & !< parameter for kinetic law (Kocks,Argon,Ashby) viscosity, & !< viscosity for dislocation glide in Pa s fattack, & !< attack frequency in Hz surfaceTransmissivity, & !< transmissivity at free surface grainboundaryTransmissivity, & !< transmissivity at grain boundary (identified by different texture) CFLfactor, & !< safety factor for CFL flux condition fEdgeMultiplication, & !< factor that determines how much edge dislocations contribute to multiplication (0...1) linetensionEffect, & edgeJogFactor, & mu, & nu real(pReal), dimension(:), allocatable :: & minDipoleHeight_edge, & !< minimum stable edge dipole height minDipoleHeight_screw, & !< minimum stable screw dipole height peierlsstress_edge, & peierlsstress_screw, & lambda0, & !< mean free path prefactor for each burgers !< absolute length of burgers vector [m] real(pReal), dimension(:,:), allocatable :: & slip_normal, & slip_direction, & slip_transverse, & minDipoleHeight, & ! edge and screw peierlsstress, & ! edge and screw interactionSlipSlip ,& !< coefficients for slip-slip interaction forestProjection_Edge, & !< matrix of forest projections of edge dislocations forestProjection_Screw !< matrix of forest projections of screw dislocations real(pReal), dimension(:,:,:), allocatable :: & Schmid, & !< Schmid contribution nonSchmid_pos, & nonSchmid_neg !< combined projection of Schmid and non-Schmid contributions to the resolved shear stress (only for screws) integer :: & sum_N_sl integer, dimension(:), allocatable :: & colinearSystem !< colinear system to the active slip system (only valid for fcc!) character(len=pStringLen), dimension(:), allocatable :: & output logical :: & shortRangeStressCorrection, & !< use of short range stress correction by excess density gradient term nonSchmidActive = .false. end type tParameters type :: tNonlocalMicrostructure real(pReal), allocatable, dimension(:,:) :: & tau_pass, & tau_Back end type tNonlocalMicrostructure type :: tNonlocalState real(pReal), pointer, dimension(:,:) :: & rho, & ! < all dislocations rhoSgl, & rhoSglMobile, & ! iRhoU rho_sgl_mob_edg_pos, & rho_sgl_mob_edg_neg, & rho_sgl_mob_scr_pos, & rho_sgl_mob_scr_neg, & rhoSglImmobile, & rho_sgl_imm_edg_pos, & rho_sgl_imm_edg_neg, & rho_sgl_imm_scr_pos, & rho_sgl_imm_scr_neg, & rhoDip, & rho_dip_edg, & rho_dip_scr, & rho_forest, & gamma, & v, & v_edg_pos, & v_edg_neg, & v_scr_pos, & v_scr_neg end type tNonlocalState type(tNonlocalState), allocatable, dimension(:) :: & deltaState, & dotState, & state, & state0 type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) type(tNonlocalMicrostructure), dimension(:), allocatable :: microstructure contains !-------------------------------------------------------------------------------------------------- !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_init integer :: & Ninstance, & p, & NipcMyPhase, & sizeState, sizeDotState, sizeDependentState, sizeDeltaState, & s1, s2, & s, t, l real(pReal), dimension(:), allocatable :: & a character(len=pStringLen) :: & extmsg = '' type(tInitialParameters) :: & ini write(6,'(/,a)') ' <<<+- constitutive_'//PLASTICITY_NONLOCAL_LABEL//' init -+>>>'; flush(6) write(6,'(/,a)') ' Reuber et al., Acta Materialia 71:333–348, 2014' write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2014.03.012' write(6,'(/,a)') ' Kords, Dissertation RWTH Aachen, 2014' write(6,'(a)') ' http://publications.rwth-aachen.de/record/229993' Ninstance = count(phase_plasticity == PLASTICITY_NONLOCAL_ID) if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & write(6,'(a16,1x,i5,/)') '# instances:',Ninstance allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(state0(Ninstance)) allocate(dotState(Ninstance)) allocate(deltaState(Ninstance)) allocate(microstructure(Ninstance)) do p=1, size(config_phase) if (phase_plasticity(p) /= PLASTICITY_NONLOCAL_ID) cycle associate(prm => param(phase_plasticityInstance(p)), & dot => dotState(phase_plasticityInstance(p)), & stt => state(phase_plasticityInstance(p)), & st0 => state0(phase_plasticityInstance(p)), & del => deltaState(phase_plasticityInstance(p)), & dst => microstructure(phase_plasticityInstance(p)), & config => config_phase(p)) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) prm%atol_rho = config%getFloat('atol_rho',defaultVal=1.0e4_pReal) ! This data is read in already in lattice prm%mu = lattice_mu(p) prm%nu = lattice_nu(p) ini%N_sl = config%getInts('nslip',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(ini%N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%Schmid = lattice_SchmidMatrix_slip(ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) if(trim(config%getString('lattice_structure')) == 'bcc') then a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray) if(size(a) > 0) prm%nonSchmidActive = .true. prm%nonSchmid_pos = lattice_nonSchmidMatrix(ini%N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(ini%N_sl,a,-1) else prm%nonSchmid_pos = prm%Schmid prm%nonSchmid_neg = prm%Schmid endif prm%interactionSlipSlip = lattice_interaction_SlipBySlip(ini%N_sl, & config%getFloats('interaction_slipslip'), & config%getString('lattice_structure')) prm%forestProjection_edge = lattice_forestProjection_edge (ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%forestProjection_screw = lattice_forestProjection_screw(ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%slip_direction = lattice_slip_direction (ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%slip_transverse = lattice_slip_transverse(ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%slip_normal = lattice_slip_normal (ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) ! collinear systems (only for octahedral slip systems in fcc) allocate(prm%colinearSystem(prm%sum_N_sl), source = -1) do s1 = 1, prm%sum_N_sl do s2 = 1, prm%sum_N_sl if (all(dEq0 (math_cross(prm%slip_direction(1:3,s1),prm%slip_direction(1:3,s2)))) .and. & any(dNeq0(math_cross(prm%slip_normal (1:3,s1),prm%slip_normal (1:3,s2))))) & prm%colinearSystem(s1) = s2 enddo enddo ini%rhoSglEdgePos0 = config%getFloats('rhosgledgepos0', requiredSize=size(ini%N_sl)) ini%rhoSglEdgeNeg0 = config%getFloats('rhosgledgeneg0', requiredSize=size(ini%N_sl)) ini%rhoSglScrewPos0 = config%getFloats('rhosglscrewpos0', requiredSize=size(ini%N_sl)) ini%rhoSglScrewNeg0 = config%getFloats('rhosglscrewneg0', requiredSize=size(ini%N_sl)) ini%rhoDipEdge0 = config%getFloats('rhodipedge0', requiredSize=size(ini%N_sl)) ini%rhoDipScrew0 = config%getFloats('rhodipscrew0', requiredSize=size(ini%N_sl)) prm%lambda0 = config%getFloats('lambda0', requiredSize=size(ini%N_sl)) prm%burgers = config%getFloats('burgers', requiredSize=size(ini%N_sl)) prm%lambda0 = math_expand(prm%lambda0,ini%N_sl) prm%burgers = math_expand(prm%burgers,ini%N_sl) prm%minDipoleHeight_edge = config%getFloats('minimumdipoleheightedge', requiredSize=size(ini%N_sl)) prm%minDipoleHeight_screw = config%getFloats('minimumdipoleheightscrew', requiredSize=size(ini%N_sl)) prm%minDipoleHeight_edge = math_expand(prm%minDipoleHeight_edge, ini%N_sl) prm%minDipoleHeight_screw = math_expand(prm%minDipoleHeight_screw,ini%N_sl) allocate(prm%minDipoleHeight(prm%sum_N_sl,2)) prm%minDipoleHeight(:,1) = prm%minDipoleHeight_edge prm%minDipoleHeight(:,2) = prm%minDipoleHeight_screw prm%peierlsstress_edge = config%getFloats('peierlsstressedge', requiredSize=size(ini%N_sl)) prm%peierlsstress_screw = config%getFloats('peierlsstressscrew', requiredSize=size(ini%N_sl)) prm%peierlsstress_edge = math_expand(prm%peierlsstress_edge, ini%N_sl) prm%peierlsstress_screw = math_expand(prm%peierlsstress_screw,ini%N_sl) allocate(prm%peierlsstress(prm%sum_N_sl,2)) prm%peierlsstress(:,1) = prm%peierlsstress_edge prm%peierlsstress(:,2) = prm%peierlsstress_screw prm%significantRho = config%getFloat('significantrho') prm%significantN = config%getFloat('significantn', 0.0_pReal) prm%CFLfactor = config%getFloat('cflfactor',defaultVal=2.0_pReal) prm%atomicVolume = config%getFloat('atomicvolume') prm%Dsd0 = config%getFloat('selfdiffusionprefactor') !,'dsd0' prm%selfDiffusionEnergy = config%getFloat('selfdiffusionenergy') !,'qsd' prm%linetensionEffect = config%getFloat('linetension') prm%edgeJogFactor = config%getFloat('edgejog')!,'edgejogs' prm%doublekinkwidth = config%getFloat('doublekinkwidth') prm%solidSolutionEnergy = config%getFloat('solidsolutionenergy') prm%solidSolutionSize = config%getFloat('solidsolutionsize') prm%solidSolutionConcentration = config%getFloat('solidsolutionconcentration') prm%p = config%getFloat('p') prm%q = config%getFloat('q') prm%viscosity = config%getFloat('viscosity') prm%fattack = config%getFloat('attackfrequency') ! ToDo: discuss logic ini%rhoSglScatter = config%getFloat('rhosglscatter') ini%rhoSglRandom = config%getFloat('rhosglrandom',0.0_pReal) if (config%keyExists('/rhosglrandom/')) & ini%rhoSglRandomBinning = config%getFloat('rhosglrandombinning',0.0_pReal) !ToDo: useful default? ! if (rhoSglRandom(instance) < 0.0_pReal) & ! if (rhoSglRandomBinning(instance) <= 0.0_pReal) & prm%surfaceTransmissivity = config%getFloat('surfacetransmissivity',defaultVal=1.0_pReal) prm%grainboundaryTransmissivity = config%getFloat('grainboundarytransmissivity',defaultVal=-1.0_pReal) prm%fEdgeMultiplication = config%getFloat('edgemultiplication') prm%shortRangeStressCorrection = config%keyExists('/shortrangestresscorrection/') !-------------------------------------------------------------------------------------------------- ! sanity checks if (any(prm%burgers < 0.0_pReal)) extmsg = trim(extmsg)//' burgers' if (any(prm%lambda0 <= 0.0_pReal)) extmsg = trim(extmsg)//' lambda0' if (any(ini%rhoSglEdgePos0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglEdgePos0' if (any(ini%rhoSglEdgeNeg0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglEdgeNeg0' if (any(ini%rhoSglScrewPos0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglScrewPos0' if (any(ini%rhoSglScrewNeg0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglScrewNeg0' if (any(ini%rhoDipEdge0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoDipEdge0' if (any(ini%rhoDipScrew0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoDipScrew0' if (any(prm%peierlsstress < 0.0_pReal)) extmsg = trim(extmsg)//' peierlsstress' if (any(prm%minDipoleHeight < 0.0_pReal)) extmsg = trim(extmsg)//' minDipoleHeight' if (prm%viscosity <= 0.0_pReal) extmsg = trim(extmsg)//' viscosity' if (prm%selfDiffusionEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' selfDiffusionEnergy' if (prm%fattack <= 0.0_pReal) extmsg = trim(extmsg)//' fattack' if (prm%doublekinkwidth <= 0.0_pReal) extmsg = trim(extmsg)//' doublekinkwidth' if (prm%Dsd0 < 0.0_pReal) extmsg = trim(extmsg)//' Dsd0' if (prm%atomicVolume <= 0.0_pReal) extmsg = trim(extmsg)//' atomicVolume' ! ToDo: in disloUCLA, the atomic volume is given as a factor if (prm%significantN < 0.0_pReal) extmsg = trim(extmsg)//' significantN' if (prm%significantrho < 0.0_pReal) extmsg = trim(extmsg)//' significantrho' if (prm%atol_rho < 0.0_pReal) extmsg = trim(extmsg)//' atol_rho' if (prm%CFLfactor < 0.0_pReal) extmsg = trim(extmsg)//' CFLfactor' if (prm%p <= 0.0_pReal .or. prm%p > 1.0_pReal) extmsg = trim(extmsg)//' p' if (prm%q < 1.0_pReal .or. prm%q > 2.0_pReal) extmsg = trim(extmsg)//' q' if (prm%linetensionEffect < 0.0_pReal .or. prm%linetensionEffect > 1.0_pReal) & extmsg = trim(extmsg)//' linetensionEffect' if (prm%edgeJogFactor < 0.0_pReal .or. prm%edgeJogFactor > 1.0_pReal) & extmsg = trim(extmsg)//' edgeJogFactor' if (prm%solidSolutionEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' solidSolutionEnergy' if (prm%solidSolutionSize <= 0.0_pReal) extmsg = trim(extmsg)//' solidSolutionSize' if (prm%solidSolutionConcentration <= 0.0_pReal) extmsg = trim(extmsg)//' solidSolutionConcentration' if (prm%grainboundaryTransmissivity > 1.0_pReal) extmsg = trim(extmsg)//' grainboundaryTransmissivity' if (prm%surfaceTransmissivity < 0.0_pReal .or. prm%surfaceTransmissivity > 1.0_pReal) & extmsg = trim(extmsg)//' surfaceTransmissivity' if (prm%fEdgeMultiplication < 0.0_pReal .or. prm%fEdgeMultiplication > 1.0_pReal) & extmsg = trim(extmsg)//' fEdgeMultiplication' endif slipActive !-------------------------------------------------------------------------------------------------- ! allocate state arrays NipcMyPhase = count(material_phaseAt==p) * discretization_nIP sizeDotState = size([ 'rhoSglEdgePosMobile ','rhoSglEdgeNegMobile ', & 'rhoSglScrewPosMobile ','rhoSglScrewNegMobile ', & 'rhoSglEdgePosImmobile ','rhoSglEdgeNegImmobile ', & 'rhoSglScrewPosImmobile','rhoSglScrewNegImmobile', & 'rhoDipEdge ','rhoDipScrew ', & 'gamma ' ]) * prm%sum_N_sl !< "basic" microstructural state variables that are independent from other state variables sizeDependentState = size([ 'rhoForest ']) * prm%sum_N_sl !< microstructural state variables that depend on other state variables sizeState = sizeDotState + sizeDependentState & + size([ 'velocityEdgePos ','velocityEdgeNeg ', & 'velocityScrewPos ','velocityScrewNeg ', & 'maxDipoleHeightEdge ','maxDipoleHeightScrew' ]) * prm%sum_N_sl !< other dependent state variables that are not updated by microstructure sizeDeltaState = sizeDotState call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,sizeDeltaState) plasticState(p)%nonlocal = .true. plasticState(p)%offsetDeltaState = 0 ! ToDo: state structure does not follow convention st0%rho => plasticState(p)%state0 (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) stt%rho => plasticState(p)%state (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) dot%rho => plasticState(p)%dotState (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) del%rho => plasticState(p)%deltaState (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) plasticState(p)%atol(1:10*prm%sum_N_sl) = prm%atol_rho stt%rhoSgl => plasticState(p)%state (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) dot%rhoSgl => plasticState(p)%dotState (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) del%rhoSgl => plasticState(p)%deltaState (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) stt%rhoSglMobile => plasticState(p)%state (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) dot%rhoSglMobile => plasticState(p)%dotState (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) del%rhoSglMobile => plasticState(p)%deltaState (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) stt%rho_sgl_mob_edg_pos => plasticState(p)%state (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:) dot%rho_sgl_mob_edg_pos => plasticState(p)%dotState (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:) del%rho_sgl_mob_edg_pos => plasticState(p)%deltaState (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:) stt%rho_sgl_mob_edg_neg => plasticState(p)%state (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:) dot%rho_sgl_mob_edg_neg => plasticState(p)%dotState (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:) del%rho_sgl_mob_edg_neg => plasticState(p)%deltaState (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:) stt%rho_sgl_mob_scr_pos => plasticState(p)%state (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:) dot%rho_sgl_mob_scr_pos => plasticState(p)%dotState (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:) del%rho_sgl_mob_scr_pos => plasticState(p)%deltaState (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:) stt%rho_sgl_mob_scr_neg => plasticState(p)%state (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) dot%rho_sgl_mob_scr_neg => plasticState(p)%dotState (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) del%rho_sgl_mob_scr_neg => plasticState(p)%deltaState (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) stt%rhoSglImmobile => plasticState(p)%state (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) dot%rhoSglImmobile => plasticState(p)%dotState (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) del%rhoSglImmobile => plasticState(p)%deltaState (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) stt%rho_sgl_imm_edg_pos => plasticState(p)%state (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:) dot%rho_sgl_imm_edg_pos => plasticState(p)%dotState (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:) del%rho_sgl_imm_edg_pos => plasticState(p)%deltaState (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:) stt%rho_sgl_imm_edg_neg => plasticState(p)%state (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:) dot%rho_sgl_imm_edg_neg => plasticState(p)%dotState (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:) del%rho_sgl_imm_edg_neg => plasticState(p)%deltaState (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:) stt%rho_sgl_imm_scr_pos => plasticState(p)%state (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:) dot%rho_sgl_imm_scr_pos => plasticState(p)%dotState (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:) del%rho_sgl_imm_scr_pos => plasticState(p)%deltaState (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:) stt%rho_sgl_imm_scr_neg => plasticState(p)%state (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) dot%rho_sgl_imm_scr_neg => plasticState(p)%dotState (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) del%rho_sgl_imm_scr_neg => plasticState(p)%deltaState (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) stt%rhoDip => plasticState(p)%state (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:) dot%rhoDip => plasticState(p)%dotState (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:) del%rhoDip => plasticState(p)%deltaState (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:) stt%rho_dip_edg => plasticState(p)%state (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:) dot%rho_dip_edg => plasticState(p)%dotState (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:) del%rho_dip_edg => plasticState(p)%deltaState (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:) stt%rho_dip_scr => plasticState(p)%state (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:) dot%rho_dip_scr => plasticState(p)%dotState (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:) del%rho_dip_scr => plasticState(p)%deltaState (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:) stt%gamma => plasticState(p)%state (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) dot%gamma => plasticState(p)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) del%gamma => plasticState(p)%deltaState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) plasticState(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl ) = config%getFloat('atol_gamma', defaultVal = 1.0e-2_pReal) if(any(plasticState(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl) < 0.0_pReal)) & extmsg = trim(extmsg)//' atol_gamma' plasticState(p)%slipRate => plasticState(p)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) stt%rho_forest => plasticState(p)%state (11*prm%sum_N_sl + 1:12*prm%sum_N_sl,1:NipcMyPhase) stt%v => plasticState(p)%state (12*prm%sum_N_sl + 1:16*prm%sum_N_sl,1:NipcMyPhase) stt%v_edg_pos => plasticState(p)%state (12*prm%sum_N_sl + 1:13*prm%sum_N_sl,1:NipcMyPhase) stt%v_edg_neg => plasticState(p)%state (13*prm%sum_N_sl + 1:14*prm%sum_N_sl,1:NipcMyPhase) stt%v_scr_pos => plasticState(p)%state (14*prm%sum_N_sl + 1:15*prm%sum_N_sl,1:NipcMyPhase) stt%v_scr_neg => plasticState(p)%state (15*prm%sum_N_sl + 1:16*prm%sum_N_sl,1:NipcMyPhase) allocate(dst%tau_pass(prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_back(prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) end associate if (NipcMyPhase > 0) call stateInit(ini,p,NipcMyPhase) plasticState(p)%state0 = plasticState(p)%state !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_NONLOCAL_LABEL//')') enddo allocate(compatibility(2,maxval(param%sum_N_sl),maxval(param%sum_N_sl),nIPneighbors,& discretization_nIP,discretization_nElem), source=0.0_pReal) ! BEGIN DEPRECATED---------------------------------------------------------------------------------- allocate(iRhoU(maxval(param%sum_N_sl),4,Ninstance), source=0) allocate(iV(maxval(param%sum_N_sl),4,Ninstance), source=0) allocate(iD(maxval(param%sum_N_sl),2,Ninstance), source=0) initializeInstances: do p = 1, size(phase_plasticity) NipcMyPhase = count(material_phaseAt==p) * discretization_nIP myPhase2: if (phase_plasticity(p) == PLASTICITY_NONLOCAL_ID) then l = 0 do t = 1,4 do s = 1,param(phase_plasticityInstance(p))%sum_N_sl l = l + 1 iRhoU(s,t,phase_plasticityInstance(p)) = l enddo enddo l = l + (4+2+1+1)*param(phase_plasticityInstance(p))%sum_N_sl ! immobile(4), dipole(2), shear, forest do t = 1,4 do s = 1,param(phase_plasticityInstance(p))%sum_N_sl l = l + 1 iV(s,t,phase_plasticityInstance(p)) = l enddo enddo do t = 1,2 do s = 1,param(phase_plasticityInstance(p))%sum_N_sl l = l + 1 iD(s,t,phase_plasticityInstance(p)) = l enddo enddo if (iD(param(phase_plasticityInstance(p))%sum_N_sl,2,phase_plasticityInstance(p)) /= plasticState(p)%sizeState) & call IO_error(0, ext_msg = 'state indices not properly set ('//PLASTICITY_NONLOCAL_LABEL//')') endif myPhase2 enddo initializeInstances end subroutine plastic_nonlocal_init !-------------------------------------------------------------------------------------------------- !> @brief calculates quantities characterizing the microstructure !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_dependentState(F, Fp, instance, of, ip, el) real(pReal), dimension(3,3), intent(in) :: & F, & Fp integer, intent(in) :: & instance, & of, & ip, & el integer :: & no, & !< neighbor offset neighbor_el, & ! element number of neighboring material point neighbor_ip, & ! integration point of neighboring material point neighbor_instance, & ! instance of this plasticity of neighboring material point c, & ! index of dilsocation character (edge, screw) s, & ! slip system index dir, & n real(pReal) :: & FVsize, & nRealNeighbors ! number of really existing neighbors integer, dimension(2) :: & neighbors real(pReal), dimension(2) :: & rhoExcessGradient, & rhoExcessGradient_over_rho, & rhoTotal real(pReal), dimension(3) :: & rhoExcessDifferences, & normal_latticeConf real(pReal), dimension(3,3) :: & invFe, & !< inverse of elastic deformation gradient invFp, & !< inverse of plastic deformation gradient connections, & invConnections real(pReal), dimension(3,nIPneighbors) :: & connection_latticeConf real(pReal), dimension(2,param(instance)%sum_N_sl) :: & rhoExcess real(pReal), dimension(param(instance)%sum_N_sl) :: & rho_edg_delta, & rho_scr_delta real(pReal), dimension(param(instance)%sum_N_sl,10) :: & rho, & rho0, & rho_neighbor0 real(pReal), dimension(param(instance)%sum_N_sl,param(instance)%sum_N_sl) :: & myInteractionMatrix ! corrected slip interaction matrix real(pReal), dimension(param(instance)%sum_N_sl,nIPneighbors) :: & rho_edg_delta_neighbor, & rho_scr_delta_neighbor real(pReal), dimension(2,maxval(param%sum_N_sl),nIPneighbors) :: & neighbor_rhoExcess, & ! excess density at neighboring material point neighbor_rhoTotal ! total density at neighboring material point real(pReal), dimension(3,param(instance)%sum_N_sl,2) :: & m ! direction of dislocation motion associate(prm => param(instance),dst => microstructure(instance), stt => state(instance)) rho = getRho(instance,of,ip,el) stt%rho_forest(:,of) = matmul(prm%forestProjection_Edge, sum(abs(rho(:,edg)),2)) & + matmul(prm%forestProjection_Screw,sum(abs(rho(:,scr)),2)) ! coefficients are corrected for the line tension effect ! (see Kubin,Devincre,Hoc; 2008; Modeling dislocation storage rates and mean free paths in face-centered cubic crystals) if (any(lattice_structure(material_phaseAt(1,el)) == [LATTICE_bcc_ID,LATTICE_fcc_ID])) then myInteractionMatrix = prm%interactionSlipSlip & * spread(( 1.0_pReal - prm%linetensionEffect & + prm%linetensionEffect & * log(0.35_pReal * prm%burgers * sqrt(max(stt%rho_forest(:,of),prm%significantRho))) & / log(0.35_pReal * prm%burgers * 1e6_pReal))** 2.0_pReal,2,prm%sum_N_sl) else myInteractionMatrix = prm%interactionSlipSlip endif dst%tau_pass(:,of) = prm%mu * prm%burgers & * sqrt(matmul(myInteractionMatrix,sum(abs(rho),2))) !*** calculate the dislocation stress of the neighboring excess dislocation densities !*** zero for material points of local plasticity !################################################################################################# ! ToDo: MD: this is most likely only correct for F_i = I !################################################################################################# rho0 = getRho0(instance,of,ip,el) if (.not. phase_localPlasticity(material_phaseAt(1,el)) .and. prm%shortRangeStressCorrection) then invFp = math_inv33(Fp) invFe = matmul(Fp,math_inv33(F)) rho_edg_delta = rho0(:,mob_edg_pos) - rho0(:,mob_edg_neg) rho_scr_delta = rho0(:,mob_scr_pos) - rho0(:,mob_scr_neg) rhoExcess(1,:) = rho_edg_delta rhoExcess(2,:) = rho_scr_delta FVsize = IPvolume(ip,el) ** (1.0_pReal/3.0_pReal) !* loop through my neighborhood and get the connection vectors (in lattice frame) and the excess densities nRealNeighbors = 0.0_pReal neighbor_rhoTotal = 0.0_pReal do n = 1,nIPneighbors neighbor_el = IPneighborhood(1,n,ip,el) neighbor_ip = IPneighborhood(2,n,ip,el) no = material_phasememberAt(1,neighbor_ip,neighbor_el) if (neighbor_el > 0 .and. neighbor_ip > 0) then neighbor_instance = phase_plasticityInstance(material_phaseAt(1,neighbor_el)) if (neighbor_instance == instance) then nRealNeighbors = nRealNeighbors + 1.0_pReal rho_neighbor0 = getRho0(instance,no,neighbor_ip,neighbor_el) rho_edg_delta_neighbor(:,n) = rho_neighbor0(:,mob_edg_pos) - rho_neighbor0(:,mob_edg_neg) rho_scr_delta_neighbor(:,n) = rho_neighbor0(:,mob_scr_pos) - rho_neighbor0(:,mob_scr_neg) neighbor_rhoTotal(1,:,n) = sum(abs(rho_neighbor0(:,edg)),2) neighbor_rhoTotal(2,:,n) = sum(abs(rho_neighbor0(:,scr)),2) connection_latticeConf(1:3,n) = matmul(invFe, discretization_IPcoords(1:3,neighbor_el+neighbor_ip-1) & - discretization_IPcoords(1:3,el+neighbor_ip-1)) normal_latticeConf = matmul(transpose(invFp), IPareaNormal(1:3,n,ip,el)) if (math_inner(normal_latticeConf,connection_latticeConf(1:3,n)) < 0.0_pReal) & ! neighboring connection points in opposite direction to face normal: must be periodic image connection_latticeConf(1:3,n) = normal_latticeConf * IPvolume(ip,el)/IParea(n,ip,el) ! instead take the surface normal scaled with the diameter of the cell else ! local neighbor or different lattice structure or different constitution instance -> use central values instead connection_latticeConf(1:3,n) = 0.0_pReal rho_edg_delta_neighbor(:,n) = rho_edg_delta rho_scr_delta_neighbor(:,n) = rho_scr_delta endif else ! free surface -> use central values instead connection_latticeConf(1:3,n) = 0.0_pReal rho_edg_delta_neighbor(:,n) = rho_edg_delta rho_scr_delta_neighbor(:,n) = rho_scr_delta endif enddo neighbor_rhoExcess(1,:,:) = rho_edg_delta_neighbor neighbor_rhoExcess(2,:,:) = rho_scr_delta_neighbor !* loop through the slip systems and calculate the dislocation gradient by !* 1. interpolation of the excess density in the neighorhood !* 2. interpolation of the dead dislocation density in the central volume m(1:3,:,1) = prm%slip_direction m(1:3,:,2) = -prm%slip_transverse do s = 1,prm%sum_N_sl ! gradient from interpolation of neighboring excess density ... do c = 1,2 do dir = 1,3 neighbors(1) = 2 * dir - 1 neighbors(2) = 2 * dir connections(dir,1:3) = connection_latticeConf(1:3,neighbors(1)) & - connection_latticeConf(1:3,neighbors(2)) rhoExcessDifferences(dir) = neighbor_rhoExcess(c,s,neighbors(1)) & - neighbor_rhoExcess(c,s,neighbors(2)) enddo invConnections = math_inv33(connections) if (all(dEq0(invConnections))) call IO_error(-1,ext_msg='back stress calculation: inversion error') rhoExcessGradient(c) = math_inner(m(1:3,s,c), matmul(invConnections,rhoExcessDifferences)) enddo ! ... plus gradient from deads ... rhoExcessGradient(1) = rhoExcessGradient(1) + sum(rho(s,imm_edg)) / FVsize rhoExcessGradient(2) = rhoExcessGradient(2) + sum(rho(s,imm_scr)) / FVsize ! ... normalized with the total density ... rhoTotal(1) = (sum(abs(rho(s,edg))) + sum(neighbor_rhoTotal(1,s,:))) / (1.0_pReal + nRealNeighbors) rhoTotal(2) = (sum(abs(rho(s,scr))) + sum(neighbor_rhoTotal(2,s,:))) / (1.0_pReal + nRealNeighbors) rhoExcessGradient_over_rho = 0.0_pReal where(rhoTotal > 0.0_pReal) rhoExcessGradient_over_rho = rhoExcessGradient / rhoTotal ! ... gives the local stress correction when multiplied with a factor dst%tau_back(s,of) = - prm%mu * prm%burgers(s) / (2.0_pReal * PI) & * ( rhoExcessGradient_over_rho(1) / (1.0_pReal - prm%nu) & + rhoExcessGradient_over_rho(2)) enddo endif # 721 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" end associate end subroutine plastic_nonlocal_dependentState !-------------------------------------------------------------------------------------------------- !> @brief calculates plastic velocity gradient and its tangent !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_LpAndItsTangent(Lp,dLp_dMp, & Mp,Temperature,instance,of,ip,el) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient real(pReal), dimension(3,3,3,3), intent(out) :: & dLp_dMp integer, intent(in) :: & instance, & of, & ip, & !< current integration point el !< current element number real(pReal), intent(in) :: & Temperature !< temperature real(pReal), dimension(3,3), intent(in) :: & Mp !< derivative of Lp with respect to Mp integer :: & ns, & !< short notation for the total number of active slip systems i, & j, & k, & l, & t, & !< dislocation type s !< index of my current slip system real(pReal), dimension(param(instance)%sum_N_sl,8) :: & rhoSgl !< single dislocation densities (including blocked) real(pReal), dimension(param(instance)%sum_N_sl,10) :: & rho real(pReal), dimension(param(instance)%sum_N_sl,4) :: & v, & !< velocity tauNS, & !< resolved shear stress including non Schmid and backstress terms dv_dtau, & !< velocity derivative with respect to the shear stress dv_dtauNS !< velocity derivative with respect to the shear stress real(pReal), dimension(param(instance)%sum_N_sl) :: & tau, & !< resolved shear stress including backstress terms gdotTotal !< shear rate associate(prm => param(instance),dst=>microstructure(instance),stt=>state(instance)) ns = prm%sum_N_sl !*** shortcut to state variables rho = getRho(instance,of,ip,el) rhoSgl = rho(:,sgl) do s = 1,ns tau(s) = math_tensordot(Mp, prm%Schmid(1:3,1:3,s)) tauNS(s,1) = tau(s) tauNS(s,2) = tau(s) if (tau(s) > 0.0_pReal) then tauNS(s,3) = math_tensordot(Mp, +prm%nonSchmid_pos(1:3,1:3,s)) tauNS(s,4) = math_tensordot(Mp, -prm%nonSchmid_neg(1:3,1:3,s)) else tauNS(s,3) = math_tensordot(Mp, +prm%nonSchmid_neg(1:3,1:3,s)) tauNS(s,4) = math_tensordot(Mp, -prm%nonSchmid_pos(1:3,1:3,s)) endif enddo tauNS = tauNS + spread(dst%tau_back(:,of),2,4) tau = tau + dst%tau_back(:,of) ! edges call kinetics(v(:,1), dv_dtau(:,1), dv_dtauNS(:,1), & tau, tauNS(:,1), dst%tau_pass(:,of),1,Temperature, instance) v(:,2) = v(:,1) dv_dtau(:,2) = dv_dtau(:,1) dv_dtauNS(:,2) = dv_dtauNS(:,1) !screws if (prm%nonSchmidActive) then v(:,3:4) = spread(v(:,1),2,2) dv_dtau(:,3:4) = spread(dv_dtau(:,1),2,2) dv_dtauNS(:,3:4) = spread(dv_dtauNS(:,1),2,2) else do t = 3,4 call kinetics(v(:,t), dv_dtau(:,t), dv_dtauNS(:,t), & tau, tauNS(:,t), dst%tau_pass(:,of),2,Temperature, instance) enddo endif stt%v(:,of) = pack(v,.true.) !*** Bauschinger effect forall (s = 1:ns, t = 5:8, rhoSgl(s,t) * v(s,t-4) < 0.0_pReal) & rhoSgl(s,t-4) = rhoSgl(s,t-4) + abs(rhoSgl(s,t)) gdotTotal = sum(rhoSgl(:,1:4) * v, 2) * prm%burgers Lp = 0.0_pReal dLp_dMp = 0.0_pReal do s = 1,ns Lp = Lp + gdotTotal(s) * prm%Schmid(1:3,1:3,s) forall (i=1:3,j=1:3,k=1:3,l=1:3) & dLp_dMp(i,j,k,l) = dLp_dMp(i,j,k,l) & + prm%Schmid(i,j,s) * prm%Schmid(k,l,s) & * sum(rhoSgl(s,1:4) * dv_dtau(s,1:4)) * prm%burgers(s) & + prm%Schmid(i,j,s) & * ( prm%nonSchmid_pos(k,l,s) * rhoSgl(s,3) * dv_dtauNS(s,3) & - prm%nonSchmid_neg(k,l,s) * rhoSgl(s,4) * dv_dtauNS(s,4)) * prm%burgers(s) enddo end associate end subroutine plastic_nonlocal_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief (instantaneous) incremental change of microstructure !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_deltaState(Mp,instance,of,ip,el) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress integer, intent(in) :: & instance, & ! current instance of this plasticity of, & !< offset ip, & el integer :: & ph, & !< phase ns, & ! short notation for the total number of active slip systems c, & ! character of dislocation t, & ! type of dislocation s ! index of my current slip system real(pReal), dimension(param(instance)%sum_N_sl,10) :: & deltaRhoRemobilization, & ! density increment by remobilization deltaRhoDipole2SingleStress ! density increment by dipole dissociation (by stress change) real(pReal), dimension(param(instance)%sum_N_sl,10) :: & rho ! current dislocation densities real(pReal), dimension(param(instance)%sum_N_sl,4) :: & v ! dislocation glide velocity real(pReal), dimension(param(instance)%sum_N_sl) :: & tau ! current resolved shear stress real(pReal), dimension(param(instance)%sum_N_sl,2) :: & rhoDip, & ! current dipole dislocation densities (screw and edge dipoles) dUpper, & ! current maximum stable dipole distance for edges and screws dUpperOld, & ! old maximum stable dipole distance for edges and screws deltaDUpper ! change in maximum stable dipole distance for edges and screws ph = material_phaseAt(1,el) associate(prm => param(instance),dst => microstructure(instance),del => deltaState(instance)) ns = prm%sum_N_sl !*** shortcut to state variables forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,instance),of) forall (s = 1:ns, c = 1:2) dUpperOld(s,c) = plasticState(ph)%state(iD(s,c,instance),of) rho = getRho(instance,of,ip,el) rhoDip = rho(:,dip) !**************************************************************************** !*** dislocation remobilization (bauschinger effect) where(rho(:,imm) * v < 0.0_pReal) deltaRhoRemobilization(:,mob) = abs(rho(:,imm)) deltaRhoRemobilization(:,imm) = - rho(:,imm) rho(:,mob) = rho(:,mob) + abs(rho(:,imm)) rho(:,imm) = 0.0_pReal elsewhere deltaRhoRemobilization(:,mob) = 0.0_pReal deltaRhoRemobilization(:,imm) = 0.0_pReal endwhere deltaRhoRemobilization(:,dip) = 0.0_pReal !**************************************************************************** !*** calculate dipole formation and dissociation by stress change !*** calculate limits for stable dipole height do s = 1,prm%sum_N_sl tau(s) = math_tensordot(Mp, prm%Schmid(1:3,1:3,s)) +dst%tau_back(s,of) if (abs(tau(s)) < 1.0e-15_pReal) tau(s) = 1.0e-15_pReal enddo dUpper(:,1) = prm%mu * prm%burgers/(8.0_pReal * PI * (1.0_pReal - prm%nu) * abs(tau)) dUpper(:,2) = prm%mu * prm%burgers/(4.0_pReal * PI * abs(tau)) where(dNeq0(sqrt(sum(abs(rho(:,edg)),2)))) & dUpper(:,1) = min(1.0_pReal/sqrt(sum(abs(rho(:,edg)),2)),dUpper(:,1)) where(dNeq0(sqrt(sum(abs(rho(:,scr)),2)))) & dUpper(:,2) = min(1.0_pReal/sqrt(sum(abs(rho(:,scr)),2)),dUpper(:,2)) dUpper = max(dUpper,prm%minDipoleHeight) deltaDUpper = dUpper - dUpperOld !*** dissociation by stress increase deltaRhoDipole2SingleStress = 0.0_pReal forall (c=1:2, s=1:ns, deltaDUpper(s,c) < 0.0_pReal .and. & dNeq0(dUpperOld(s,c) - prm%minDipoleHeight(s,c))) & deltaRhoDipole2SingleStress(s,8+c) = rhoDip(s,c) * deltaDUpper(s,c) & / (dUpperOld(s,c) - prm%minDipoleHeight(s,c)) forall (t=1:4) deltaRhoDipole2SingleStress(:,t) = -0.5_pReal * deltaRhoDipole2SingleStress(:,(t-1)/2+9) forall (s = 1:ns, c = 1:2) plasticState(ph)%state(iD(s,c,instance),of) = dUpper(s,c) plasticState(ph)%deltaState(:,of) = 0.0_pReal del%rho(:,of) = reshape(deltaRhoRemobilization + deltaRhoDipole2SingleStress, [10*ns]) # 936 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" end associate end subroutine plastic_nonlocal_deltaState !--------------------------------------------------------------------------------------------------- !> @brief calculates the rate of change of microstructure !--------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, & instance,of,ip,el) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress real(pReal), dimension(3,3,homogenization_maxNgrains,discretization_nIP,discretization_nElem), intent(in) :: & F, & !< elastic deformation gradient Fp !< plastic deformation gradient real(pReal), intent(in) :: & Temperature, & !< temperature timestep !< substepped crystallite time increment integer, intent(in) :: & instance, & of, & ip, & !< current integration point el !< current element number integer :: & ph, & neighbor_instance, & !< instance of my neighbor's plasticity ns, & !< short notation for the total number of active slip systems c, & !< character of dislocation n, & !< index of my current neighbor neighbor_el, & !< element number of my neighbor neighbor_ip, & !< integration point of my neighbor neighbor_n, & !< neighbor index pointing to me when looking from my neighbor opposite_neighbor, & !< index of my opposite neighbor opposite_ip, & !< ip of my opposite neighbor opposite_el, & !< element index of my opposite neighbor opposite_n, & !< neighbor index pointing to me when looking from my opposite neighbor t, & !< type of dislocation no,& !< neighbor offset shortcut np,& !< neighbor phase shortcut topp, & !< type of dislocation with opposite sign to t s !< index of my current slip system real(pReal), dimension(param(instance)%sum_N_sl,10) :: & rho, & rho0, & !< dislocation density at beginning of time step rhoDot, & !< density evolution rhoDotMultiplication, & !< density evolution by multiplication rhoDotFlux, & !< density evolution by flux rhoDotSingle2DipoleGlide, & !< density evolution by dipole formation (by glide) rhoDotAthermalAnnihilation, & !< density evolution by athermal annihilation rhoDotThermalAnnihilation !< density evolution by thermal annihilation real(pReal), dimension(param(instance)%sum_N_sl,8) :: & rhoSgl, & !< current single dislocation densities (positive/negative screw and edge without dipoles) neighbor_rhoSgl0, & !< current single dislocation densities of neighboring ip (positive/negative screw and edge without dipoles) my_rhoSgl0 !< single dislocation densities of central ip (positive/negative screw and edge without dipoles) real(pReal), dimension(param(instance)%sum_N_sl,4) :: & v, & !< current dislocation glide velocity v0, & neighbor_v0, & !< dislocation glide velocity of enighboring ip gdot !< shear rates real(pReal), dimension(param(instance)%sum_N_sl) :: & tau, & !< current resolved shear stress vClimb !< climb velocity of edge dipoles real(pReal), dimension(param(instance)%sum_N_sl,2) :: & rhoDip, & !< current dipole dislocation densities (screw and edge dipoles) dLower, & !< minimum stable dipole distance for edges and screws dUpper !< current maximum stable dipole distance for edges and screws real(pReal), dimension(3,param(instance)%sum_N_sl,4) :: & m !< direction of dislocation motion real(pReal), dimension(3,3) :: & my_F, & !< my total deformation gradient neighbor_F, & !< total deformation gradient of my neighbor my_Fe, & !< my elastic deformation gradient neighbor_Fe, & !< elastic deformation gradient of my neighbor Favg !< average total deformation gradient of me and my neighbor real(pReal), dimension(3) :: & normal_neighbor2me, & !< interface normal pointing from my neighbor to me in neighbor's lattice configuration normal_neighbor2me_defConf, & !< interface normal pointing from my neighbor to me in shared deformed configuration normal_me2neighbor, & !< interface normal pointing from me to my neighbor in my lattice configuration normal_me2neighbor_defConf !< interface normal pointing from me to my neighbor in shared deformed configuration real(pReal) :: & area, & !< area of the current interface transmissivity, & !< overall transmissivity of dislocation flux to neighboring material point lineLength, & !< dislocation line length leaving the current interface selfDiffusion !< self diffusion ph = material_phaseAt(1,el) if (timestep <= 0.0_pReal) then plasticState(ph)%dotState = 0.0_pReal return endif associate(prm => param(instance), & dst => microstructure(instance), & dot => dotState(instance), & stt => state(instance)) ns = prm%sum_N_sl tau = 0.0_pReal gdot = 0.0_pReal rho = getRho(instance,of,ip,el) rhoSgl = rho(:,sgl) rhoDip = rho(:,dip) rho0 = getRho0(instance,of,ip,el) my_rhoSgl0 = rho0(:,sgl) forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,instance),of) gdot = rhoSgl(:,1:4) * v * spread(prm%burgers,2,4) # 1056 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" !**************************************************************************** !*** limits for stable dipole height do s = 1,ns tau(s) = math_tensordot(Mp, prm%Schmid(1:3,1:3,s)) + dst%tau_back(s,of) if (abs(tau(s)) < 1.0e-15_pReal) tau(s) = 1.0e-15_pReal enddo dLower = prm%minDipoleHeight dUpper(:,1) = prm%mu * prm%burgers/(8.0_pReal * PI * (1.0_pReal - prm%nu) * abs(tau)) dUpper(:,2) = prm%mu * prm%burgers/(4.0_pReal * PI * abs(tau)) where(dNeq0(sqrt(sum(abs(rho(:,edg)),2)))) & dUpper(:,1) = min(1.0_pReal/sqrt(sum(abs(rho(:,edg)),2)),dUpper(:,1)) where(dNeq0(sqrt(sum(abs(rho(:,scr)),2)))) & dUpper(:,2) = min(1.0_pReal/sqrt(sum(abs(rho(:,scr)),2)),dUpper(:,2)) dUpper = max(dUpper,dLower) !**************************************************************************** !*** dislocation multiplication rhoDotMultiplication = 0.0_pReal isBCC: if (lattice_structure(ph) == LATTICE_bcc_ID) then forall (s = 1:ns, sum(abs(v(s,1:4))) > 0.0_pReal) rhoDotMultiplication(s,1:2) = sum(abs(gdot(s,3:4))) / prm%burgers(s) & ! assuming double-cross-slip of screws to be decisive for multiplication * sqrt(stt%rho_forest(s,of)) / prm%lambda0(s) ! & ! mean free path ! * 2.0_pReal * sum(abs(v(s,3:4))) / sum(abs(v(s,1:4))) ! ratio of screw to overall velocity determines edge generation rhoDotMultiplication(s,3:4) = sum(abs(gdot(s,3:4))) /prm%burgers(s) & ! assuming double-cross-slip of screws to be decisive for multiplication * sqrt(stt%rho_forest(s,of)) / prm%lambda0(s) ! & ! mean free path ! * 2.0_pReal * sum(abs(v(s,1:2))) / sum(abs(v(s,1:4))) ! ratio of edge to overall velocity determines screw generation endforall else isBCC rhoDotMultiplication(:,1:4) = spread( & (sum(abs(gdot(:,1:2)),2) * prm%fEdgeMultiplication + sum(abs(gdot(:,3:4)),2)) & * sqrt(stt%rho_forest(:,of)) / prm%lambda0 / prm%burgers, 2, 4) endif isBCC forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,instance),of) !**************************************************************************** !*** calculate dislocation fluxes (only for nonlocal plasticity) rhoDotFlux = 0.0_pReal if (.not. phase_localPlasticity(material_phaseAt(1,el))) then !*** check CFL (Courant-Friedrichs-Lewy) condition for flux if (any( abs(gdot) > 0.0_pReal & ! any active slip system ... .and. prm%CFLfactor * abs(v0) * timestep & > IPvolume(ip,el) / maxval(IParea(:,ip,el)))) then ! ...with velocity above critical value (we use the reference volume and area for simplicity here) # 1116 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" plasticState(ph)%dotState = IEEE_value(1.0_pReal,IEEE_quiet_NaN) ! -> return NaN and, hence, enforce cutback return endif !*** be aware of the definition of slip_transverse = slip_direction x slip_normal !!! !*** opposite sign to our t vector in the (s,t,n) triplet !!! m(1:3,:,1) = prm%slip_direction m(1:3,:,2) = -prm%slip_direction m(1:3,:,3) = -prm%slip_transverse m(1:3,:,4) = prm%slip_transverse my_F = F(1:3,1:3,1,ip,el) my_Fe = matmul(my_F, math_inv33(Fp(1:3,1:3,1,ip,el))) neighbors: do n = 1,nIPneighbors neighbor_el = IPneighborhood(1,n,ip,el) neighbor_ip = IPneighborhood(2,n,ip,el) neighbor_n = IPneighborhood(3,n,ip,el) np = material_phaseAt(1,neighbor_el) no = material_phasememberAt(1,neighbor_ip,neighbor_el) opposite_neighbor = n + mod(n,2) - mod(n+1,2) opposite_el = IPneighborhood(1,opposite_neighbor,ip,el) opposite_ip = IPneighborhood(2,opposite_neighbor,ip,el) opposite_n = IPneighborhood(3,opposite_neighbor,ip,el) if (neighbor_n > 0) then ! if neighbor exists, average deformation gradient neighbor_instance = phase_plasticityInstance(material_phaseAt(1,neighbor_el)) neighbor_F = F(1:3,1:3,1,neighbor_ip,neighbor_el) neighbor_Fe = matmul(neighbor_F, math_inv33(Fp(1:3,1:3,1,neighbor_ip,neighbor_el))) Favg = 0.5_pReal * (my_F + neighbor_F) else ! if no neighbor, take my value as average Favg = my_F endif neighbor_v0 = 0.0_pReal ! needed for check of sign change in flux density below !* FLUX FROM MY NEIGHBOR TO ME !* This is only considered, if I have a neighbor of nonlocal plasticity !* (also nonlocal constitutive law with local properties) that is at least a little bit !* compatible. !* If it's not at all compatible, no flux is arriving, because everything is dammed in front of !* my neighbor's interface. !* The entering flux from my neighbor will be distributed on my slip systems according to the !* compatibility if (neighbor_n > 0) then if (phase_plasticity(material_phaseAt(1,neighbor_el)) == PLASTICITY_NONLOCAL_ID .and. & any(compatibility(:,:,:,n,ip,el) > 0.0_pReal)) then forall (s = 1:ns, t = 1:4) neighbor_v0(s,t) = plasticState(np)%state0(iV (s,t,neighbor_instance),no) neighbor_rhoSgl0(s,t) = max(plasticState(np)%state0(iRhoU(s,t,neighbor_instance),no),0.0_pReal) endforall where (neighbor_rhoSgl0 * IPvolume(neighbor_ip,neighbor_el) ** 0.667_pReal < prm%significantN & .or. neighbor_rhoSgl0 < prm%significantRho) & neighbor_rhoSgl0 = 0.0_pReal normal_neighbor2me_defConf = math_det33(Favg) * matmul(math_inv33(transpose(Favg)), & IPareaNormal(1:3,neighbor_n,neighbor_ip,neighbor_el)) ! normal of the interface in (average) deformed configuration (pointing neighbor => me) normal_neighbor2me = matmul(transpose(neighbor_Fe), normal_neighbor2me_defConf) & / math_det33(neighbor_Fe) ! interface normal in the lattice configuration of my neighbor area = IParea(neighbor_n,neighbor_ip,neighbor_el) * norm2(normal_neighbor2me) normal_neighbor2me = normal_neighbor2me / norm2(normal_neighbor2me) ! normalize the surface normal to unit length do s = 1,ns do t = 1,4 c = (t + 1) / 2 topp = t + mod(t,2) - mod(t+1,2) if (neighbor_v0(s,t) * math_inner(m(1:3,s,t), normal_neighbor2me) > 0.0_pReal & ! flux from my neighbor to me == entering flux for me .and. v0(s,t) * neighbor_v0(s,t) >= 0.0_pReal ) then ! ... only if no sign change in flux density lineLength = neighbor_rhoSgl0(s,t) * neighbor_v0(s,t) & * math_inner(m(1:3,s,t), normal_neighbor2me) * area ! positive line length that wants to enter through this interface where (compatibility(c,:,s,n,ip,el) > 0.0_pReal) & rhoDotFlux(:,t) = rhoDotFlux(1:ns,t) & + lineLength/IPvolume(ip,el)*compatibility(c,:,s,n,ip,el)**2.0_pReal ! transferring to equally signed mobile dislocation type where (compatibility(c,:,s,n,ip,el) < 0.0_pReal) & rhoDotFlux(:,topp) = rhoDotFlux(:,topp) & + lineLength/IPvolume(ip,el)*compatibility(c,:,s,n,ip,el)**2.0_pReal ! transferring to opposite signed mobile dislocation type endif enddo enddo endif; endif !* FLUX FROM ME TO MY NEIGHBOR !* This is not considered, if my opposite neighbor has a different constitutive law than nonlocal (still considered for nonlocal law with local properties). !* Then, we assume, that the opposite(!) neighbor sends an equal amount of dislocations to me. !* So the net flux in the direction of my neighbor is equal to zero: !* leaving flux to neighbor == entering flux from opposite neighbor !* In case of reduced transmissivity, part of the leaving flux is stored as dead dislocation density. !* That means for an interface of zero transmissivity the leaving flux is fully converted to dead dislocations. if (opposite_n > 0) then if (phase_plasticity(material_phaseAt(1,opposite_el)) == PLASTICITY_NONLOCAL_ID) then normal_me2neighbor_defConf = math_det33(Favg) & * matmul(math_inv33(transpose(Favg)),IPareaNormal(1:3,n,ip,el)) ! normal of the interface in (average) deformed configuration (pointing me => neighbor) normal_me2neighbor = matmul(transpose(my_Fe), normal_me2neighbor_defConf) & / math_det33(my_Fe) ! interface normal in my lattice configuration area = IParea(n,ip,el) * norm2(normal_me2neighbor) normal_me2neighbor = normal_me2neighbor / norm2(normal_me2neighbor) ! normalize the surface normal to unit length do s = 1,ns do t = 1,4 c = (t + 1) / 2 if (v0(s,t) * math_inner(m(1:3,s,t), normal_me2neighbor) > 0.0_pReal ) then ! flux from me to my neighbor == leaving flux for me (might also be a pure flux from my mobile density to dead density if interface not at all transmissive) if (v0(s,t) * neighbor_v0(s,t) >= 0.0_pReal) then ! no sign change in flux density transmissivity = sum(compatibility(c,:,s,n,ip,el)**2.0_pReal) ! overall transmissivity from this slip system to my neighbor else ! sign change in flux density means sign change in stress which does not allow for dislocations to arive at the neighbor transmissivity = 0.0_pReal endif lineLength = my_rhoSgl0(s,t) * v0(s,t) & * math_inner(m(1:3,s,t), normal_me2neighbor) * area ! positive line length of mobiles that wants to leave through this interface rhoDotFlux(s,t) = rhoDotFlux(s,t) - lineLength / IPvolume(ip,el) ! subtract dislocation flux from current type rhoDotFlux(s,t+4) = rhoDotFlux(s,t+4) & + lineLength / IPvolume(ip,el) * (1.0_pReal - transmissivity) & * sign(1.0_pReal, v0(s,t)) ! dislocation flux that is not able to leave through interface (because of low transmissivity) will remain as immobile single density at the material point endif enddo enddo endif; endif enddo neighbors endif !**************************************************************************** !*** calculate dipole formation and annihilation !*** formation by glide do c = 1,2 rhoDotSingle2DipoleGlide(:,2*c-1) = -2.0_pReal * dUpper(:,c) / prm%burgers & * ( rhoSgl(:,2*c-1) * abs(gdot(:,2*c)) & ! negative mobile --> positive mobile + rhoSgl(:,2*c) * abs(gdot(:,2*c-1)) & ! positive mobile --> negative mobile + abs(rhoSgl(:,2*c+4)) * abs(gdot(:,2*c-1))) ! positive mobile --> negative immobile rhoDotSingle2DipoleGlide(:,2*c) = -2.0_pReal * dUpper(:,c) / prm%burgers & * ( rhoSgl(:,2*c-1) * abs(gdot(:,2*c)) & ! negative mobile --> positive mobile + rhoSgl(:,2*c) * abs(gdot(:,2*c-1)) & ! positive mobile --> negative mobile + abs(rhoSgl(:,2*c+3)) * abs(gdot(:,2*c))) ! negative mobile --> positive immobile rhoDotSingle2DipoleGlide(:,2*c+3) = -2.0_pReal * dUpper(:,c) / prm%burgers & * rhoSgl(:,2*c+3) * abs(gdot(:,2*c)) ! negative mobile --> positive immobile rhoDotSingle2DipoleGlide(:,2*c+4) = -2.0_pReal * dUpper(:,c) / prm%burgers & * rhoSgl(:,2*c+4) * abs(gdot(:,2*c-1)) ! positive mobile --> negative immobile rhoDotSingle2DipoleGlide(:,c+8) = abs(rhoDotSingle2DipoleGlide(:,2*c+3)) & + abs(rhoDotSingle2DipoleGlide(:,2*c+4)) & - rhoDotSingle2DipoleGlide(:,2*c-1) & - rhoDotSingle2DipoleGlide(:,2*c) enddo !*** athermal annihilation rhoDotAthermalAnnihilation = 0.0_pReal forall (c=1:2) & rhoDotAthermalAnnihilation(:,c+8) = -2.0_pReal * dLower(:,c) / prm%burgers & * ( 2.0_pReal * (rhoSgl(:,2*c-1) * abs(gdot(:,2*c)) + rhoSgl(:,2*c) * abs(gdot(:,2*c-1))) & ! was single hitting single + 2.0_pReal * (abs(rhoSgl(:,2*c+3)) * abs(gdot(:,2*c)) + abs(rhoSgl(:,2*c+4)) * abs(gdot(:,2*c-1))) & ! was single hitting immobile single or was immobile single hit by single + rhoDip(:,c) * (abs(gdot(:,2*c-1)) + abs(gdot(:,2*c)))) ! single knocks dipole constituent ! annihilated screw dipoles leave edge jogs behind on the colinear system if (lattice_structure(ph) == LATTICE_fcc_ID) & forall (s = 1:ns, prm%colinearSystem(s) > 0) & rhoDotAthermalAnnihilation(prm%colinearSystem(s),1:2) = - rhoDotAthermalAnnihilation(s,10) & * 0.25_pReal * sqrt(stt%rho_forest(s,of)) * (dUpper(s,2) + dLower(s,2)) * prm%edgeJogFactor !*** thermally activated annihilation of edge dipoles by climb rhoDotThermalAnnihilation = 0.0_pReal selfDiffusion = prm%Dsd0 * exp(-prm%selfDiffusionEnergy / (kB * Temperature)) vClimb = prm%atomicVolume * selfDiffusion * prm%mu & / ( kB * Temperature * PI * (1.0_pReal-prm%nu) * (dUpper(:,1) + dLower(:,1))) forall (s = 1:ns, dUpper(s,1) > dLower(s,1)) & rhoDotThermalAnnihilation(s,9) = max(- 4.0_pReal * rhoDip(s,1) * vClimb(s) / (dUpper(s,1) - dLower(s,1)), & - rhoDip(s,1) / timestep - rhoDotAthermalAnnihilation(s,9) & - rhoDotSingle2DipoleGlide(s,9)) ! make sure that we do not annihilate more dipoles than we have rhoDot = rhoDotFlux & + rhoDotMultiplication & + rhoDotSingle2DipoleGlide & + rhoDotAthermalAnnihilation & + rhoDotThermalAnnihilation # 1325 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" if ( any(rho(:,mob) + rhoDot(:,1:4) * timestep < -prm%atol_rho) & .or. any(rho(:,dip) + rhoDot(:,9:10) * timestep < -prm%atol_rho)) then plasticState(ph)%dotState = IEEE_value(1.0_pReal,IEEE_quiet_NaN) else dot%rho(:,of) = pack(rhoDot,.true.) dot%gamma(:,of) = sum(gdot,2) endif end associate end subroutine plastic_nonlocal_dotState !-------------------------------------------------------------------------------------------------- !> @brief Compatibility update !> @detail Compatibility is defined as normalized product of signed cosine of the angle between the slip ! plane normals and signed cosine of the angle between the slip directions. Only the largest values ! that sum up to a total of 1 are considered, all others are set to zero. !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e) type(rotation), dimension(1,discretization_nIP,discretization_nElem), intent(in) :: & orientation ! crystal orientation integer, intent(in) :: & instance, & i, & e integer :: & n, & ! neighbor index neighbor_e, & ! element index of my neighbor neighbor_i, & ! integration point index of my neighbor ph, & neighbor_phase, & ns, & ! number of active slip systems s1, & ! slip system index (me) s2 ! slip system index (my neighbor) real(pReal), dimension(2,param(instance)%sum_N_sl,param(instance)%sum_N_sl,nIPneighbors) :: & my_compatibility ! my_compatibility for current element and ip real(pReal) :: & my_compatibilitySum, & thresholdValue, & nThresholdValues logical, dimension(param(instance)%sum_N_sl) :: & belowThreshold type(rotation) :: mis ph = material_phaseAt(1,e) associate(prm => param(instance)) ns = prm%sum_N_sl !*** start out fully compatible my_compatibility = 0.0_pReal forall(s1 = 1:ns) my_compatibility(:,s1,s1,:) = 1.0_pReal neighbors: do n = 1,nIPneighbors neighbor_e = IPneighborhood(1,n,i,e) neighbor_i = IPneighborhood(2,n,i,e) neighbor_phase = material_phaseAt(1,neighbor_e) if (neighbor_e <= 0 .or. neighbor_i <= 0) then !* FREE SURFACE !* Set surface transmissivity to the value specified in the material.config forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%surfaceTransmissivity) elseif (neighbor_phase /= ph) then !* PHASE BOUNDARY !* If we encounter a different nonlocal phase at the neighbor, !* we consider this to be a real "physical" phase boundary, so completely incompatible. !* If one of the two phases has a local plasticity law, !* we do not consider this to be a phase boundary, so completely compatible. if (.not. phase_localPlasticity(neighbor_phase) .and. .not. phase_localPlasticity(ph)) & forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = 0.0_pReal elseif (prm%grainboundaryTransmissivity >= 0.0_pReal) then !* GRAIN BOUNDARY ! !* fixed transmissivity for adjacent ips with different texture (only if explicitly given in material.config) if (material_texture(1,i,e) /= material_texture(1,neighbor_i,neighbor_e) .and. & (.not. phase_localPlasticity(neighbor_phase))) & forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%grainboundaryTransmissivity) else !* GRAIN BOUNDARY ? !* Compatibility defined by relative orientation of slip systems: !* The my_compatibility value is defined as the product of the slip normal projection and the slip direction projection. !* Its sign is always positive for screws, for edges it has the same sign as the slip normal projection. !* Since the sum for each slip system can easily exceed one (which would result in a transmissivity larger than one), !* only values above or equal to a certain threshold value are considered. This threshold value is chosen, such that !* the number of compatible slip systems is minimized with the sum of the original compatibility values exceeding one. !* Finally the smallest compatibility value is decreased until the sum is exactly equal to one. !* All values below the threshold are set to zero. mis = orientation(1,i,e)%misorientation(orientation(1,neighbor_i,neighbor_e)) mySlipSystems: do s1 = 1,ns neighborSlipSystems: do s2 = 1,ns my_compatibility(1,s2,s1,n) = math_inner(prm%slip_normal(1:3,s1), & mis%rotate(prm%slip_normal(1:3,s2))) & * abs(math_inner(prm%slip_direction(1:3,s1), & mis%rotate(prm%slip_direction(1:3,s2)))) my_compatibility(2,s2,s1,n) = abs(math_inner(prm%slip_normal(1:3,s1), & mis%rotate(prm%slip_normal(1:3,s2)))) & * abs(math_inner(prm%slip_direction(1:3,s1), & mis%rotate(prm%slip_direction(1:3,s2)))) enddo neighborSlipSystems my_compatibilitySum = 0.0_pReal belowThreshold = .true. do while (my_compatibilitySum < 1.0_pReal .and. any(belowThreshold)) thresholdValue = maxval(my_compatibility(2,:,s1,n), belowThreshold) ! screws always positive nThresholdValues = real(count(my_compatibility(2,:,s1,n) >= thresholdValue),pReal) where (my_compatibility(2,:,s1,n) >= thresholdValue) belowThreshold = .false. if (my_compatibilitySum + thresholdValue * nThresholdValues > 1.0_pReal) & where (abs(my_compatibility(:,:,s1,n)) >= thresholdValue) & my_compatibility(:,:,s1,n) = sign((1.0_pReal - my_compatibilitySum)/nThresholdValues,& my_compatibility(:,:,s1,n)) my_compatibilitySum = my_compatibilitySum + nThresholdValues * thresholdValue enddo where(belowThreshold) my_compatibility(1,:,s1,n) = 0.0_pReal where(belowThreshold) my_compatibility(2,:,s1,n) = 0.0_pReal enddo mySlipSystems endif enddo neighbors compatibility(:,:,:,:,i,e) = my_compatibility end associate end subroutine plastic_nonlocal_updateCompatibility !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_results(instance,group) integer, intent(in) :: instance character(len=*),intent(in) :: group integer :: o associate(prm => param(instance),dst => microstructure(instance),stt=>state(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) case('rho_sgl_mob_edg_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_edg_pos, 'rho_sgl_mob_edg_pos', & 'positive mobile edge density','1/m²') case('rho_sgl_imm_edg_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_edg_pos, 'rho_sgl_imm_edg_pos',& 'positive immobile edge density','1/m²') case('rho_sgl_mob_edg_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_edg_neg, 'rho_sgl_mob_edg_neg',& 'negative mobile edge density','1/m²') case('rho_sgl_imm_edg_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_edg_neg, 'rho_sgl_imm_edg_neg',& 'negative immobile edge density','1/m²') case('rho_dip_edg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip_edg, 'rho_dip_edg',& 'edge dipole density','1/m²') case('rho_sgl_mob_scr_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_scr_pos, 'rho_sgl_mob_scr_pos',& 'positive mobile screw density','1/m²') case('rho_sgl_imm_scr_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_scr_pos, 'rho_sgl_imm_scr_pos',& 'positive immobile screw density','1/m²') case('rho_sgl_mob_scr_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_scr_neg, 'rho_sgl_mob_scr_neg',& 'negative mobile screw density','1/m²') case('rho_sgl_imm_scr_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_scr_neg, 'rho_sgl_imm_scr_neg',& 'negative immobile screw density','1/m²') case('rho_dip_scr') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip_scr, 'rho_dip_scr',& 'screw dipole density','1/m²') case('rho_forest') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_forest, 'rho_forest',& 'forest density','1/m²') case('v_edg_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_edg_pos, 'v_edg_pos',& 'positive edge velocity','m/s') case('v_edg_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_edg_neg, 'v_edg_neg',& 'negative edge velocity','m/s') case('v_scr_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_scr_pos, 'v_scr_pos',& 'positive srew velocity','m/s') case('v_scr_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_scr_neg, 'v_scr_neg',& 'negative screw velocity','m/s') case('gamma') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma,'gamma',& 'plastic shear','1') case('tau_pass') if(prm%sum_N_sl>0) call results_writeDataset(group,dst%tau_pass,'tau_pass',& 'passing stress for slip','Pa') end select enddo outputsLoop end associate end subroutine plastic_nonlocal_results !-------------------------------------------------------------------------------------------------- !> @brief populates the initial dislocation density !-------------------------------------------------------------------------------------------------- subroutine stateInit(ini,phase,NipcMyPhase) type(tInitialParameters) :: & ini integer,intent(in) :: & phase, & NipcMyPhase integer :: & e, & i, & f, & from, & upto, & s, & instance, & phasemember real(pReal), dimension(2) :: & noise, & rnd real(pReal) :: & meanDensity, & totalVolume, & densityBinning, & minimumIpVolume real(pReal), dimension(NipcMyPhase) :: & volume instance = phase_plasticityInstance(phase) associate(stt => state(instance)) if (ini%rhoSglRandom > 0.0_pReal) then ! randomly distribute dislocation segments on random slip system and of random type in the volume do e = 1,discretization_nElem do i = 1,discretization_nIP if (material_phaseAt(1,e) == phase) volume(material_phasememberAt(1,i,e)) = IPvolume(i,e) enddo enddo totalVolume = sum(volume) minimumIPVolume = minval(volume) densityBinning = ini%rhoSglRandomBinning / minimumIpVolume ** (2.0_pReal / 3.0_pReal) ! fill random material points with dislocation segments until the desired overall density is reached meanDensity = 0.0_pReal do while(meanDensity < ini%rhoSglRandom) call random_number(rnd) phasemember = nint(rnd(1)*real(NipcMyPhase,pReal) + 0.5_pReal) s = nint(rnd(2)*real(sum(ini%N_sl),pReal)*4.0_pReal + 0.5_pReal) meanDensity = meanDensity + densityBinning * volume(phasemember) / totalVolume stt%rhoSglMobile(s,phasemember) = densityBinning enddo else ! homogeneous distribution with noise do e = 1, NipcMyPhase do f = 1,size(ini%N_sl,1) from = 1 + sum(ini%N_sl(1:f-1)) upto = sum(ini%N_sl(1:f)) do s = from,upto noise = [math_sampleGaussVar(0.0_pReal, ini%rhoSglScatter), & math_sampleGaussVar(0.0_pReal, ini%rhoSglScatter)] stt%rho_sgl_mob_edg_pos(s,e) = ini%rhoSglEdgePos0(f) + noise(1) stt%rho_sgl_mob_edg_neg(s,e) = ini%rhoSglEdgeNeg0(f) + noise(1) stt%rho_sgl_mob_scr_pos(s,e) = ini%rhoSglScrewPos0(f) + noise(2) stt%rho_sgl_mob_scr_neg(s,e) = ini%rhoSglScrewNeg0(f) + noise(2) enddo stt%rho_dip_edg(from:upto,e) = ini%rhoDipEdge0(f) stt%rho_dip_scr(from:upto,e) = ini%rhoDipScrew0(f) enddo enddo endif end associate end subroutine stateInit !-------------------------------------------------------------------------------------------------- !> @brief calculates kinetics !-------------------------------------------------------------------------------------------------- subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Temperature, instance) integer, intent(in) :: & c, & !< dislocation character (1:edge, 2:screw) instance real(pReal), intent(in) :: & Temperature !< temperature real(pReal), dimension(param(instance)%sum_N_sl), intent(in) :: & tau, & !< resolved external shear stress (without non Schmid effects) tauNS, & !< resolved external shear stress (including non Schmid effects) tauThreshold !< threshold shear stress real(pReal), dimension(param(instance)%sum_N_sl), intent(out) :: & v, & !< velocity dv_dtau, & !< velocity derivative with respect to resolved shear stress (without non Schmid contributions) dv_dtauNS !< velocity derivative with respect to resolved shear stress (including non Schmid contributions) integer :: & ns, & !< short notation for the total number of active slip systems s !< index of my current slip system real(pReal) :: & tauRel_P, & tauRel_S, & tauEff, & !< effective shear stress tPeierls, & !< waiting time in front of a peierls barriers tSolidSolution, & !< waiting time in front of a solid solution obstacle vViscous, & !< viscous glide velocity dtPeierls_dtau, & !< derivative with respect to resolved shear stress dtSolidSolution_dtau, & !< derivative with respect to resolved shear stress meanfreepath_S, & !< mean free travel distance for dislocations between two solid solution obstacles meanfreepath_P, & !< mean free travel distance for dislocations between two Peierls barriers jumpWidth_P, & !< depth of activated area jumpWidth_S, & !< depth of activated area activationLength_P, & !< length of activated dislocation line activationLength_S, & !< length of activated dislocation line activationVolume_P, & !< volume that needs to be activated to overcome barrier activationVolume_S, & !< volume that needs to be activated to overcome barrier activationEnergy_P, & !< energy that is needed to overcome barrier activationEnergy_S, & !< energy that is needed to overcome barrier criticalStress_P, & !< maximum obstacle strength criticalStress_S, & !< maximum obstacle strength mobility !< dislocation mobility associate(prm => param(instance)) ns = prm%sum_N_sl v = 0.0_pReal dv_dtau = 0.0_pReal dv_dtauNS = 0.0_pReal do s = 1,ns if (abs(tau(s)) > tauThreshold(s)) then !* Peierls contribution !* Effective stress includes non Schmid constributions !* The derivative only gives absolute values; the correct sign is taken care of in the formula for the derivative of the velocity tauEff = max(0.0_pReal, abs(tauNS(s)) - tauThreshold(s)) ! ensure that the effective stress is positive meanfreepath_P = prm%burgers(s) jumpWidth_P = prm%burgers(s) activationLength_P = prm%doublekinkwidth *prm%burgers(s) activationVolume_P = activationLength_P * jumpWidth_P * prm%burgers(s) criticalStress_P = prm%peierlsStress(s,c) activationEnergy_P = criticalStress_P * activationVolume_P tauRel_P = min(1.0_pReal, tauEff / criticalStress_P) ! ensure that the activation probability cannot become greater than one tPeierls = 1.0_pReal / prm%fattack & * exp(activationEnergy_P / (kB * Temperature) & * (1.0_pReal - tauRel_P**prm%p)**prm%q) if (tauEff < criticalStress_P) then dtPeierls_dtau = tPeierls * prm%p * prm%q * activationVolume_P / (kB * Temperature) & * (1.0_pReal - tauRel_P**prm%p)**(prm%q-1.0_pReal) * tauRel_P**(prm%p-1.0_pReal) else dtPeierls_dtau = 0.0_pReal endif !* Contribution from solid solution strengthening !* The derivative only gives absolute values; the correct sign is taken care of in the formula for the derivative of the velocity tauEff = abs(tau(s)) - tauThreshold(s) meanfreepath_S = prm%burgers(s) / sqrt(prm%solidSolutionConcentration) jumpWidth_S = prm%solidSolutionSize * prm%burgers(s) activationLength_S = prm%burgers(s) / sqrt(prm%solidSolutionConcentration) activationVolume_S = activationLength_S * jumpWidth_S * prm%burgers(s) activationEnergy_S = prm%solidSolutionEnergy criticalStress_S = activationEnergy_S / activationVolume_S tauRel_S = min(1.0_pReal, tauEff / criticalStress_S) ! ensure that the activation probability cannot become greater than one tSolidSolution = 1.0_pReal / prm%fattack & * exp(activationEnergy_S / (kB * Temperature)* (1.0_pReal - tauRel_S**prm%p)**prm%q) if (tauEff < criticalStress_S) then dtSolidSolution_dtau = tSolidSolution * prm%p * prm%q * activationVolume_S / (kB * Temperature) & * (1.0_pReal - tauRel_S**prm%p)**(prm%q-1.0_pReal)* tauRel_S**(prm%p-1.0_pReal) else dtSolidSolution_dtau = 0.0_pReal endif !* viscous glide velocity tauEff = abs(tau(s)) - tauThreshold(s) mobility = prm%burgers(s) / prm%viscosity vViscous = mobility * tauEff !* Mean velocity results from waiting time at peierls barriers and solid solution obstacles with respective meanfreepath of !* free flight at glide velocity in between. !* adopt sign from resolved stress v(s) = sign(1.0_pReal,tau(s)) & / (tPeierls / meanfreepath_P + tSolidSolution / meanfreepath_S + 1.0_pReal / vViscous) dv_dtau(s) = v(s)**2.0_pReal * (dtSolidSolution_dtau / meanfreepath_S + mobility /vViscous**2.0_pReal) dv_dtauNS(s) = v(s)**2.0_pReal * dtPeierls_dtau / meanfreepath_P endif enddo end associate end subroutine kinetics !-------------------------------------------------------------------------------------------------- !> @brief returns copy of current dislocation densities from state !> @details raw values is rectified !-------------------------------------------------------------------------------------------------- function getRho(instance,of,ip,el) integer, intent(in) :: instance, of,ip,el real(pReal), dimension(param(instance)%sum_N_sl,10) :: getRho associate(prm => param(instance)) getRho = reshape(state(instance)%rho(:,of),[prm%sum_N_sl,10]) ! ensure positive densities (not for imm, they have a sign) getRho(:,mob) = max(getRho(:,mob),0.0_pReal) getRho(:,dip) = max(getRho(:,dip),0.0_pReal) where(abs(getRho) < max(prm%significantN/IPvolume(ip,el)**(2.0_pReal/3.0_pReal),prm%significantRho)) & getRho = 0.0_pReal end associate end function getRho !-------------------------------------------------------------------------------------------------- !> @brief returns copy of current dislocation densities from state !> @details raw values is rectified !-------------------------------------------------------------------------------------------------- function getRho0(instance,of,ip,el) integer, intent(in) :: instance, of,ip,el real(pReal), dimension(param(instance)%sum_N_sl,10) :: getRho0 associate(prm => param(instance)) getRho0 = reshape(state0(instance)%rho(:,of),[prm%sum_N_sl,10]) ! ensure positive densities (not for imm, they have a sign) getRho0(:,mob) = max(getRho0(:,mob),0.0_pReal) getRho0(:,dip) = max(getRho0(:,dip),0.0_pReal) where(abs(getRho0) < max(prm%significantN/IPvolume(ip,el)**(2.0_pReal/3.0_pReal),prm%significantRho)) & getRho0 = 0.0_pReal end associate end function getRho0 end submodule plastic_nonlocal # 44 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/crystallite.f90" 1 !-------------------------------------------------------------------------------------------------- !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH !> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH !> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @author Christoph Kords, Max-Planck-Institut für Eisenforschung GmbH !> @author Chen Zhang, Michigan State University !> @brief crystallite state integration functions and reporting of results !-------------------------------------------------------------------------------------------------- module crystallite use prec use IO use HDF5_utilities use DAMASK_interface use config use debug use numerics use rotations use math use FEsolving use material use constitutive use discretization use lattice use results implicit none private real(pReal), dimension(:,:,:), allocatable, public :: & crystallite_dt !< requested time increment of each grain real(pReal), dimension(:,:,:), allocatable :: & crystallite_subdt, & !< substepped time increment of each grain crystallite_subFrac, & !< already calculated fraction of increment crystallite_subStep !< size of next integration step type(rotation), dimension(:,:,:), allocatable :: & crystallite_orientation !< current orientation real(pReal), dimension(:,:,:,:,:), allocatable, public, protected :: & crystallite_Fe, & !< current "elastic" def grad (end of converged time step) crystallite_P, & !< 1st Piola-Kirchhoff stress per grain crystallite_S0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc crystallite_Fp0, & !< plastic def grad at start of FE inc crystallite_Fi0, & !< intermediate def grad at start of FE inc crystallite_F0, & !< def grad at start of FE inc crystallite_Lp0, & !< plastic velocitiy grad at start of FE inc crystallite_Li0 !< intermediate velocitiy grad at start of FE inc real(pReal), dimension(:,:,:,:,:), allocatable, public :: & crystallite_S, & !< current 2nd Piola-Kirchhoff stress vector (end of converged time step) crystallite_partionedS0, & !< 2nd Piola-Kirchhoff stress vector at start of homog inc crystallite_Fp, & !< current plastic def grad (end of converged time step) crystallite_partionedFp0,& !< plastic def grad at start of homog inc crystallite_Fi, & !< current intermediate def grad (end of converged time step) crystallite_partionedFi0,& !< intermediate def grad at start of homog inc crystallite_partionedF, & !< def grad to be reached at end of homog inc crystallite_partionedF0, & !< def grad at start of homog inc crystallite_Lp, & !< current plastic velocitiy grad (end of converged time step) crystallite_partionedLp0, & !< plastic velocity grad at start of homog inc crystallite_Li, & !< current intermediate velocitiy grad (end of converged time step) crystallite_partionedLi0 !< intermediate velocity grad at start of homog inc real(pReal), dimension(:,:,:,:,:), allocatable :: & crystallite_subFp0,& !< plastic def grad at start of crystallite inc crystallite_subFi0,& !< intermediate def grad at start of crystallite inc crystallite_subF, & !< def grad to be reached at end of crystallite inc crystallite_subF0, & !< def grad at start of crystallite inc crystallite_subLp0,& !< plastic velocity grad at start of crystallite inc crystallite_subLi0 !< intermediate velocity grad at start of crystallite inc real(pReal), dimension(:,:,:,:,:,:,:), allocatable, public, protected :: & crystallite_dPdF !< current individual dPdF per grain (end of converged time step) logical, dimension(:,:,:), allocatable, public :: & crystallite_requested !< used by upper level (homogenization) to request crystallite calculation logical, dimension(:,:,:), allocatable :: & crystallite_converged, & !< convergence flag crystallite_todo, & !< flag to indicate need for further computation crystallite_localPlasticity !< indicates this grain to have purely local constitutive law type :: tOutput !< new requested output (per phase) character(len=pStringLen), allocatable, dimension(:) :: & label end type tOutput type(tOutput), allocatable, dimension(:) :: output_constituent type :: tNumerics integer :: & iJacoLpresiduum, & !< frequency of Jacobian update of residuum in Lp nState, & !< state loop limit nStress !< stress loop limit real(pReal) :: & subStepMinCryst, & !< minimum (relative) size of sub-step allowed during cutback subStepSizeCryst, & !< size of first substep when cutback subStepSizeLp, & !< size of first substep when cutback in Lp calculation subStepSizeLi, & !< size of first substep when cutback in Li calculation stepIncreaseCryst, & !< increase of next substep size when previous substep converged rtol_crystalliteState, & !< relative tolerance in state loop rtol_crystalliteStress, & !< relative tolerance in stress loop atol_crystalliteStress !< absolute tolerance in stress loop end type tNumerics type(tNumerics) :: num ! numerics parameters. Better name? procedure(), pointer :: integrateState public :: & crystallite_init, & crystallite_stress, & crystallite_stressTangent, & crystallite_orientations, & crystallite_push33ToRef, & crystallite_results, & crystallite_restartWrite, & crystallite_restartRead, & crystallite_forward contains !-------------------------------------------------------------------------------------------------- !> @brief allocates and initialize per grain variables !-------------------------------------------------------------------------------------------------- subroutine crystallite_init logical, dimension(discretization_nIP,discretization_nElem) :: devNull integer :: & c, & !< counter in integration point component loop i, & !< counter in integration point loop e, & !< counter in element loop cMax, & !< maximum number of integration point components iMax, & !< maximum number of integration points eMax, & !< maximum number of elements myNcomponents !< number of components at current IP write(6,'(/,a)') ' <<<+- crystallite init -+>>>' cMax = homogenization_maxNgrains iMax = discretization_nIP eMax = discretization_nElem allocate(crystallite_partionedF(3,3,cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_S0, & crystallite_F0, crystallite_Fi0,crystallite_Fp0, & crystallite_Li0,crystallite_Lp0, & crystallite_partionedS0, & crystallite_partionedF0,crystallite_partionedFp0,crystallite_partionedFi0, & crystallite_partionedLp0,crystallite_partionedLi0, & crystallite_S,crystallite_P, & crystallite_Fe,crystallite_Fi,crystallite_Fp, & crystallite_Li,crystallite_Lp, & crystallite_subF,crystallite_subF0, & crystallite_subFp0,crystallite_subFi0, & crystallite_subLi0,crystallite_subLp0, & source = crystallite_partionedF) allocate(crystallite_dPdF(3,3,3,3,cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_dt(cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_subdt,crystallite_subFrac,crystallite_subStep, & source = crystallite_dt) allocate(crystallite_orientation(cMax,iMax,eMax)) allocate(crystallite_localPlasticity(cMax,iMax,eMax), source=.true.) allocate(crystallite_requested(cMax,iMax,eMax), source=.false.) allocate(crystallite_todo(cMax,iMax,eMax), source=.false.) allocate(crystallite_converged(cMax,iMax,eMax), source=.true.) num%subStepMinCryst = config_numerics%getFloat('substepmincryst', defaultVal=1.0e-3_pReal) num%subStepSizeCryst = config_numerics%getFloat('substepsizecryst', defaultVal=0.25_pReal) num%stepIncreaseCryst = config_numerics%getFloat('stepincreasecryst', defaultVal=1.5_pReal) num%subStepSizeLp = config_numerics%getFloat('substepsizelp', defaultVal=0.5_pReal) num%subStepSizeLi = config_numerics%getFloat('substepsizeli', defaultVal=0.5_pReal) num%rtol_crystalliteState = config_numerics%getFloat('rtol_crystallitestate', defaultVal=1.0e-6_pReal) num%rtol_crystalliteStress = config_numerics%getFloat('rtol_crystallitestress',defaultVal=1.0e-6_pReal) num%atol_crystalliteStress = config_numerics%getFloat('atol_crystallitestress',defaultVal=1.0e-8_pReal) num%iJacoLpresiduum = config_numerics%getInt ('ijacolpresiduum', defaultVal=1) num%nState = config_numerics%getInt ('nstate', defaultVal=20) num%nStress = config_numerics%getInt ('nstress', defaultVal=40) if(num%subStepMinCryst <= 0.0_pReal) call IO_error(301,ext_msg='subStepMinCryst') if(num%subStepSizeCryst <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeCryst') if(num%stepIncreaseCryst <= 0.0_pReal) call IO_error(301,ext_msg='stepIncreaseCryst') if(num%subStepSizeLp <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeLp') if(num%subStepSizeLi <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeLi') if(num%rtol_crystalliteState <= 0.0_pReal) call IO_error(301,ext_msg='rtol_crystalliteState') if(num%rtol_crystalliteStress <= 0.0_pReal) call IO_error(301,ext_msg='rtol_crystalliteStress') if(num%atol_crystalliteStress <= 0.0_pReal) call IO_error(301,ext_msg='atol_crystalliteStress') if(num%iJacoLpresiduum < 1) call IO_error(301,ext_msg='iJacoLpresiduum') if(num%nState < 1) call IO_error(301,ext_msg='nState') if(num%nStress< 1) call IO_error(301,ext_msg='nStress') select case(numerics_integrator) case(1) integrateState => integrateStateFPI case(2) integrateState => integrateStateEuler case(3) integrateState => integrateStateAdaptiveEuler case(4) integrateState => integrateStateRK4 case(5) integrateState => integrateStateRKCK45 end select allocate(output_constituent(size(config_phase))) do c = 1, size(config_phase) allocate(output_constituent(c)%label(1)) output_constituent(c)%label(1)= 'GfortranBug86277' output_constituent(c)%label = config_phase(c)%getStrings('(output)',defaultVal=output_constituent(c)%label ) if (output_constituent(c)%label (1) == 'GfortranBug86277') output_constituent(c)%label = [character(len=pStringLen)::] enddo call config_deallocate('material.config/phase') !-------------------------------------------------------------------------------------------------- ! initialize !$OMP PARALLEL DO PRIVATE(myNcomponents,i,c) do e = FEsolving_execElem(1),FEsolving_execElem(2) myNcomponents = homogenization_Ngrains(material_homogenizationAt(e)) do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, myNcomponents crystallite_Fp0(1:3,1:3,c,i,e) = material_orientation0(c,i,e)%asMatrix() ! plastic def gradient reflects init orientation crystallite_Fp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) & / math_det33(crystallite_Fp0(1:3,1:3,c,i,e))**(1.0_pReal/3.0_pReal) crystallite_Fi0(1:3,1:3,c,i,e) = constitutive_initialFi(c,i,e) crystallite_F0(1:3,1:3,c,i,e) = math_I3 crystallite_localPlasticity(c,i,e) = phase_localPlasticity(material_phaseAt(c,e)) crystallite_Fe(1:3,1:3,c,i,e) = math_inv33(matmul(crystallite_Fi0(1:3,1:3,c,i,e), & crystallite_Fp0(1:3,1:3,c,i,e))) ! assuming that euler angles are given in internal strain free configuration crystallite_Fp(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) crystallite_Fi(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e) crystallite_requested(c,i,e) = .true. enddo; enddo enddo !$OMP END PARALLEL DO if(any(.not. crystallite_localPlasticity) .and. .not. usePingPong) call IO_error(601) ! exit if nonlocal but no ping-pong ToDo: Why not check earlier? or in nonlocal? crystallite_partionedFp0 = crystallite_Fp0 crystallite_partionedFi0 = crystallite_Fi0 crystallite_partionedF0 = crystallite_F0 crystallite_partionedF = crystallite_F0 call crystallite_orientations() !$OMP PARALLEL DO do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Ngrains(material_homogenizationAt(e)) call constitutive_dependentState(crystallite_partionedF0(1:3,1:3,c,i,e), & crystallite_partionedFp0(1:3,1:3,c,i,e), & c,i,e) ! update dependent state variables to be consistent with basic states enddo enddo enddo !$OMP END PARALLEL DO devNull = crystallite_stress() call crystallite_stressTangent # 283 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/crystallite.f90" end subroutine crystallite_init !-------------------------------------------------------------------------------------------------- !> @brief calculate stress (P) !-------------------------------------------------------------------------------------------------- function crystallite_stress(dummyArgumentToPreventInternalCompilerErrorWithGCC) logical, dimension(discretization_nIP,discretization_nElem) :: crystallite_stress real(pReal), intent(in), optional :: & dummyArgumentToPreventInternalCompilerErrorWithGCC real(pReal) :: & formerSubStep integer :: & NiterationCrystallite, & ! number of iterations in crystallite loop c, & !< counter in integration point component loop i, & !< counter in integration point loop e, & !< counter in element loop startIP, endIP, & s # 325 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/crystallite.f90" !-------------------------------------------------------------------------------------------------- ! initialize to starting condition crystallite_subStep = 0.0_pReal !$OMP PARALLEL DO elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Ngrains(material_homogenizationAt(e)) homogenizationRequestsCalculation: if (crystallite_requested(c,i,e)) then plasticState (material_phaseAt(c,e))%subState0( :,material_phaseMemberAt(c,i,e)) = & plasticState (material_phaseAt(c,e))%partionedState0(:,material_phaseMemberAt(c,i,e)) do s = 1, phase_Nsources(material_phaseAt(c,e)) sourceState(material_phaseAt(c,e))%p(s)%subState0( :,material_phaseMemberAt(c,i,e)) = & sourceState(material_phaseAt(c,e))%p(s)%partionedState0(:,material_phaseMemberAt(c,i,e)) enddo crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_partionedFp0(1:3,1:3,c,i,e) crystallite_subLp0(1:3,1:3,c,i,e) = crystallite_partionedLp0(1:3,1:3,c,i,e) crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_partionedFi0(1:3,1:3,c,i,e) crystallite_subLi0(1:3,1:3,c,i,e) = crystallite_partionedLi0(1:3,1:3,c,i,e) crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partionedF0(1:3,1:3,c,i,e) crystallite_subFrac(c,i,e) = 0.0_pReal crystallite_subStep(c,i,e) = 1.0_pReal/num%subStepSizeCryst crystallite_todo(c,i,e) = .true. crystallite_converged(c,i,e) = .false. ! pretend failed step of 1/subStepSizeCryst endif homogenizationRequestsCalculation enddo; enddo enddo elementLooping1 !$OMP END PARALLEL DO singleRun: if (FEsolving_execELem(1) == FEsolving_execElem(2) .and. & FEsolving_execIP (1) == FEsolving_execIP (2)) then startIP = FEsolving_execIP(1) endIP = startIP else singleRun startIP = 1 endIP = discretization_nIP endif singleRun NiterationCrystallite = 0 cutbackLooping: do while (any(crystallite_todo(:,startIP:endIP,FEsolving_execELem(1):FEsolving_execElem(2)))) NiterationCrystallite = NiterationCrystallite + 1 !$OMP PARALLEL DO PRIVATE(formerSubStep) elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Ngrains(material_homogenizationAt(e)) !-------------------------------------------------------------------------------------------------- ! wind forward if (crystallite_converged(c,i,e)) then formerSubStep = crystallite_subStep(c,i,e) crystallite_subFrac(c,i,e) = crystallite_subFrac(c,i,e) + crystallite_subStep(c,i,e) crystallite_subStep(c,i,e) = min(1.0_pReal - crystallite_subFrac(c,i,e), & num%stepIncreaseCryst * crystallite_subStep(c,i,e)) crystallite_todo(c,i,e) = crystallite_subStep(c,i,e) > 0.0_pReal ! still time left to integrate on? if (crystallite_todo(c,i,e)) then crystallite_subF0 (1:3,1:3,c,i,e) = crystallite_subF(1:3,1:3,c,i,e) crystallite_subLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) crystallite_subLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e) crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e) !if abbrevation, make c and p private in omp plasticState( material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) & = plasticState(material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) do s = 1, phase_Nsources(material_phaseAt(c,e)) sourceState( material_phaseAt(c,e))%p(s)%subState0(:,material_phaseMemberAt(c,i,e)) & = sourceState(material_phaseAt(c,e))%p(s)%state( :,material_phaseMemberAt(c,i,e)) enddo endif !-------------------------------------------------------------------------------------------------- ! cut back (reduced time and restore) else crystallite_subStep(c,i,e) = num%subStepSizeCryst * crystallite_subStep(c,i,e) crystallite_Fp (1:3,1:3,c,i,e) = crystallite_subFp0(1:3,1:3,c,i,e) crystallite_Fi (1:3,1:3,c,i,e) = crystallite_subFi0(1:3,1:3,c,i,e) crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e) if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback crystallite_Lp (1:3,1:3,c,i,e) = crystallite_subLp0(1:3,1:3,c,i,e) crystallite_Li (1:3,1:3,c,i,e) = crystallite_subLi0(1:3,1:3,c,i,e) endif plasticState (material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) & = plasticState(material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) do s = 1, phase_Nsources(material_phaseAt(c,e)) sourceState( material_phaseAt(c,e))%p(s)%state( :,material_phaseMemberAt(c,i,e)) & = sourceState(material_phaseAt(c,e))%p(s)%subState0(:,material_phaseMemberAt(c,i,e)) enddo ! cant restore dotState here, since not yet calculated in first cutback after initialization crystallite_todo(c,i,e) = crystallite_subStep(c,i,e) > num%subStepMinCryst ! still on track or already done (beyond repair) endif !-------------------------------------------------------------------------------------------------- ! prepare for integration if (crystallite_todo(c,i,e)) then crystallite_subF(1:3,1:3,c,i,e) = crystallite_subF0(1:3,1:3,c,i,e) & + crystallite_subStep(c,i,e) *( crystallite_partionedF (1:3,1:3,c,i,e) & -crystallite_partionedF0(1:3,1:3,c,i,e)) crystallite_Fe(1:3,1:3,c,i,e) = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), & math_inv33(crystallite_Fp(1:3,1:3,c,i,e))), & math_inv33(crystallite_Fi(1:3,1:3,c,i,e))) crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e) crystallite_converged(c,i,e) = .false. endif enddo enddo enddo elementLooping3 !$OMP END PARALLEL DO !-------------------------------------------------------------------------------------------------- ! integrate --- requires fully defined state array (basic + dependent state) if (any(crystallite_todo)) call integrateState ! TODO: unroll into proper elementloop to avoid N^2 for single point evaluation where(.not. crystallite_converged .and. crystallite_subStep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further crystallite_todo = .true. ! TODO: again unroll this into proper elementloop to avoid N^2 for single point evaluation enddo cutbackLooping ! return whether converged or not crystallite_stress = .false. elementLooping5: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) crystallite_stress(i,e) = all(crystallite_converged(:,i,e)) enddo enddo elementLooping5 end function crystallite_stress !-------------------------------------------------------------------------------------------------- !> @brief calculate tangent (dPdF) !-------------------------------------------------------------------------------------------------- subroutine crystallite_stressTangent integer :: & c, & !< counter in integration point component loop i, & !< counter in integration point loop e, & !< counter in element loop o, & p real(pReal), dimension(3,3) :: devNull, & invSubFp0,invSubFi0,invFp,invFi, & temp_33_1, temp_33_2, temp_33_3, temp_33_4 real(pReal), dimension(3,3,3,3) :: dSdFe, & dSdF, & dSdFi, & dLidS, & ! tangent in lattice configuration dLidFi, & dLpdS, & dLpdFi, & dFidS, & dFpinvdF, & rhs_3333, & lhs_3333, & temp_3333 real(pReal), dimension(9,9):: temp_99 logical :: error !$OMP PARALLEL DO PRIVATE(dSdF,dSdFe,dSdFi,dLpdS,dLpdFi,dFpinvdF,dLidS,dLidFi,dFidS,o,p, & !$OMP invSubFp0,invSubFi0,invFp,invFi, & !$OMP rhs_3333,lhs_3333,temp_99,temp_33_1,temp_33_2,temp_33_3,temp_33_4,temp_3333,error) elementLooping: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Ngrains(material_homogenizationAt(e)) call constitutive_SandItsTangents(devNull,dSdFe,dSdFi, & crystallite_Fe(1:3,1:3,c,i,e), & crystallite_Fi(1:3,1:3,c,i,e),c,i,e) call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & crystallite_S (1:3,1:3,c,i,e), & crystallite_Fi(1:3,1:3,c,i,e), & c,i,e) invFp = math_inv33(crystallite_Fp(1:3,1:3,c,i,e)) invFi = math_inv33(crystallite_Fi(1:3,1:3,c,i,e)) invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,c,i,e)) invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,c,i,e)) if (sum(abs(dLidS)) < tol_math_check) then dFidS = 0.0_pReal else lhs_3333 = 0.0_pReal; rhs_3333 = 0.0_pReal do o=1,3; do p=1,3 lhs_3333(1:3,1:3,o,p) = lhs_3333(1:3,1:3,o,p) & + crystallite_subdt(c,i,e)*matmul(invSubFi0,dLidFi(1:3,1:3,o,p)) lhs_3333(1:3,o,1:3,p) = lhs_3333(1:3,o,1:3,p) & + invFi*invFi(p,o) rhs_3333(1:3,1:3,o,p) = rhs_3333(1:3,1:3,o,p) & - crystallite_subdt(c,i,e)*matmul(invSubFi0,dLidS(1:3,1:3,o,p)) enddo; enddo call math_invert(temp_99,error,math_3333to99(lhs_3333)) if (error) then call IO_warning(warning_ID=600,el=e,ip=i,g=c, & ext_msg='inversion error in analytic tangent calculation') dFidS = 0.0_pReal else dFidS = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) endif dLidS = math_mul3333xx3333(dLidFi,dFidS) + dLidS endif call constitutive_LpAndItsTangents(devNull,dLpdS,dLpdFi, & crystallite_S (1:3,1:3,c,i,e), & crystallite_Fi(1:3,1:3,c,i,e),c,i,e) ! call constitutive law to calculate Lp tangent in lattice configuration dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS !-------------------------------------------------------------------------------------------------- ! calculate dSdF temp_33_1 = transpose(matmul(invFp,invFi)) temp_33_2 = matmul(crystallite_subF(1:3,1:3,c,i,e),invSubFp0) temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e),invFp), invSubFi0) do o=1,3; do p=1,3 rhs_3333(p,o,1:3,1:3) = matmul(dSdFe(p,o,1:3,1:3),temp_33_1) temp_3333(1:3,1:3,p,o) = matmul(matmul(temp_33_2,dLpdS(1:3,1:3,p,o)), invFi) & + matmul(temp_33_3,dLidS(1:3,1:3,p,o)) enddo; enddo lhs_3333 = crystallite_subdt(c,i,e)*math_mul3333xx3333(dSdFe,temp_3333) & + math_mul3333xx3333(dSdFi,dFidS) call math_invert(temp_99,error,math_identity2nd(9)+math_3333to99(lhs_3333)) if (error) then call IO_warning(warning_ID=600,el=e,ip=i,g=c, & ext_msg='inversion error in analytic tangent calculation') dSdF = rhs_3333 else dSdF = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) endif !-------------------------------------------------------------------------------------------------- ! calculate dFpinvdF temp_3333 = math_mul3333xx3333(dLpdS,dSdF) do o=1,3; do p=1,3 dFpinvdF(1:3,1:3,p,o) = -crystallite_subdt(c,i,e) & * matmul(invSubFp0, matmul(temp_3333(1:3,1:3,p,o),invFi)) enddo; enddo !-------------------------------------------------------------------------------------------------- ! assemble dPdF temp_33_1 = matmul(crystallite_S(1:3,1:3,c,i,e),transpose(invFp)) temp_33_2 = matmul(invFp,temp_33_1) temp_33_3 = matmul(crystallite_subF(1:3,1:3,c,i,e),invFp) temp_33_4 = matmul(temp_33_3,crystallite_S(1:3,1:3,c,i,e)) crystallite_dPdF(1:3,1:3,1:3,1:3,c,i,e) = 0.0_pReal do p=1,3 crystallite_dPdF(p,1:3,p,1:3,c,i,e) = transpose(temp_33_2) enddo do o=1,3; do p=1,3 crystallite_dPdF(1:3,1:3,p,o,c,i,e) = crystallite_dPdF(1:3,1:3,p,o,c,i,e) & + matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), & dFpinvdF(1:3,1:3,p,o)),temp_33_1) & + matmul(matmul(temp_33_3,dSdF(1:3,1:3,p,o)), & transpose(invFp)) & + matmul(temp_33_4,transpose(dFpinvdF(1:3,1:3,p,o))) enddo; enddo enddo; enddo enddo elementLooping !$OMP END PARALLEL DO end subroutine crystallite_stressTangent !-------------------------------------------------------------------------------------------------- !> @brief calculates orientations !-------------------------------------------------------------------------------------------------- subroutine crystallite_orientations integer & c, & !< counter in integration point component loop i, & !< counter in integration point loop e !< counter in element loop !$OMP PARALLEL DO do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Ngrains(material_homogenizationAt(e)) call crystallite_orientation(c,i,e)%fromMatrix(transpose(math_rotationalPart(crystallite_Fe(1:3,1:3,c,i,e)))) enddo; enddo; enddo !$OMP END PARALLEL DO nonlocalPresent: if (any(plasticState%nonLocal)) then !$OMP PARALLEL DO do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) if (plasticState(material_phaseAt(1,e))%nonLocal) & call plastic_nonlocal_updateCompatibility(crystallite_orientation, & phase_plasticityInstance(material_phaseAt(i,e)),i,e) enddo; enddo !$OMP END PARALLEL DO endif nonlocalPresent end subroutine crystallite_orientations !-------------------------------------------------------------------------------------------------- !> @brief Map 2nd order tensor to reference config !-------------------------------------------------------------------------------------------------- function crystallite_push33ToRef(ipc,ip,el, tensor33) real(pReal), dimension(3,3) :: crystallite_push33ToRef real(pReal), dimension(3,3), intent(in) :: tensor33 real(pReal), dimension(3,3) :: T integer, intent(in):: & el, & ip, & ipc T = matmul(material_orientation0(ipc,ip,el)%asMatrix(), & ! ToDo: initial orientation correct? transpose(math_inv33(crystallite_subF(1:3,1:3,ipc,ip,el)))) crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) end function crystallite_push33ToRef !-------------------------------------------------------------------------------------------------- !> @brief writes crystallite results to HDF5 output file !-------------------------------------------------------------------------------------------------- subroutine crystallite_results integer :: p,o real(pReal), allocatable, dimension(:,:,:) :: selected_tensors type(rotation), allocatable, dimension(:) :: selected_rotations character(len=pStringLen) :: group,structureLabel do p=1,size(config_name_phase) group = trim('current/constituent')//'/'//trim(config_name_phase(p))//'/generic' call results_closeGroup(results_addGroup(group)) do o = 1, size(output_constituent(p)%label) select case (output_constituent(p)%label(o)) case('f') selected_tensors = select_tensors(crystallite_partionedF,p) call results_writeDataset(group,selected_tensors,'F',& 'deformation gradient','1') case('fe') selected_tensors = select_tensors(crystallite_Fe,p) call results_writeDataset(group,selected_tensors,'Fe',& 'elastic deformation gradient','1') case('fp') selected_tensors = select_tensors(crystallite_Fp,p) call results_writeDataset(group,selected_tensors,'Fp',& 'plastic deformation gradient','1') case('fi') selected_tensors = select_tensors(crystallite_Fi,p) call results_writeDataset(group,selected_tensors,'Fi',& 'inelastic deformation gradient','1') case('lp') selected_tensors = select_tensors(crystallite_Lp,p) call results_writeDataset(group,selected_tensors,'Lp',& 'plastic velocity gradient','1/s') case('li') selected_tensors = select_tensors(crystallite_Li,p) call results_writeDataset(group,selected_tensors,'Li',& 'inelastic velocity gradient','1/s') case('p') selected_tensors = select_tensors(crystallite_P,p) call results_writeDataset(group,selected_tensors,'P',& 'First Piola-Kirchoff stress','Pa') case('s') selected_tensors = select_tensors(crystallite_S,p) call results_writeDataset(group,selected_tensors,'S',& 'Second Piola-Kirchoff stress','Pa') case('orientation') select case(lattice_structure(p)) case(lattice_ISO_ID) structureLabel = 'iso' case(lattice_FCC_ID) structureLabel = 'fcc' case(lattice_BCC_ID) structureLabel = 'bcc' case(lattice_BCT_ID) structureLabel = 'bct' case(lattice_HEX_ID) structureLabel = 'hex' case(lattice_ORT_ID) structureLabel = 'ort' end select selected_rotations = select_rotations(crystallite_orientation,p) call results_writeDataset(group,selected_rotations,'orientation',& 'crystal orientation as quaternion',structureLabel) end select enddo enddo contains !------------------------------------------------------------------------------------------------ !> @brief select tensors for output !------------------------------------------------------------------------------------------------ function select_tensors(dataset,instance) integer, intent(in) :: instance real(pReal), dimension(:,:,:,:,:), intent(in) :: dataset real(pReal), allocatable, dimension(:,:,:) :: select_tensors integer :: e,i,c,j allocate(select_tensors(3,3,count(material_phaseAt==instance)*discretization_nIP)) j=0 do e = 1, size(material_phaseAt,2) do i = 1, discretization_nIP do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains if (material_phaseAt(c,e) == instance) then j = j + 1 select_tensors(1:3,1:3,j) = dataset(1:3,1:3,c,i,e) endif enddo enddo enddo end function select_tensors !-------------------------------------------------------------------------------------------------- !> @brief select rotations for output !-------------------------------------------------------------------------------------------------- function select_rotations(dataset,instance) integer, intent(in) :: instance type(rotation), dimension(:,:,:), intent(in) :: dataset type(rotation), allocatable, dimension(:) :: select_rotations integer :: e,i,c,j allocate(select_rotations(count(material_phaseAt==instance)*homogenization_maxNgrains*discretization_nIP)) j=0 do e = 1, size(material_phaseAt,2) do i = 1, discretization_nIP do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains if (material_phaseAt(c,e) == instance) then j = j + 1 select_rotations(j) = dataset(c,i,e) endif enddo enddo enddo end function select_rotations end subroutine crystallite_results !-------------------------------------------------------------------------------------------------- !> @brief calculation of stress (P) with time integration based on a residuum in Lp and !> intermediate acceleration of the Newton-Raphson correction !-------------------------------------------------------------------------------------------------- logical function integrateStress(ipc,ip,el,timeFraction) integer, intent(in):: el, & ! element index ip, & ! integration point index ipc ! grain index real(pReal), optional, intent(in) :: timeFraction ! fraction of timestep real(pReal), dimension(3,3):: F, & ! deformation gradient at end of timestep Fp_new, & ! plastic deformation gradient at end of timestep invFp_new, & ! inverse of Fp_new invFp_current, & ! inverse of Fp_current Lpguess, & ! current guess for plastic velocity gradient Lpguess_old, & ! known last good guess for plastic velocity gradient Lp_constitutive, & ! plastic velocity gradient resulting from constitutive law residuumLp, & ! current residuum of plastic velocity gradient residuumLp_old, & ! last residuum of plastic velocity gradient deltaLp, & ! direction of next guess Fi_new, & ! gradient of intermediate deformation stages invFi_new, & invFi_current, & ! inverse of Fi_current Liguess, & ! current guess for intermediate velocity gradient Liguess_old, & ! known last good guess for intermediate velocity gradient Li_constitutive, & ! intermediate velocity gradient resulting from constitutive law residuumLi, & ! current residuum of intermediate velocity gradient residuumLi_old, & ! last residuum of intermediate velocity gradient deltaLi, & ! direction of next guess Fe, & ! elastic deformation gradient Fe_new, & S, & ! 2nd Piola-Kirchhoff Stress in plastic (lattice) configuration A, & B, & temp_33 real(pReal), dimension(9) :: temp_9 ! needed for matrix inversion by LAPACK integer, dimension(9) :: devNull_9 ! needed for matrix inversion by LAPACK real(pReal), dimension(9,9) :: dRLp_dLp, & ! partial derivative of residuum (Jacobian for Newton-Raphson scheme) dRLi_dLi ! partial derivative of residuumI (Jacobian for Newton-Raphson scheme) real(pReal), dimension(3,3,3,3):: dS_dFe, & ! partial derivative of 2nd Piola-Kirchhoff stress dS_dFi, & dFe_dLp, & ! partial derivative of elastic deformation gradient dFe_dLi, & dFi_dLi, & dLp_dFi, & dLi_dFi, & dLp_dS, & dLi_dS real(pReal) steplengthLp, & steplengthLi, & dt, & ! time increment atol_Lp, & atol_Li, & devNull integer NiterationStressLp, & ! number of stress integrations NiterationStressLi, & ! number of inner stress integrations ierr, & ! error indicator for LAPACK o, & p, & jacoCounterLp, & jacoCounterLi ! counters to check for Jacobian update logical :: error external :: & dgesv integrateStress = .false. if (present(timeFraction)) then dt = crystallite_subdt(ipc,ip,el) * timeFraction F = crystallite_subF0(1:3,1:3,ipc,ip,el) & + (crystallite_subF(1:3,1:3,ipc,ip,el) - crystallite_subF0(1:3,1:3,ipc,ip,el)) * timeFraction else dt = crystallite_subdt(ipc,ip,el) F = crystallite_subF(1:3,1:3,ipc,ip,el) endif Lpguess = crystallite_Lp(1:3,1:3,ipc,ip,el) ! take as first guess Liguess = crystallite_Li(1:3,1:3,ipc,ip,el) ! take as first guess call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,ipc,ip,el)) if (error) return ! error call math_invert33(invFi_current,devNull,error,crystallite_subFi0(1:3,1:3,ipc,ip,el)) if (error) return ! error A = matmul(F,invFp_current) ! intermediate tensor needed later to calculate dFe_dLp jacoCounterLi = 0 steplengthLi = 1.0_pReal residuumLi_old = 0.0_pReal Liguess_old = Liguess NiterationStressLi = 0 LiLoop: do NiterationStressLi = NiterationStressLi + 1 if (NiterationStressLi>num%nStress) return ! error invFi_new = matmul(invFi_current,math_I3 - dt*Liguess) Fi_new = math_inv33(invFi_new) jacoCounterLp = 0 steplengthLp = 1.0_pReal residuumLp_old = 0.0_pReal Lpguess_old = Lpguess NiterationStressLp = 0 LpLoop: do NiterationStressLp = NiterationStressLp + 1 if (NiterationStressLp>num%nStress) return ! error B = math_I3 - dt*Lpguess Fe = matmul(matmul(A,B), invFi_new) call constitutive_SandItsTangents(S, dS_dFe, dS_dFi, & Fe, Fi_new, ipc, ip, el) call constitutive_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & S, Fi_new, ipc, ip, el) !* update current residuum and check for convergence of loop atol_Lp = max(num%rtol_crystalliteStress * max(norm2(Lpguess),norm2(Lp_constitutive)), & ! absolute tolerance from largest acceptable relative error num%atol_crystalliteStress) ! minimum lower cutoff residuumLp = Lpguess - Lp_constitutive if (any(IEEE_is_NaN(residuumLp))) then return ! error elseif (norm2(residuumLp) < atol_Lp) then ! converged if below absolute tolerance exit LpLoop elseif (NiterationStressLp == 1 .or. norm2(residuumLp) < norm2(residuumLp_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... residuumLp_old = residuumLp ! ...remember old values and... Lpguess_old = Lpguess steplengthLp = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) else ! not converged and residuum not improved... steplengthLp = num%subStepSizeLp * steplengthLp ! ...try with smaller step length in same direction Lpguess = Lpguess_old & + deltaLp * stepLengthLp cycle LpLoop endif !* calculate Jacobian for correction term if (mod(jacoCounterLp, num%iJacoLpresiduum) == 0) then jacoCounterLp = jacoCounterLp + 1 do o=1,3; do p=1,3 dFe_dLp(o,1:3,p,1:3) = A(o,p)*transpose(invFi_new) ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) enddo; enddo dFe_dLp = - dt * dFe_dLp dRLp_dLp = math_identity2nd(9) & - math_3333to99(math_mul3333xx3333(math_mul3333xx3333(dLp_dS,dS_dFe),dFe_dLp)) temp_9 = math_33to9(residuumLp) call dgesv(9,1,dRLp_dLp,9,devNull_9,temp_9,9,ierr) ! solve dRLp/dLp * delta Lp = -res for delta Lp if (ierr /= 0) return ! error deltaLp = - math_9to33(temp_9) endif Lpguess = Lpguess & + deltaLp * steplengthLp enddo LpLoop call constitutive_LiAndItsTangents(Li_constitutive, dLi_dS, dLi_dFi, & S, Fi_new, ipc, ip, el) !* update current residuum and check for convergence of loop atol_Li = max(num%rtol_crystalliteStress * max(norm2(Liguess),norm2(Li_constitutive)), & ! absolute tolerance from largest acceptable relative error num%atol_crystalliteStress) ! minimum lower cutoff residuumLi = Liguess - Li_constitutive if (any(IEEE_is_NaN(residuumLi))) then return ! error elseif (norm2(residuumLi) < atol_Li) then ! converged if below absolute tolerance exit LiLoop elseif (NiterationStressLi == 1 .or. norm2(residuumLi) < norm2(residuumLi_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... residuumLi_old = residuumLi ! ...remember old values and... Liguess_old = Liguess steplengthLi = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) else ! not converged and residuum not improved... steplengthLi = num%subStepSizeLi �s] for each twin system
18109  dot_n_0_tr, & !< trans nucleation rate [1/m�s] for each trans system t_tw, & !< twin thickness [m] for each twin system CLambdaSlip, & !< Adj. parameter for distance between 2 forest dislocations for each slip system t_tr, & !< martensite lamellar thickness [m] for each trans system and instance p, & !< p-exponent in glide velocity q, & !< q-exponent in glide velocity r, & !< r-exponent in twin nucleation rate s, & !< s-exponent in trans nucleation rate gamma_char, & !< characteristic shear for twins B !< drag coefficient real(pReal), allocatable, dimension(:,:) :: & h_sl_sl, & !< h_sl_tw, & !< h_tw_tw, & !< h_sl_tr, & !< h_tr_tr, & !< n0_sl, & !< slip system normal forestProjection, & C66 real(pReal), allocatable, dimension(:,:,:) :: & P_sl, & P_tw, & P_tr, & C66_tw, & C66_tr integer :: & sum_N_sl, & !< total number of active slip system sum_N_tw, & !< total number of active twin system sum_N_tr !< total number of active transformation system integer, allocatable, dimension(:,:) :: & fcc_twinNucleationSlipPair ! ToDo: Better name? Is also use for trans character(len=pStringLen), allocatable, dimension(:) :: & output logical :: & ExtendedDislocations, & !< consider split into partials for climb calculation fccTwinTransNucleation, & !< twinning and transformation models are for fcc dipoleFormation !< flag indicating consideration of dipole formation end type !< container type for internal constitutive parameters type :: tDislotwinState real(pReal), dimension(:,:), pointer :: & rho_mob, & rho_dip, & gamma_sl, & f_tw, & f_tr end type tDislotwinState type :: tDislotwinMicrostructure real(pReal), dimension(:,:), allocatable :: & Lambda_sl, & !< mean free path between 2 obstacles seen by a moving dislocation Lambda_tw, & !< mean free path between 2 obstacles seen by a growing twin Lambda_tr, & !< mean free path between 2 obstacles seen by a growing martensite tau_pass, & tau_hat_tw, & tau_hat_tr, & V_tw, & !< volume of a new twin V_tr, & !< volume of a new martensite disc tau_r_tw, & !< stress to bring partials close together (twin) tau_r_tr !< stress to bring partials close together (trans) end type tDislotwinMicrostructure !-------------------------------------------------------------------------------------------------- ! containers for parameters and state type(tParameters), allocatable, dimension(:) :: param type(tDislotwinState), allocatable, dimension(:) :: & dotState, & state type(tDislotwinMicrostructure), allocatable, dimension(:) :: dependentState contains !-------------------------------------------------------------------------------------------------- !> @brief Perform module initialization. !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- module subroutine plastic_dislotwin_init integer :: & Ninstance, & p, i, & NipcMyPhase, & sizeState, sizeDotState, & startIndex, endIndex integer, dimension(:), allocatable :: & N_sl, N_tw, N_tr real(pReal), allocatable, dimension(:) :: & rho_mob_0, & !< initial unipolar dislocation density per slip system rho_dip_0 !< initial dipole dislocation density per slip system character(len=pStringLen) :: & extmsg = '' write(6,'(/,a)') ' <<<+- constitutive_'//PLASTICITY_DISLOTWIN_LABEL//' init -+>>>'; flush(6) write(6,'(/,a)') ' Ma and Roters, Acta Materialia 52(12):3603–3612, 2004' write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2004.04.012' write(6,'(/,a)') ' Roters et al., Computational Materials Science 39:91–95, 2007' write(6,'(a)') ' https://doi.org/10.1016/j.commatsci.2006.04.014' write(6,'(/,a)') ' Wong et al., Acta Materialia 118:140–151, 2016' write(6,'(a,/)') ' https://doi.org/10.1016/j.actamat.2016.07.032' Ninstance = count(phase_plasticity == PLASTICITY_DISLOTWIN_ID) if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & write(6,'(a16,1x,i5,/)') '# instances:',Ninstance allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(dotState(Ninstance)) allocate(dependentState(Ninstance)) do p = 1, size(phase_plasticity) if (phase_plasticity(p) /= PLASTICITY_DISLOTWIN_ID) cycle associate(prm => param(phase_plasticityInstance(p)), & dot => dotState(phase_plasticityInstance(p)), & stt => state(phase_plasticityInstance(p)), & dst => dependentState(phase_plasticityInstance(p)), & config => config_phase(p)) prm%output = config%getStrings('(output)', defaultVal=emptyStringArray) ! This data is read in already in lattice prm%mu = lattice_mu(p) prm%nu = lattice_nu(p) prm%C66 = lattice_C66(1:6,1:6,p) !-------------------------------------------------------------------------------------------------- ! slip related parameters N_sl = config%getInts('nslip',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%P_sl = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,config%getFloats('interaction_slipslip'), & config%getString('lattice_structure')) prm%forestProjection = lattice_forestProjection_edge(N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%forestProjection = transpose(prm%forestProjection) prm%n0_sl = lattice_slip_normal(N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%fccTwinTransNucleation = merge(.true., .false., lattice_structure(p) == lattice_FCC_ID) & .and. (N_sl(1) == 12) if(prm%fccTwinTransNucleation) prm%fcc_twinNucleationSlipPair = lattice_FCC_TWINNUCLEATIONSLIPPAIR rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(N_sl)) rho_dip_0 = config%getFloats('rhoedgedip0',requiredSize=size(N_sl)) prm%v0 = config%getFloats('v0', requiredSize=size(N_sl)) prm%b_sl = config%getFloats('slipburgers',requiredSize=size(N_sl)) prm%Delta_F = config%getFloats('qedge', requiredSize=size(N_sl)) prm%CLambdaSlip = config%getFloats('clambdaslip',requiredSize=size(N_sl)) prm%p = config%getFloats('p_slip', requiredSize=size(N_sl)) prm%q = config%getFloats('q_slip', requiredSize=size(N_sl)) prm%B = config%getFloats('b', requiredSize=size(N_sl), & defaultVal=[(0.0_pReal, i=1,size(N_sl))]) prm%tau_0 = config%getFloat('solidsolutionstrength') prm%CEdgeDipMinDistance = config%getFloat('cedgedipmindistance') prm%D0 = config%getFloat('d0') prm%Qsd = config%getFloat('qsd') prm%ExtendedDislocations = config%keyExists('/extend_dislocations/') if (prm%ExtendedDislocations) then prm%SFE_0K = config%getFloat('sfe_0k') prm%dSFE_dT = config%getFloat('dsfe_dt') endif prm%dipoleformation = .not. config%keyExists('/nodipoleformation/') ! multiplication factor according to crystal structure (nearest neighbors bcc vs fcc/hex) ! details: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981 prm%omega = config%getFloat('omega', defaultVal = 1000.0_pReal) & * merge(12.0_pReal,8.0_pReal,any(lattice_structure(p) == [lattice_FCC_ID,lattice_HEX_ID])) ! expand: family => system rho_mob_0 = math_expand(rho_mob_0, N_sl) rho_dip_0 = math_expand(rho_dip_0, N_sl) prm%v0 = math_expand(prm%v0, N_sl) prm%b_sl = math_expand(prm%b_sl, N_sl) prm%Delta_F = math_expand(prm%Delta_F, N_sl) prm%CLambdaSlip = math_expand(prm%CLambdaSlip, N_sl) prm%p = math_expand(prm%p, N_sl) prm%q = math_expand(prm%q, N_sl) prm%B = math_expand(prm%B, N_sl) ! sanity checks if ( prm%D0 <= 0.0_pReal) extmsg = trim(extmsg)//' D0' if ( prm%Qsd <= 0.0_pReal) extmsg = trim(extmsg)//' Qsd' if (any(rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_mob_0' if (any(rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rho_dip_0' if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v0' if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl' if (any(prm%Delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' Delta_F' if (any(prm%CLambdaSlip <= 0.0_pReal)) extmsg = trim(extmsg)//' CLambdaSlip' if (any(prm%B < 0.0_pReal)) extmsg = trim(extmsg)//' B' if (any(prm%p<=0.0_pReal .or. prm%p>1.0_pReal)) extmsg = trim(extmsg)//' p' if (any(prm%q< 1.0_pReal .or. prm%q>2.0_pReal)) extmsg = trim(extmsg)//' q' else slipActive rho_mob_0 = emptyRealArray; rho_dip_0 = emptyRealArray allocate(prm%b_sl,prm%Delta_F,prm%v0,prm%CLambdaSlip,prm%p,prm%q,prm%B,source=emptyRealArray) allocate(prm%forestProjection(0,0),prm%h_sl_sl(0,0)) endif slipActive !-------------------------------------------------------------------------------------------------- ! twin related parameters N_tw = config%getInts('ntwin', defaultVal=emptyIntArray) prm%sum_N_tw = sum(abs(N_tw)) twinActive: if (prm%sum_N_tw > 0) then prm%P_tw = lattice_SchmidMatrix_twin(N_tw,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%h_tw_tw = lattice_interaction_TwinByTwin(N_tw,& config%getFloats('interaction_twintwin'), & config%getString('lattice_structure')) prm%b_tw = config%getFloats('twinburgers', requiredSize=size(N_tw)) prm%t_tw = config%getFloats('twinsize', requiredSize=size(N_tw)) prm%r = config%getFloats('r_twin', requiredSize=size(N_tw)) prm%xc_twin = config%getFloat('xc_twin') prm%L_tw = config%getFloat('l0_twin') prm%i_tw = config%getFloat('cmfptwin') prm%gamma_char= lattice_characteristicShear_Twin(N_tw,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%C66_tw = lattice_C66_twin(N_tw,prm%C66,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) if (.not. prm%fccTwinTransNucleation) then prm%dot_N_0_tw = config%getFloats('ndot0_twin') prm%dot_N_0_tw = math_expand(prm%dot_N_0_tw,N_tw) endif ! expand: family => system prm%b_tw = math_expand(prm%b_tw,N_tw) prm%t_tw = math_expand(prm%t_tw,N_tw) prm%r = math_expand(prm%r,N_tw) ! sanity checks if ( prm%xc_twin < 0.0_pReal) extmsg = trim(extmsg)//' xc_twin' if ( prm%L_tw < 0.0_pReal) extmsg = trim(extmsg)//' L_tw' if ( prm%i_tw < 0.0_pReal) extmsg = trim(extmsg)//' i_tw' if (any(prm%b_tw < 0.0_pReal)) extmsg = trim(extmsg)//' b_tw' if (any(prm%t_tw < 0.0_pReal)) extmsg = trim(extmsg)//' t_tw' if (any(prm%r < 0.0_pReal)) extmsg = trim(extmsg)//' r' if (.not. prm%fccTwinTransNucleation) then if (any(prm%dot_N_0_tw < 0.0_pReal)) extmsg = trim(extmsg)//' dot_N_0_tw' endif else twinActive allocate(prm%gamma_char,prm%b_tw,prm%dot_N_0_tw,prm%t_tw,prm%r,source=emptyRealArray) allocate(prm%h_tw_tw(0,0)) endif twinActive !-------------------------------------------------------------------------------------------------- ! transformation related parameters N_tr = config%getInts('ntrans', defaultVal=emptyIntArray) prm%sum_N_tr = sum(abs(N_tr)) transActive: if (prm%sum_N_tr > 0) then prm%b_tr = config%getFloats('transburgers') prm%b_tr = math_expand(prm%b_tr,N_tr) prm%h = config%getFloat('transstackheight', defaultVal=0.0_pReal) ! ToDo: How to handle that??? prm%i_tr = config%getFloat('cmfptrans', defaultVal=0.0_pReal) ! ToDo: How to handle that??? prm%gamma_fcc_hex = config%getFloat('deltag') prm%xc_trans = config%getFloat('xc_trans', defaultVal=0.0_pReal) ! ToDo: How to handle that??? prm%L_tr = config%getFloat('l0_trans') prm%h_tr_tr = lattice_interaction_TransByTrans(N_tr,config%getFloats('interaction_transtrans'), & config%getString('lattice_structure')) prm%C66_tr = lattice_C66_trans(N_tr,prm%C66,config%getString('trans_lattice_structure'), & 0.0_pReal, & config%getFloat('a_bcc', defaultVal=0.0_pReal), & config%getFloat('a_fcc', defaultVal=0.0_pReal)) prm%P_tr = lattice_SchmidMatrix_trans(N_tr,config%getString('trans_lattice_structure'), & 0.0_pReal, & config%getFloat('a_bcc', defaultVal=0.0_pReal), & config%getFloat('a_fcc', defaultVal=0.0_pReal)) if (lattice_structure(p) /= lattice_FCC_ID) then prm%dot_N_0_tr = config%getFloats('ndot0_trans') prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,N_tr) endif prm%t_tr = config%getFloats('lamellarsize') prm%t_tr = math_expand(prm%t_tr,N_tr) prm%s = config%getFloats('s_trans',defaultVal=[0.0_pReal]) prm%s = math_expand(prm%s,N_tr) ! sanity checks if ( prm%xc_trans < 0.0_pReal) extmsg = trim(extmsg)//' xc_trans' if ( prm%L_tr < 0.0_pReal) extmsg = trim(extmsg)//' L_tr' if ( prm%i_tr < 0.0_pReal) extmsg = trim(extmsg)//' i_tr' if (any(prm%t_tr < 0.0_pReal)) extmsg = trim(extmsg)//' t_tr' if (any(prm%s < 0.0_pReal)) extmsg = trim(extmsg)//' s' if (lattice_structure(p) /= lattice_FCC_ID) then if (any(prm%dot_N_0_tr < 0.0_pReal)) extmsg = trim(extmsg)//' dot_N_0_tr' endif else transActive allocate(prm%s,prm%b_tr,prm%t_tr,prm%dot_N_0_tr,source=emptyRealArray) allocate(prm%h_tr_tr(0,0)) endif transActive !-------------------------------------------------------------------------------------------------- ! shearband related parameters prm%sbVelocity = config%getFloat('shearbandvelocity',defaultVal=0.0_pReal) if (prm%sbVelocity > 0.0_pReal) then prm%sbResistance = config%getFloat('shearbandresistance') prm%E_sb = config%getFloat('qedgepersbsystem') prm%p_sb = config%getFloat('p_shearband') prm%q_sb = config%getFloat('q_shearband') ! sanity checks if (prm%sbResistance < 0.0_pReal) extmsg = trim(extmsg)//' shearbandresistance' if (prm%E_sb < 0.0_pReal) extmsg = trim(extmsg)//' qedgepersbsystem' if (prm%p_sb <= 0.0_pReal) extmsg = trim(extmsg)//' p_shearband' if (prm%q_sb <= 0.0_pReal) extmsg = trim(extmsg)//' q_shearband' endif !-------------------------------------------------------------------------------------------------- ! parameters required for several mechanisms and their interactions if(prm%sum_N_sl + prm%sum_N_tw + prm%sum_N_tw > 0) & prm%D = config%getFloat('grainsize') twinOrSlipActive: if (prm%sum_N_tw + prm%sum_N_tr > 0) then prm%SFE_0K = config%getFloat('sfe_0k') prm%dSFE_dT = config%getFloat('dsfe_dt') prm%V_cs = config%getFloat('vcrossslip') endif twinOrSlipActive slipAndTwinActive: if (prm%sum_N_sl * prm%sum_N_tw > 0) then prm%h_sl_tw = lattice_interaction_SlipByTwin(N_sl,N_tw,& config%getFloats('interaction_sliptwin'), & config%getString('lattice_structure')) if (prm%fccTwinTransNucleation .and. size(N_tw) /= 1) extmsg = trim(extmsg)//' interaction_sliptwin' endif slipAndTwinActive slipAndTransActive: if (prm%sum_N_sl * prm%sum_N_tr > 0) then prm%h_sl_tr = lattice_interaction_SlipByTrans(N_sl,N_tr,& config%getFloats('interaction_sliptrans'), & config%getString('lattice_structure')) if (prm%fccTwinTransNucleation .and. size(N_tr) /= 1) extmsg = trim(extmsg)//' interaction_sliptrans' endif slipAndTransActive !-------------------------------------------------------------------------------------------------- ! allocate state arrays NipcMyPhase = count(material_phaseAt == p) * discretization_nIP sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl & + size(['f_tw']) * prm%sum_N_tw & + size(['f_tr']) * prm%sum_N_tr sizeState = sizeDotState call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0) !-------------------------------------------------------------------------------------------------- ! locally defined state aliases and initialization of state0 and atol startIndex = 1 endIndex = prm%sum_N_sl stt%rho_mob=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_mob= spread(rho_mob_0,2,NipcMyPhase) dot%rho_mob=>plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%rho_dip=>plasticState(p)%state(startIndex:endIndex,:) stt%rho_dip= spread(rho_dip_0,2,NipcMyPhase) dot%rho_dip=>plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%gamma_sl=>plasticState(p)%state(startIndex:endIndex,:) dot%gamma_sl=>plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = 1.0e-2_pReal ! global alias plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_tw stt%f_tw=>plasticState(p)%state(startIndex:endIndex,:) dot%f_tw=>plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('f_twin',defaultVal=1.0e-7_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_twin' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_tr stt%f_tr=>plasticState(p)%state(startIndex:endIndex,:) dot%f_tr=>plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('f_trans',defaultVal=1.0e-6_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' f_trans' allocate(dst%Lambda_sl (prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_pass (prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) allocate(dst%Lambda_tw (prm%sum_N_tw,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_hat_tw (prm%sum_N_tw,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_r_tw (prm%sum_N_tw,NipcMyPhase),source=0.0_pReal) allocate(dst%V_tw (prm%sum_N_tw,NipcMyPhase),source=0.0_pReal) allocate(dst%Lambda_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_hat_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_r_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal) allocate(dst%V_tr (prm%sum_N_tr,NipcMyPhase),source=0.0_pReal) plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally end associate !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOTWIN_LABEL//')') enddo end subroutine plastic_dislotwin_init !-------------------------------------------------------------------------------------------------- !> @brief Return the homogenized elasticity matrix. !-------------------------------------------------------------------------------------------------- module function plastic_dislotwin_homogenizedC(ipc,ip,el) result(homogenizedC) real(pReal), dimension(6,6) :: & homogenizedC integer, intent(in) :: & ipc, & !< component-ID of integration point ip, & !< integration point el !< element integer :: i, & of real(pReal) :: f_unrotated of = material_phasememberAt(ipc,ip,el) associate(prm => param(phase_plasticityInstance(material_phaseAt(ipc,el))),& stt => state(phase_plasticityInstance(material_phaseAT(ipc,el)))) f_unrotated = 1.0_pReal & - sum(stt%f_tw(1:prm%sum_N_tw,of)) & - sum(stt%f_tr(1:prm%sum_N_tr,of)) homogenizedC = f_unrotated * prm%C66 do i=1,prm%sum_N_tw homogenizedC = homogenizedC & + stt%f_tw(i,of)*prm%C66_tw(1:6,1:6,i) enddo do i=1,prm%sum_N_tr homogenizedC = homogenizedC & + stt%f_tr(i,of)*prm%C66_tr(1:6,1:6,i) enddo end associate end function plastic_dislotwin_homogenizedC !-------------------------------------------------------------------------------------------------- !> @brief Calculate plastic velocity gradient and its tangent. !-------------------------------------------------------------------------------------------------- module subroutine plastic_dislotwin_LpAndItsTangent(Lp,dLp_dMp,Mp,T,instance,of) real(pReal), dimension(3,3), intent(out) :: Lp real(pReal), dimension(3,3,3,3), intent(out) :: dLp_dMp real(pReal), dimension(3,3), intent(in) :: Mp integer, intent(in) :: instance,of real(pReal), intent(in) :: T integer :: i,k,l,m,n real(pReal) :: & f_unrotated,StressRatio_p,& BoltzmannRatio, & ddot_gamma_dtau, & tau real(pReal), dimension(param(instance)%sum_N_sl) :: & dot_gamma_sl,ddot_gamma_dtau_slip real(pReal), dimension(param(instance)%sum_N_tw) :: & dot_gamma_twin,ddot_gamma_dtau_twin real(pReal), dimension(param(instance)%sum_N_tr) :: & dot_gamma_tr,ddot_gamma_dtau_trans real(pReal):: dot_gamma_sb real(pReal), dimension(3,3) :: eigVectors, P_sb real(pReal), dimension(3) :: eigValues real(pReal), dimension(3,6), parameter :: & sb_sComposition = & reshape(real([& 1, 0, 1, & 1, 0,-1, & 1, 1, 0, & 1,-1, 0, & 0, 1, 1, & 0, 1,-1 & ],pReal),[ 3,6]), & sb_mComposition = & reshape(real([& 1, 0,-1, & 1, 0,+1, & 1,-1, 0, & 1, 1, 0, & 0, 1,-1, & 0, 1, 1 & ],pReal),[ 3,6]) associate(prm => param(instance), stt => state(instance)) f_unrotated = 1.0_pReal & - sum(stt%f_tw(1:prm%sum_N_tw,of)) & - sum(stt%f_tr(1:prm%sum_N_tr,of)) Lp = 0.0_pReal dLp_dMp = 0.0_pReal call kinetics_slip(Mp,T,instance,of,dot_gamma_sl,ddot_gamma_dtau_slip) slipContribution: do i = 1, prm%sum_N_sl Lp = Lp + dot_gamma_sl(i)*prm%P_sl(1:3,1:3,i) forall (k=1:3,l=1:3,m=1:3,n=1:3) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & + ddot_gamma_dtau_slip(i) * prm%P_sl(k,l,i) * prm%P_sl(m,n,i) enddo slipContribution !ToDo: Why do this before shear banding? Lp = Lp * f_unrotated dLp_dMp = dLp_dMp * f_unrotated shearBandingContribution: if(dNeq0(prm%sbVelocity)) then BoltzmannRatio = prm%E_sb/(kB*T) call math_eigh33(Mp,eigValues,eigVectors) ! is Mp symmetric by design? do i = 1,6 P_sb = 0.5_pReal * math_outer(matmul(eigVectors,sb_sComposition(1:3,i)),& matmul(eigVectors,sb_mComposition(1:3,i))) tau = math_tensordot(Mp,P_sb) significantShearBandStress: if (abs(tau) > tol_math_check) then StressRatio_p = (abs(tau)/prm%sbResistance)**prm%p_sb dot_gamma_sb = sign(prm%sbVelocity*exp(-BoltzmannRatio*(1-StressRatio_p)**prm%q_sb), tau) ddot_gamma_dtau = abs(dot_gamma_sb)*BoltzmannRatio* prm%p_sb*prm%q_sb/ prm%sbResistance & * (abs(tau)/prm%sbResistance)**(prm%p_sb-1.0_pReal) & * (1.0_pReal-StressRatio_p)**(prm%q_sb-1.0_pReal) Lp = Lp + dot_gamma_sb * P_sb forall (k=1:3,l=1:3,m=1:3,n=1:3) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & + ddot_gamma_dtau * P_sb(k,l) * P_sb(m,n) endif significantShearBandStress enddo endif shearBandingContribution call kinetics_twin(Mp,T,dot_gamma_sl,instance,of,dot_gamma_twin,ddot_gamma_dtau_twin) twinContibution: do i = 1, prm%sum_N_tw Lp = Lp + dot_gamma_twin(i)*prm%P_tw(1:3,1:3,i) * f_unrotated forall (k=1:3,l=1:3,m=1:3,n=1:3) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & + ddot_gamma_dtau_twin(i)* prm%P_tw(k,l,i)*prm%P_tw(m,n,i) * f_unrotated enddo twinContibution call kinetics_trans(Mp,T,dot_gamma_sl,instance,of,dot_gamma_tr,ddot_gamma_dtau_trans) transContibution: do i = 1, prm%sum_N_tr Lp = Lp + dot_gamma_tr(i)*prm%P_tr(1:3,1:3,i) * f_unrotated forall (k=1:3,l=1:3,m=1:3,n=1:3) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & + ddot_gamma_dtau_trans(i)* prm%P_tr(k,l,i)*prm%P_tr(m,n,i) * f_unrotated enddo transContibution end associate end subroutine plastic_dislotwin_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief Calculate the rate of change of microstructure. !-------------------------------------------------------------------------------------------------- module subroutine plastic_dislotwin_dotState(Mp,T,instance,of) real(pReal), dimension(3,3), intent(in):: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature at integration point integer, intent(in) :: & instance, & of integer :: i real(pReal) :: & f_unrotated, & rho_dip_distance, & v_cl, & !< climb velocity Gamma, & !< stacking fault energy tau, & sigma_cl, & !< climb stress b_d !< ratio of burgers vector to stacking fault width real(pReal), dimension(param(instance)%sum_N_sl) :: & dot_rho_dip_formation, & dot_rho_dip_climb, & rho_dip_distance_min, & dot_gamma_sl real(pReal), dimension(param(instance)%sum_N_tw) :: & dot_gamma_twin real(pReal), dimension(param(instance)%sum_N_tr) :: & dot_gamma_tr associate(prm => param(instance), stt => state(instance), & dot => dotState(instance), dst => dependentState(instance)) f_unrotated = 1.0_pReal & - sum(stt%f_tw(1:prm%sum_N_tw,of)) & - sum(stt%f_tr(1:prm%sum_N_tr,of)) call kinetics_slip(Mp,T,instance,of,dot_gamma_sl) dot%gamma_sl(:,of) = abs(dot_gamma_sl) rho_dip_distance_min = prm%CEdgeDipMinDistance*prm%b_sl slipState: do i = 1, prm%sum_N_sl tau = math_tensordot(Mp,prm%P_sl(1:3,1:3,i)) significantSlipStress: if (dEq0(tau)) then dot_rho_dip_formation(i) = 0.0_pReal dot_rho_dip_climb(i) = 0.0_pReal else significantSlipStress rho_dip_distance = 3.0_pReal*prm%mu*prm%b_sl(i)/(16.0_pReal*PI*abs(tau)) rho_dip_distance = math_clip(rho_dip_distance, right = dst%Lambda_sl(i,of)) rho_dip_distance = math_clip(rho_dip_distance, left = rho_dip_distance_min(i)) if (prm%dipoleFormation) then dot_rho_dip_formation(i) = 2.0_pReal*(rho_dip_distance-rho_dip_distance_min(i))/prm%b_sl(i) & * stt%rho_mob(i,of)*abs(dot_gamma_sl(i)) else dot_rho_dip_formation(i) = 0.0_pReal endif if (dEq(rho_dip_distance,rho_dip_distance_min(i))) then dot_rho_dip_climb(i) = 0.0_pReal else !@details: Refer: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981 sigma_cl = dot_product(prm%n0_sl(1:3,i),matmul(Mp,prm%n0_sl(1:3,i))) if (prm%ExtendedDislocations) then Gamma = prm%SFE_0K + prm%dSFE_dT * T b_d = 24.0_pReal*PI*(1.0_pReal - prm%nu)/(2.0_pReal + prm%nu)* Gamma/(prm%mu*prm%b_sl(i)) else b_d = 1.0_pReal endif v_cl = 2.0_pReal*prm%omega*b_d**2.0_pReal*exp(-prm%Qsd/(kB*T)) & * (exp(abs(sigma_cl)*prm%b_sl(i)**3.0_pReal/(kB*T)) - 1.0_pReal) dot_rho_dip_climb(i) = 4.0_pReal*v_cl*stt%rho_dip(i,of) & / (rho_dip_distance-rho_dip_distance_min(i)) endif endif significantSlipStress enddo slipState dot%rho_mob(:,of) = abs(dot_gamma_sl)/(prm%b_sl*dst%Lambda_sl(:,of)) & - dot_rho_dip_formation & - 2.0_pReal*rho_dip_distance_min/prm%b_sl * stt%rho_mob(:,of)*abs(dot_gamma_sl) dot%rho_dip(:,of) = dot_rho_dip_formation & - 2.0_pReal*rho_dip_distance_min/prm%b_sl * stt%rho_dip(:,of)*abs(dot_gamma_sl) & - dot_rho_dip_climb call kinetics_twin(Mp,T,dot_gamma_sl,instance,of,dot_gamma_twin) dot%f_tw(:,of) = f_unrotated*dot_gamma_twin/prm%gamma_char call kinetics_trans(Mp,T,dot_gamma_sl,instance,of,dot_gamma_tr) dot%f_tr(:,of) = f_unrotated*dot_gamma_tr end associate end subroutine plastic_dislotwin_dotState !-------------------------------------------------------------------------------------------------- !> @brief Calculate derived quantities from state. !-------------------------------------------------------------------------------------------------- module subroutine plastic_dislotwin_dependentState(T,instance,of) integer, intent(in) :: & instance, & of real(pReal), intent(in) :: & T real(pReal) :: & sumf_twin,Gamma,sumf_trans real(pReal), dimension(param(instance)%sum_N_sl) :: & inv_lambda_sl_sl, & !< 1/mean free distance between 2 forest dislocations seen by a moving dislocation inv_lambda_sl_tw, & !< 1/mean free distance between 2 twin stacks from different systems seen by a moving dislocation inv_lambda_sl_tr !< 1/mean free distance between 2 martensite lamellar from different systems seen by a moving dislocation real(pReal), dimension(param(instance)%sum_N_tw) :: & inv_lambda_tw_tw, & !< 1/mean free distance between 2 twin stacks from different systems seen by a growing twin f_over_t_tw real(pReal), dimension(param(instance)%sum_N_tr) :: & inv_lambda_tr_tr, & !< 1/mean free distance between 2 martensite stacks from different systems seen by a growing martensite f_over_t_tr real(pReal), dimension(:), allocatable :: & x0 associate(prm => param(instance),& stt => state(instance),& dst => dependentState(instance)) sumf_twin = sum(stt%f_tw(1:prm%sum_N_tw,of)) sumf_trans = sum(stt%f_tr(1:prm%sum_N_tr,of)) Gamma = prm%SFE_0K + prm%dSFE_dT * T !* rescaled volume fraction for topology f_over_t_tw = stt%f_tw(1:prm%sum_N_tw,of)/prm%t_tw ! this is per system ... f_over_t_tr = sumf_trans/prm%t_tr ! but this not ! ToDo ...Physically correct, but naming could be adjusted inv_lambda_sl_sl = sqrt(matmul(prm%forestProjection, & stt%rho_mob(:,of)+stt%rho_dip(:,of)))/prm%CLambdaSlip if (prm%sum_N_tw > 0 .and. prm%sum_N_sl > 0) & inv_lambda_sl_tw = matmul(prm%h_sl_tw,f_over_t_tw)/(1.0_pReal-sumf_twin) inv_lambda_tw_tw = matmul(prm%h_tw_tw,f_over_t_tw)/(1.0_pReal-sumf_twin) if (prm%sum_N_tr > 0 .and. prm%sum_N_sl > 0) & inv_lambda_sl_tr = matmul(prm%h_sl_tr,f_over_t_tr)/(1.0_pReal-sumf_trans) inv_lambda_tr_tr = matmul(prm%h_tr_tr,f_over_t_tr)/(1.0_pReal-sumf_trans) if ((prm%sum_N_tw > 0) .or. (prm%sum_N_tr > 0)) then ! ToDo: better logic needed here dst%Lambda_sl(:,of) = prm%D & / (1.0_pReal+prm%D*(inv_lambda_sl_sl + inv_lambda_sl_tw + inv_lambda_sl_tr)) else dst%Lambda_sl(:,of) = prm%D & / (1.0_pReal+prm%D*inv_lambda_sl_sl) !!!!!! correct? endif dst%Lambda_tw(:,of) = prm%i_tw*prm%D/(1.0_pReal+prm%D*inv_lambda_tw_tw) dst%Lambda_tr(:,of) = prm%i_tr*prm%D/(1.0_pReal+prm%D*inv_lambda_tr_tr) !* threshold stress for dislocation motion dst%tau_pass(:,of) = prm%mu*prm%b_sl* sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of))) !* threshold stress for growing twin/martensite if(prm%sum_N_tw == prm%sum_N_sl) & dst%tau_hat_tw(:,of) = Gamma/(3.0_pReal*prm%b_tw) & + 3.0_pReal*prm%b_tw*prm%mu/(prm%L_tw*prm%b_sl) ! slip burgers here correct? if(prm%sum_N_tr == prm%sum_N_sl) & dst%tau_hat_tr(:,of) = Gamma/(3.0_pReal*prm%b_tr) & + 3.0_pReal*prm%b_tr*prm%mu/(prm%L_tr*prm%b_sl) & ! slip burgers here correct? + prm%h*prm%gamma_fcc_hex/ (3.0_pReal*prm%b_tr) dst%V_tw(:,of) = (PI/4.0_pReal)*prm%t_tw*dst%Lambda_tw(:,of)**2.0_pReal dst%V_tr(:,of) = (PI/4.0_pReal)*prm%t_tr*dst%Lambda_tr(:,of)**2.0_pReal x0 = prm%mu*prm%b_tw**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip and is the same for twin and trans dst%tau_r_tw(:,of) = prm%mu*prm%b_tw/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%xc_twin)+cos(pi/3.0_pReal)/x0) x0 = prm%mu*prm%b_tr**2.0_pReal/(Gamma*8.0_pReal*PI)*(2.0_pReal+prm%nu)/(1.0_pReal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip dst%tau_r_tr(:,of) = prm%mu*prm%b_tr/(2.0_pReal*PI)*(1.0_pReal/(x0+prm%xc_trans)+cos(pi/3.0_pReal)/x0) end associate end subroutine plastic_dislotwin_dependentState !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- module subroutine plastic_dislotwin_results(instance,group) integer, intent(in) :: instance character(len=*), intent(in) :: group integer :: o associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) case('rho_mob') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_mob,'rho_mob',& 'mobile dislocation density','1/m²') case('rho_dip') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,'rho_dip',& 'dislocation dipole density''1/m²') case('gamma_sl') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,'gamma_sl',& 'plastic shear','1') case('lambda_sl') if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,'Lambda_sl',& 'mean free path for slip','m') case('tau_pass') if(prm%sum_N_sl>0) call results_writeDataset(group,dst%tau_pass,'tau_pass',& 'passing stress for slip','Pa') case('f_tw') if(prm%sum_N_tw>0) call results_writeDataset(group,stt%f_tw,'f_tw',& 'twinned volume fraction','m³/m³') case('lambda_tw') if(prm%sum_N_tw>0) call results_writeDataset(group,dst%Lambda_tw,'Lambda_tw',& 'mean free path for twinning','m') case('tau_hat_tw') if(prm%sum_N_tw>0) call results_writeDataset(group,dst%tau_hat_tw,'tau_hat_tw',& 'threshold stress for twinning','Pa') case('f_tr') if(prm%sum_N_tr>0) call results_writeDataset(group,stt%f_tr,'f_tr',& 'martensite volume fraction','m³/m³') end select enddo outputsLoop end associate end subroutine plastic_dislotwin_results !-------------------------------------------------------------------------------------------------- !> @brief Calculate shear rates on slip systems, their derivatives with respect to resolved ! stress, and the resolved stress. !> @details Derivatives and resolved stress are calculated only optionally. ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end !-------------------------------------------------------------------------------------------------- pure subroutine kinetics_slip(Mp,T,instance,of, & dot_gamma_sl,ddot_gamma_dtau_slip,tau_slip) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of real(pReal), dimension(param(instance)%sum_N_sl), intent(out) :: & dot_gamma_sl real(pReal), dimension(param(instance)%sum_N_sl), optional, intent(out) :: & ddot_gamma_dtau_slip, & tau_slip real(pReal), dimension(param(instance)%sum_N_sl) :: & ddot_gamma_dtau real(pReal), dimension(param(instance)%sum_N_sl) :: & tau, & stressRatio, & StressRatio_p, & BoltzmannRatio, & v_wait_inverse, & !< inverse of the effective velocity of a dislocation waiting at obstacles (unsigned) v_run_inverse, & !< inverse of the velocity of a free moving dislocation (unsigned) dV_wait_inverse_dTau, & dV_run_inverse_dTau, & dV_dTau, & tau_eff !< effective resolved stress integer :: i associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) do i = 1, prm%sum_N_sl tau(i) = math_tensordot(Mp,prm%P_sl(1:3,1:3,i)) enddo tau_eff = abs(tau)-dst%tau_pass(:,of) significantStress: where(tau_eff > tol_math_check) stressRatio = tau_eff/prm%tau_0 StressRatio_p = stressRatio** prm%p BoltzmannRatio = prm%Delta_F/(kB*T) v_wait_inverse = prm%v0**(-1.0_pReal) * exp(BoltzmannRatio*(1.0_pReal-StressRatio_p)** prm%q) v_run_inverse = prm%B/(tau_eff*prm%b_sl) dot_gamma_sl = sign(stt%rho_mob(:,of)*prm%b_sl/(v_wait_inverse+v_run_inverse),tau) dV_wait_inverse_dTau = -1.0_pReal * v_wait_inverse * prm%p * prm%q * BoltzmannRatio & * (stressRatio**(prm%p-1.0_pReal)) & * (1.0_pReal-StressRatio_p)**(prm%q-1.0_pReal) & / prm%tau_0 dV_run_inverse_dTau = -1.0_pReal * v_run_inverse/tau_eff dV_dTau = -1.0_pReal * (dV_wait_inverse_dTau+dV_run_inverse_dTau) & / (v_wait_inverse+v_run_inverse)**2.0_pReal ddot_gamma_dtau = dV_dTau*stt%rho_mob(:,of)*prm%b_sl else where significantStress dot_gamma_sl = 0.0_pReal ddot_gamma_dtau = 0.0_pReal end where significantStress end associate if(present(ddot_gamma_dtau_slip)) ddot_gamma_dtau_slip = ddot_gamma_dtau if(present(tau_slip)) tau_slip = tau end subroutine kinetics_slip !-------------------------------------------------------------------------------------------------- !> @brief Calculate shear rates on twin systems and their derivatives with respect to resolved ! stress. !> @details Derivatives are calculated only optionally. ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end. !-------------------------------------------------------------------------------------------------- pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,instance,of,& dot_gamma_twin,ddot_gamma_dtau_twin) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of real(pReal), dimension(param(instance)%sum_N_sl), intent(in) :: & dot_gamma_sl real(pReal), dimension(param(instance)%sum_N_tw), intent(out) :: & dot_gamma_twin real(pReal), dimension(param(instance)%sum_N_tw), optional, intent(out) :: & ddot_gamma_dtau_twin real, dimension(param(instance)%sum_N_tw) :: & tau, & Ndot0, & stressRatio_r, & ddot_gamma_dtau integer :: i,s1,s2 associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) do i = 1, prm%sum_N_tw tau(i) = math_tensordot(Mp,prm%P_tw(1:3,1:3,i)) isFCC: if (prm%fccTwinTransNucleation) then s1=prm%fcc_twinNucleationSlipPair(1,i) s2=prm%fcc_twinNucleationSlipPair(2,i) if (tau(i) < dst%tau_r_tw(i,of)) then ! ToDo: correct? Ndot0=(abs(dot_gamma_sl(s1))*(stt%rho_mob(s2,of)+stt%rho_dip(s2,of))+& abs(dot_gamma_sl(s2))*(stt%rho_mob(s1,of)+stt%rho_dip(s1,of)))/& ! ToDo: MD: it would be more consistent to use shearrates from state (prm%L_tw*prm%b_sl(i))*& (1.0_pReal-exp(-prm%V_cs/(kB*T)*(dst%tau_r_tw(i,of)-tau(i)))) ! P_ncs else Ndot0=0.0_pReal end if else isFCC Ndot0=prm%dot_N_0_tw(i) endif isFCC enddo significantStress: where(tau > tol_math_check) StressRatio_r = (dst%tau_hat_tw(:,of)/tau)**prm%r dot_gamma_twin = prm%gamma_char * dst%V_tw(:,of) * Ndot0*exp(-StressRatio_r) ddot_gamma_dtau = (dot_gamma_twin*prm%r/tau)*StressRatio_r else where significantStress dot_gamma_twin = 0.0_pReal ddot_gamma_dtau = 0.0_pReal end where significantStress end associate if(present(ddot_gamma_dtau_twin)) ddot_gamma_dtau_twin = ddot_gamma_dtau end subroutine kinetics_twin !-------------------------------------------------------------------------------------------------- !> @brief Calculate shear rates on transformation systems and their derivatives with respect to ! resolved stress. !> @details Derivatives are calculated only optionally. ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end. !-------------------------------------------------------------------------------------------------- pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,instance,of,& dot_gamma_tr,ddot_gamma_dtau_trans) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of real(pReal), dimension(param(instance)%sum_N_sl), intent(in) :: & dot_gamma_sl real(pReal), dimension(param(instance)%sum_N_tr), intent(out) :: & dot_gamma_tr real(pReal), dimension(param(instance)%sum_N_tr), optional, intent(out) :: & ddot_gamma_dtau_trans real, dimension(param(instance)%sum_N_tr) :: & tau, & Ndot0, & stressRatio_s, & ddot_gamma_dtau integer :: i,s1,s2 associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) do i = 1, prm%sum_N_tr tau(i) = math_tensordot(Mp,prm%P_tr(1:3,1:3,i)) isFCC: if (prm%fccTwinTransNucleation) then s1=prm%fcc_twinNucleationSlipPair(1,i) s2=prm%fcc_twinNucleationSlipPair(2,i) if (tau(i) < dst%tau_r_tr(i,of)) then ! ToDo: correct? Ndot0=(abs(dot_gamma_sl(s1))*(stt%rho_mob(s2,of)+stt%rho_dip(s2,of))+& abs(dot_gamma_sl(s2))*(stt%rho_mob(s1,of)+stt%rho_dip(s1,of)))/& ! ToDo: MD: it would be more consistent to use shearrates from state (prm%L_tr*prm%b_sl(i))*& (1.0_pReal-exp(-prm%V_cs/(kB*T)*(dst%tau_r_tr(i,of)-tau(i)))) ! P_ncs else Ndot0=0.0_pReal end if else isFCC Ndot0=prm%dot_N_0_tr(i) endif isFCC enddo significantStress: where(tau > tol_math_check) StressRatio_s = (dst%tau_hat_tr(:,of)/tau)**prm%s dot_gamma_tr = dst%V_tr(:,of) * Ndot0*exp(-StressRatio_s) ddot_gamma_dtau = (dot_gamma_tr*prm%s/tau)*StressRatio_s else where significantStress dot_gamma_tr = 0.0_pReal ddot_gamma_dtau = 0.0_pReal end where significantStress end associate if(present(ddot_gamma_dtau_trans)) ddot_gamma_dtau_trans = ddot_gamma_dtau end subroutine kinetics_trans end submodule plastic_dislotwin # 42 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_disloUCLA.f90" 1 !-------------------------------------------------------------------------------------------------- !> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @author David Cereceda, Lawrence Livermore National Laboratory !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH !> @brief crystal plasticity model for bcc metals, especially Tungsten !-------------------------------------------------------------------------------------------------- submodule(constitutive) plastic_disloUCLA real(pReal), parameter :: & kB = 1.38e-23_pReal !< Boltzmann constant in J/Kelvin type :: tParameters real(pReal) :: & D = 1.0_pReal, & !< grain size mu = 1.0_pReal, & !< equivalent shear modulus D_0 = 1.0_pReal, & !< prefactor for self-diffusion coefficient Q_cl = 1.0_pReal !< activation energy for dislocation climb real(pReal), allocatable, dimension(:) :: & b_sl, & !< magnitude of burgers vector [m] D_a, & i_sl, & !< Adj. parameter for distance between 2 forest dislocations atomicVolume, & tau_0, & !* mobility law parameters delta_F, & !< activation energy for glide [J] v0, & !< dislocation velocity prefactor [m/s] p, & !< p-exponent in glide velocity q, & !< q-exponent in glide velocity B, & !< friction coefficient kink_height, & !< height of the kink pair w, & !< width of the kink pair omega !< attempt frequency for kink pair nucleation real(pReal), allocatable, dimension(:,:) :: & h_sl_sl, & !< slip resistance from slip activity forestProjection real(pReal), allocatable, dimension(:,:,:) :: & P_sl, & nonSchmid_pos, & nonSchmid_neg integer :: & sum_N_sl !< total number of active slip system character(len=pStringLen), allocatable, dimension(:) :: & output logical :: & dipoleFormation !< flag indicating consideration of dipole formation end type !< container type for internal constitutive parameters type :: tDisloUCLAState real(pReal), dimension(:,:), pointer :: & rho_mob, & rho_dip, & gamma_sl end type tDisloUCLAState type :: tDisloUCLAdependentState real(pReal), dimension(:,:), allocatable :: & Lambda_sl, & threshold_stress end type tDisloUCLAdependentState !-------------------------------------------------------------------------------------------------- ! containers for parameters and state type(tParameters), allocatable, dimension(:) :: param type(tDisloUCLAState), allocatable, dimension(:) :: & dotState, & state type(tDisloUCLAdependentState), allocatable, dimension(:) :: dependentState contains !-------------------------------------------------------------------------------------------------- !> @brief Perform module initialization. !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- module subroutine plastic_disloUCLA_init integer :: & Ninstance, & p, i, & NipcMyPhase, & sizeState, sizeDotState, & startIndex, endIndex integer, dimension(:), allocatable :: & N_sl real(pReal),dimension(:), allocatable :: & rho_mob_0, & !< initial dislocation density rho_dip_0, & !< initial dipole density a !< non-Schmid coefficients character(len=pStringLen) :: & extmsg = '' write(6,'(/,a)') ' <<<+- plastic_'//PLASTICITY_DISLOUCLA_LABEL//' init -+>>>'; flush(6) write(6,'(/,a)') ' Cereceda et al., International Journal of Plasticity 78:242–256, 2016' write(6,'(a)') ' https://dx.doi.org/10.1016/j.ijplas.2015.09.002' Ninstance = count(phase_plasticity == PLASTICITY_DISLOUCLA_ID) if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & write(6,'(a16,1x,i5,/)') '# instances:',Ninstance allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(dotState(Ninstance)) allocate(dependentState(Ninstance)) do p = 1, size(phase_plasticity) if (phase_plasticity(p) /= PLASTICITY_DISLOUCLA_ID) cycle associate(prm => param(phase_plasticityInstance(p)), & dot => dotState(phase_plasticityInstance(p)), & stt => state(phase_plasticityInstance(p)), & dst => dependentState(phase_plasticityInstance(p)), & config => config_phase(p)) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) ! This data is read in already in lattice prm%mu = lattice_mu(p) !-------------------------------------------------------------------------------------------------- ! slip related parameters N_sl = config%getInts('nslip',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%P_sl = lattice_SchmidMatrix_slip(N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) if(trim(config%getString('lattice_structure')) == 'bcc') then a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray) prm%nonSchmid_pos = lattice_nonSchmidMatrix(N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(N_sl,a,-1) else prm%nonSchmid_pos = prm%P_sl prm%nonSchmid_neg = prm%P_sl endif prm%h_sl_sl = lattice_interaction_SlipBySlip(N_sl,config%getFloats('interaction_slipslip'), & config%getString('lattice_structure')) prm%forestProjection = lattice_forestProjection_edge(N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%forestProjection = transpose(prm%forestProjection) rho_mob_0 = config%getFloats('rhoedge0', requiredSize=size(N_sl)) rho_dip_0 = config%getFloats('rhoedgedip0', requiredSize=size(N_sl)) prm%v0 = config%getFloats('v0', requiredSize=size(N_sl)) prm%b_sl = config%getFloats('slipburgers', requiredSize=size(N_sl)) prm%delta_F = config%getFloats('qedge', requiredSize=size(N_sl)) prm%i_sl = config%getFloats('clambdaslip', requiredSize=size(N_sl)) prm%tau_0 = config%getFloats('tau_peierls', requiredSize=size(N_sl)) prm%p = config%getFloats('p_slip', requiredSize=size(N_sl), & defaultVal=[(1.0_pReal,i=1,size(N_sl))]) prm%q = config%getFloats('q_slip', requiredSize=size(N_sl), & defaultVal=[(1.0_pReal,i=1,size(N_sl))]) prm%kink_height = config%getFloats('kink_height', requiredSize=size(N_sl)) prm%w = config%getFloats('kink_width', requiredSize=size(N_sl)) prm%omega = config%getFloats('omega', requiredSize=size(N_sl)) prm%B = config%getFloats('friction_coeff', requiredSize=size(N_sl)) prm%D = config%getFloat('grainsize') prm%D_0 = config%getFloat('d0') prm%Q_cl = config%getFloat('qsd') prm%atomicVolume = config%getFloat('catomicvolume') * prm%b_sl**3.0_pReal prm%D_a = config%getFloat('cedgedipmindistance') * prm%b_sl prm%dipoleformation = config%getFloat('dipoleformationfactor') > 0.0_pReal !should be on by default, ToDo: change to /key/-type key ! expand: family => system rho_mob_0 = math_expand(rho_mob_0, N_sl) rho_dip_0 = math_expand(rho_dip_0, N_sl) prm%q = math_expand(prm%q, N_sl) prm%p = math_expand(prm%p, N_sl) prm%delta_F = math_expand(prm%delta_F, N_sl) prm%b_sl = math_expand(prm%b_sl, N_sl) prm%kink_height = math_expand(prm%kink_height, N_sl) prm%w = math_expand(prm%w, N_sl) prm%omega = math_expand(prm%omega, N_sl) prm%tau_0 = math_expand(prm%tau_0, N_sl) prm%v0 = math_expand(prm%v0, N_sl) prm%B = math_expand(prm%B, N_sl) prm%i_sl = math_expand(prm%i_sl, N_sl) prm%atomicVolume = math_expand(prm%atomicVolume, N_sl) prm%D_a = math_expand(prm%D_a, N_sl) ! sanity checks if ( prm%D_0 <= 0.0_pReal) extmsg = trim(extmsg)//' D_0' if ( prm%Q_cl <= 0.0_pReal) extmsg = trim(extmsg)//' Q_cl' if (any(rho_mob_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedge0' if (any(rho_dip_0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoedgedip0' if (any(prm%v0 < 0.0_pReal)) extmsg = trim(extmsg)//' v0' if (any(prm%b_sl <= 0.0_pReal)) extmsg = trim(extmsg)//' b_sl' if (any(prm%delta_F <= 0.0_pReal)) extmsg = trim(extmsg)//' qedge' if (any(prm%tau_0 < 0.0_pReal)) extmsg = trim(extmsg)//' tau_0' if (any(prm%D_a <= 0.0_pReal)) extmsg = trim(extmsg)//' cedgedipmindistance or b_sl' if (any(prm%atomicVolume <= 0.0_pReal)) extmsg = trim(extmsg)//' catomicvolume or b_sl' else slipActive rho_mob_0= emptyRealArray; rho_dip_0 = emptyRealArray allocate(prm%b_sl,prm%D_a,prm%i_sl,prm%atomicVolume,prm%tau_0, & prm%delta_F,prm%v0,prm%p,prm%q,prm%B,prm%kink_height,prm%w,prm%omega, & source = emptyRealArray) allocate(prm%forestProjection(0,0)) allocate(prm%h_sl_sl (0,0)) endif slipActive !-------------------------------------------------------------------------------------------------- ! allocate state arrays NipcMyPhase = count(material_phaseAt == p) * discretization_nIP sizeDotState = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl sizeState = sizeDotState call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,0) !-------------------------------------------------------------------------------------------------- ! state aliases and initialization startIndex = 1 endIndex = prm%sum_N_sl stt%rho_mob => plasticState(p)%state(startIndex:endIndex,:) stt%rho_mob = spread(rho_mob_0,2,NipcMyPhase) dot%rho_mob => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) if (any(plasticState(p)%atol(startIndex:endIndex) < 0.0_pReal)) extmsg = trim(extmsg)//' atol_rho' startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%rho_dip => plasticState(p)%state(startIndex:endIndex,:) stt%rho_dip = spread(rho_dip_0,2,NipcMyPhase) dot%rho_dip => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = config%getFloat('atol_rho',defaultVal=1.0_pReal) startIndex = endIndex + 1 endIndex = endIndex + prm%sum_N_sl stt%gamma_sl => plasticState(p)%state(startIndex:endIndex,:) dot%gamma_sl => plasticState(p)%dotState(startIndex:endIndex,:) plasticState(p)%atol(startIndex:endIndex) = 1.0e-2_pReal ! global alias plasticState(p)%slipRate => plasticState(p)%dotState(startIndex:endIndex,:) allocate(dst%Lambda_sl(prm%sum_N_sl,NipcMyPhase), source=0.0_pReal) allocate(dst%threshold_stress(prm%sum_N_sl,NipcMyPhase), source=0.0_pReal) plasticState(p)%state0 = plasticState(p)%state ! ToDo: this could be done centrally end associate !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_DISLOUCLA_LABEL//')') enddo end subroutine plastic_disloUCLA_init !-------------------------------------------------------------------------------------------------- !> @brief Calculate plastic velocity gradient and its tangent. !-------------------------------------------------------------------------------------------------- pure module subroutine plastic_disloUCLA_LpAndItsTangent(Lp,dLp_dMp, & Mp,T,instance,of) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient real(pReal), dimension(3,3,3,3), intent(out) :: & dLp_dMp !< derivative of Lp with respect to the Mandel stress real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of integer :: & i,k,l,m,n real(pReal), dimension(param(instance)%sum_N_sl) :: & dot_gamma_pos,dot_gamma_neg, & ddot_gamma_dtau_pos,ddot_gamma_dtau_neg Lp = 0.0_pReal dLp_dMp = 0.0_pReal associate(prm => param(instance)) call kinetics(Mp,T,instance,of,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg) do i = 1, prm%sum_N_sl Lp = Lp + (dot_gamma_pos(i)+dot_gamma_neg(i))*prm%P_sl(1:3,1:3,i) forall (k=1:3,l=1:3,m=1:3,n=1:3) & dLp_dMp(k,l,m,n) = dLp_dMp(k,l,m,n) & + ddot_gamma_dtau_pos(i) * prm%P_sl(k,l,i) * prm%nonSchmid_pos(m,n,i) & + ddot_gamma_dtau_neg(i) * prm%P_sl(k,l,i) * prm%nonSchmid_neg(m,n,i) enddo end associate end subroutine plastic_disloUCLA_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief Calculate the rate of change of microstructure. !-------------------------------------------------------------------------------------------------- module subroutine plastic_disloUCLA_dotState(Mp,T,instance,of) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of real(pReal) :: & VacancyDiffusion real(pReal), dimension(param(instance)%sum_N_sl) :: & gdot_pos, gdot_neg,& tau_pos,& tau_neg, & v_cl, & dot_rho_dip_formation, & dot_rho_dip_climb, & dip_distance associate(prm => param(instance), stt => state(instance),dot => dotState(instance), dst => dependentState(instance)) call kinetics(Mp,T,instance,of,& gdot_pos,gdot_neg, & tau_pos_out = tau_pos,tau_neg_out = tau_neg) dot%gamma_sl(:,of) = (gdot_pos+gdot_neg) ! ToDo: needs to be abs VacancyDiffusion = prm%D_0*exp(-prm%Q_cl/(kB*T)) where(dEq0(tau_pos)) ! ToDo: use avg of pos and neg dot_rho_dip_formation = 0.0_pReal dot_rho_dip_climb = 0.0_pReal else where dip_distance = math_clip(3.0_pReal*prm%mu*prm%b_sl/(16.0_pReal*PI*abs(tau_pos)), & prm%D_a, & ! lower limit dst%Lambda_sl(:,of)) ! upper limit dot_rho_dip_formation = merge(2.0_pReal*dip_distance* stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of))/prm%b_sl, & ! ToDo: ignore region of spontaneous annihilation 0.0_pReal, & prm%dipoleformation) v_cl = (3.0_pReal*prm%mu*VacancyDiffusion*prm%atomicVolume/(2.0_pReal*pi*kB*T)) & * (1.0_pReal/(dip_distance+prm%D_a)) dot_rho_dip_climb = (4.0_pReal*v_cl*stt%rho_dip(:,of))/(dip_distance-prm%D_a) ! ToDo: Discuss with Franz: Stress dependency? end where dot%rho_mob(:,of) = abs(dot%gamma_sl(:,of))/(prm%b_sl*dst%Lambda_sl(:,of)) & ! multiplication - dot_rho_dip_formation & - (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of)) ! Spontaneous annihilation of 2 single edge dislocations dot%rho_dip(:,of) = dot_rho_dip_formation & - (2.0_pReal*prm%D_a)/prm%b_sl*stt%rho_dip(:,of)*abs(dot%gamma_sl(:,of)) & ! Spontaneous annihilation of a single edge dislocation with a dipole constituent - dot_rho_dip_climb end associate end subroutine plastic_disloUCLA_dotState !-------------------------------------------------------------------------------------------------- !> @brief Calculate derived quantities from state. !-------------------------------------------------------------------------------------------------- module subroutine plastic_disloUCLA_dependentState(instance,of) integer, intent(in) :: & instance, & of real(pReal), dimension(param(instance)%sum_N_sl) :: & dislocationSpacing associate(prm => param(instance), stt => state(instance),dst => dependentState(instance)) dislocationSpacing = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,of)+stt%rho_dip(:,of))) dst%threshold_stress(:,of) = prm%mu*prm%b_sl & * sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of))) dst%Lambda_sl(:,of) = prm%D/(1.0_pReal+prm%D*dislocationSpacing/prm%i_sl) end associate end subroutine plastic_disloUCLA_dependentState !-------------------------------------------------------------------------------------------------- !> @brief Write results to HDF5 output file. !-------------------------------------------------------------------------------------------------- module subroutine plastic_disloUCLA_results(instance,group) integer, intent(in) :: instance character(len=*), intent(in) :: group integer :: o associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) case('edge_density') ! ToDo: should be rho_mob if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_mob,'rho_mob',& 'mobile dislocation density','1/m²') case('dipole_density') ! ToDo: should be rho_dip if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip,'rho_dip',& 'dislocation dipole density''1/m²') case('shear_rate_slip') ! should be gamma if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma_sl,'dot_gamma_sl',& ! this is not dot!! 'plastic shear','1') case('mfp_slip') !ToDo: should be Lambda if(prm%sum_N_sl>0) call results_writeDataset(group,dst%Lambda_sl,'Lambda_sl',& 'mean free path for slip','m') case('threshold_stress_slip') !ToDo: should be tau_pass if(prm%sum_N_sl>0) call results_writeDataset(group,dst%threshold_stress,'tau_pass',& 'threshold stress for slip','Pa') end select enddo outputsLoop end associate end subroutine plastic_disloUCLA_results !-------------------------------------------------------------------------------------------------- !> @brief Calculate shear rates on slip systems, their derivatives with respect to resolved ! stress, and the resolved stress. !> @details Derivatives and resolved stress are calculated only optionally. ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to ! have the optional arguments at the end !-------------------------------------------------------------------------------------------------- pure subroutine kinetics(Mp,T,instance,of, & dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg,tau_pos_out,tau_neg_out) real(pReal), dimension(3,3), intent(in) :: & Mp !< Mandel stress real(pReal), intent(in) :: & T !< temperature integer, intent(in) :: & instance, & of real(pReal), intent(out), dimension(param(instance)%sum_N_sl) :: & dot_gamma_pos, & dot_gamma_neg real(pReal), intent(out), optional, dimension(param(instance)%sum_N_sl) :: & ddot_gamma_dtau_pos, & ddot_gamma_dtau_neg, & tau_pos_out, & tau_neg_out real(pReal), dimension(param(instance)%sum_N_sl) :: & StressRatio, & StressRatio_p,StressRatio_pminus1, & dvel, vel, & tau_pos,tau_neg, & t_n, t_k, dtk,dtn, & needsGoodName ! ToDo: @Karo: any idea? integer :: j associate(prm => param(instance), stt => state(instance), dst => dependentState(instance)) do j = 1, prm%sum_N_sl tau_pos(j) = math_tensordot(Mp,prm%nonSchmid_pos(1:3,1:3,j)) tau_neg(j) = math_tensordot(Mp,prm%nonSchmid_neg(1:3,1:3,j)) enddo if (present(tau_pos_out)) tau_pos_out = tau_pos if (present(tau_neg_out)) tau_neg_out = tau_neg associate(BoltzmannRatio => prm%delta_F/(kB*T), & dot_gamma_0 => stt%rho_mob(:,of)*prm%b_sl*prm%v0, & effectiveLength => dst%Lambda_sl(:,of) - prm%w) significantPositiveTau: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check) StressRatio = (abs(tau_pos)-dst%threshold_stress(:,of))/prm%tau_0 StressRatio_p = StressRatio** prm%p StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal) needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q) t_n = prm%b_sl/(needsGoodName*prm%omega*effectiveLength) t_k = effectiveLength * prm%B /(2.0_pReal*prm%b_sl*tau_pos) vel = prm%kink_height/(t_n + t_k) dot_gamma_pos = dot_gamma_0 * sign(vel,tau_pos) * 0.5_pReal else where significantPositiveTau dot_gamma_pos = 0.0_pReal end where significantPositiveTau if (present(ddot_gamma_dtau_pos)) then significantPositiveTau2: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check) dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) & * (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_0 dtk = -1.0_pReal * t_k / tau_pos dvel = -1.0_pReal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_pReal ddot_gamma_dtau_pos = dot_gamma_0 * dvel* 0.5_pReal else where significantPositiveTau2 ddot_gamma_dtau_pos = 0.0_pReal end where significantPositiveTau2 endif significantNegativeTau: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check) StressRatio = (abs(tau_neg)-dst%threshold_stress(:,of))/prm%tau_0 StressRatio_p = StressRatio** prm%p StressRatio_pminus1 = StressRatio**(prm%p-1.0_pReal) needsGoodName = exp(-BoltzmannRatio*(1-StressRatio_p) ** prm%q) t_n = prm%b_sl/(needsGoodName*prm%omega*effectiveLength) t_k = effectiveLength * prm%B /(2.0_pReal*prm%b_sl*tau_pos) vel = prm%kink_height/(t_n + t_k) dot_gamma_neg = dot_gamma_0 * sign(vel,tau_neg) * 0.5_pReal else where significantNegativeTau dot_gamma_neg = 0.0_pReal end where significantNegativeTau if (present(ddot_gamma_dtau_neg)) then significantNegativeTau2: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check) dtn = -1.0_pReal * t_n * BoltzmannRatio * prm%p * prm%q * (1.0_pReal-StressRatio_p)**(prm%q - 1.0_pReal) & * (StressRatio)**(prm%p - 1.0_pReal) / prm%tau_0 dtk = -1.0_pReal * t_k / tau_neg dvel = -1.0_pReal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_pReal ddot_gamma_dtau_neg = dot_gamma_0 * dvel * 0.5_pReal else where significantNegativeTau2 ddot_gamma_dtau_neg = 0.0_pReal end where significantNegativeTau2 end if end associate end associate end subroutine kinetics end submodule plastic_disloUCLA # 43 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" 1 !-------------------------------------------------------------------------------------------------- !> @author Christoph Kords, Max-Planck-Institut für Eisenforschung GmbH !> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @brief material subroutine for plasticity including dislocation flux !-------------------------------------------------------------------------------------------------- submodule(constitutive) plastic_nonlocal use geometry_plastic_nonlocal, only: & nIPneighbors => geometry_plastic_nonlocal_nIPneighbors, & IPneighborhood => geometry_plastic_nonlocal_IPneighborhood, & IPvolume => geometry_plastic_nonlocal_IPvolume0, & IParea => geometry_plastic_nonlocal_IParea0, & IPareaNormal => geometry_plastic_nonlocal_IPareaNormal0 real(pReal), parameter :: & kB = 1.38e-23_pReal !< Boltzmann constant in J/Kelvin ! storage order of dislocation types integer, dimension(8), parameter :: & sgl = [1,2,3,4,5,6,7,8] !< signed (single) integer, dimension(5), parameter :: & edg = [1,2,5,6,9], & !< edge scr = [3,4,7,8,10] !< screw integer, dimension(4), parameter :: & mob = [1,2,3,4], & !< mobile imm = [5,6,7,8] !< immobile (blocked) integer, dimension(2), parameter :: & dip = [9,10], & !< dipole imm_edg = imm(1:2), & !< immobile edge imm_scr = imm(3:4) !< immobile screw integer, parameter :: & mob_edg_pos = 1, & !< mobile edge positive mob_edg_neg = 2, & !< mobile edge negative mob_scr_pos = 3, & !< mobile screw positive mob_scr_neg = 4 !< mobile screw positive ! BEGIN DEPRECATED integer, dimension(:,:,:), allocatable :: & iRhoU, & !< state indices for unblocked density iV, & !< state indices for dislcation velocities iD !< state indices for stable dipole height !END DEPRECATED real(pReal), dimension(:,:,:,:,:,:), allocatable :: & compatibility !< slip system compatibility between me and my neighbors type :: tInitialParameters !< container type for internal constitutive parameters real(pReal) :: & rhoSglScatter, & !< standard deviation of scatter in initial dislocation density rhoSglRandom, & rhoSglRandomBinning real(pReal), dimension(:), allocatable :: & rhoSglEdgePos0, & !< initial edge_pos dislocation density rhoSglEdgeNeg0, & !< initial edge_neg dislocation density rhoSglScrewPos0, & !< initial screw_pos dislocation density rhoSglScrewNeg0, & !< initial screw_neg dislocation density rhoDipEdge0, & !< initial edge dipole dislocation density rhoDipScrew0 !< initial screw dipole dislocation density integer, dimension(:) ,allocatable :: & N_sl end type tInitialParameters type :: tParameters !< container type for internal constitutive parameters real(pReal) :: & atomicVolume, & !< atomic volume Dsd0, & !< prefactor for self-diffusion coefficient selfDiffusionEnergy, & !< activation enthalpy for diffusion atol_rho, & !< absolute tolerance for dislocation density in state integration significantRho, & !< density considered significant significantN, & !< number of dislocations considered significant doublekinkwidth, & !< width of a doubkle kink in multiples of the burgers vector length b solidSolutionEnergy, & !< activation energy for solid solution in J solidSolutionSize, & !< solid solution obstacle size in multiples of the burgers vector length solidSolutionConcentration, & !< concentration of solid solution in atomic parts p, & !< parameter for kinetic law (Kocks,Argon,Ashby) q, & !< parameter for kinetic law (Kocks,Argon,Ashby) viscosity, & !< viscosity for dislocation glide in Pa s fattack, & !< attack frequency in Hz surfaceTransmissivity, & !< transmissivity at free surface grainboundaryTransmissivity, & !< transmissivity at grain boundary (identified by different texture) CFLfactor, & !< safety factor for CFL flux condition fEdgeMultiplication, & !< factor that determines how much edge dislocations contribute to multiplication (0...1) linetensionEffect, & edgeJogFactor, & mu, & nu real(pReal), dimension(:), allocatable :: & minDipoleHeight_edge, & !< minimum stable edge dipole height minDipoleHeight_screw, & !< minimum stable screw dipole height peierlsstress_edge, & peierlsstress_screw, & lambda0, & !< mean free path prefactor for each burgers !< absolute length of burgers vector [m] real(pReal), dimension(:,:), allocatable :: & slip_normal, & slip_direction, & slip_transverse, & minDipoleHeight, & ! edge and screw peierlsstress, & ! edge and screw interactionSlipSlip ,& !< coefficients for slip-slip interaction forestProjection_Edge, & !< matrix of forest projections of edge dislocations forestProjection_Screw !< matrix of forest projections of screw dislocations real(pReal), dimension(:,:,:), allocatable :: & Schmid, & !< Schmid contribution nonSchmid_pos, & nonSchmid_neg !< combined projection of Schmid and non-Schmid contributions to the resolved shear stress (only for screws) integer :: & sum_N_sl integer, dimension(:), allocatable :: & colinearSystem !< colinear system to the active slip system (only valid for fcc!) character(len=pStringLen), dimension(:), allocatable :: & output logical :: & shortRangeStressCorrection, & !< use of short range stress correction by excess density gradient term nonSchmidActive = .false. end type tParameters type :: tNonlocalMicrostructure real(pReal), allocatable, dimension(:,:) :: & tau_pass, & tau_Back end type tNonlocalMicrostructure type :: tNonlocalState real(pReal), pointer, dimension(:,:) :: & rho, & ! < all dislocations rhoSgl, & rhoSglMobile, & ! iRhoU rho_sgl_mob_edg_pos, & rho_sgl_mob_edg_neg, & rho_sgl_mob_scr_pos, & rho_sgl_mob_scr_neg, & rhoSglImmobile, & rho_sgl_imm_edg_pos, & rho_sgl_imm_edg_neg, & rho_sgl_imm_scr_pos, & rho_sgl_imm_scr_neg, & rhoDip, & rho_dip_edg, & rho_dip_scr, & rho_forest, & gamma, & v, & v_edg_pos, & v_edg_neg, & v_scr_pos, & v_scr_neg end type tNonlocalState type(tNonlocalState), allocatable, dimension(:) :: & deltaState, & dotState, & state, & state0 type(tParameters), dimension(:), allocatable :: param !< containers of constitutive parameters (len Ninstance) type(tNonlocalMicrostructure), dimension(:), allocatable :: microstructure contains !-------------------------------------------------------------------------------------------------- !> @brief module initialization !> @details reads in material parameters, allocates arrays, and does sanity checks !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_init integer :: & Ninstance, & p, & NipcMyPhase, & sizeState, sizeDotState, sizeDependentState, sizeDeltaState, & s1, s2, & s, t, l real(pReal), dimension(:), allocatable :: & a character(len=pStringLen) :: & extmsg = '' type(tInitialParameters) :: & ini write(6,'(/,a)') ' <<<+- constitutive_'//PLASTICITY_NONLOCAL_LABEL//' init -+>>>'; flush(6) write(6,'(/,a)') ' Reuber et al., Acta Materialia 71:333–348, 2014' write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2014.03.012' write(6,'(/,a)') ' Kords, Dissertation RWTH Aachen, 2014' write(6,'(a)') ' http://publications.rwth-aachen.de/record/229993' Ninstance = count(phase_plasticity == PLASTICITY_NONLOCAL_ID) if (iand(debug_level(debug_constitutive),debug_levelBasic) /= 0) & write(6,'(a16,1x,i5,/)') '# instances:',Ninstance allocate(param(Ninstance)) allocate(state(Ninstance)) allocate(state0(Ninstance)) allocate(dotState(Ninstance)) allocate(deltaState(Ninstance)) allocate(microstructure(Ninstance)) do p=1, size(config_phase) if (phase_plasticity(p) /= PLASTICITY_NONLOCAL_ID) cycle associate(prm => param(phase_plasticityInstance(p)), & dot => dotState(phase_plasticityInstance(p)), & stt => state(phase_plasticityInstance(p)), & st0 => state0(phase_plasticityInstance(p)), & del => deltaState(phase_plasticityInstance(p)), & dst => microstructure(phase_plasticityInstance(p)), & config => config_phase(p)) prm%output = config%getStrings('(output)',defaultVal=emptyStringArray) prm%atol_rho = config%getFloat('atol_rho',defaultVal=1.0e4_pReal) ! This data is read in already in lattice prm%mu = lattice_mu(p) prm%nu = lattice_nu(p) ini%N_sl = config%getInts('nslip',defaultVal=emptyIntArray) prm%sum_N_sl = sum(abs(ini%N_sl)) slipActive: if (prm%sum_N_sl > 0) then prm%Schmid = lattice_SchmidMatrix_slip(ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) if(trim(config%getString('lattice_structure')) == 'bcc') then a = config%getFloats('nonschmid_coefficients',defaultVal = emptyRealArray) if(size(a) > 0) prm%nonSchmidActive = .true. prm%nonSchmid_pos = lattice_nonSchmidMatrix(ini%N_sl,a,+1) prm%nonSchmid_neg = lattice_nonSchmidMatrix(ini%N_sl,a,-1) else prm%nonSchmid_pos = prm%Schmid prm%nonSchmid_neg = prm%Schmid endif prm%interactionSlipSlip = lattice_interaction_SlipBySlip(ini%N_sl, & config%getFloats('interaction_slipslip'), & config%getString('lattice_structure')) prm%forestProjection_edge = lattice_forestProjection_edge (ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%forestProjection_screw = lattice_forestProjection_screw(ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%slip_direction = lattice_slip_direction (ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%slip_transverse = lattice_slip_transverse(ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) prm%slip_normal = lattice_slip_normal (ini%N_sl,config%getString('lattice_structure'),& config%getFloat('c/a',defaultVal=0.0_pReal)) ! collinear systems (only for octahedral slip systems in fcc) allocate(prm%colinearSystem(prm%sum_N_sl), source = -1) do s1 = 1, prm%sum_N_sl do s2 = 1, prm%sum_N_sl if (all(dEq0 (math_cross(prm%slip_direction(1:3,s1),prm%slip_direction(1:3,s2)))) .and. & any(dNeq0(math_cross(prm%slip_normal (1:3,s1),prm%slip_normal (1:3,s2))))) & prm%colinearSystem(s1) = s2 enddo enddo ini%rhoSglEdgePos0 = config%getFloats('rhosgledgepos0', requiredSize=size(ini%N_sl)) ini%rhoSglEdgeNeg0 = config%getFloats('rhosgledgeneg0', requiredSize=size(ini%N_sl)) ini%rhoSglScrewPos0 = config%getFloats('rhosglscrewpos0', requiredSize=size(ini%N_sl)) ini%rhoSglScrewNeg0 = config%getFloats('rhosglscrewneg0', requiredSize=size(ini%N_sl)) ini%rhoDipEdge0 = config%getFloats('rhodipedge0', requiredSize=size(ini%N_sl)) ini%rhoDipScrew0 = config%getFloats('rhodipscrew0', requiredSize=size(ini%N_sl)) prm%lambda0 = config%getFloats('lambda0', requiredSize=size(ini%N_sl)) prm%burgers = config%getFloats('burgers', requiredSize=size(ini%N_sl)) prm%lambda0 = math_expand(prm%lambda0,ini%N_sl) prm%burgers = math_expand(prm%burgers,ini%N_sl) prm%minDipoleHeight_edge = config%getFloats('minimumdipoleheightedge', requiredSize=size(ini%N_sl)) prm%minDipoleHeight_screw = config%getFloats('minimumdipoleheightscrew', requiredSize=size(ini%N_sl)) prm%minDipoleHeight_edge = math_expand(prm%minDipoleHeight_edge, ini%N_sl) prm%minDipoleHeight_screw = math_expand(prm%minDipoleHeight_screw,ini%N_sl) allocate(prm%minDipoleHeight(prm%sum_N_sl,2)) prm%minDipoleHeight(:,1) = prm%minDipoleHeight_edge prm%minDipoleHeight(:,2) = prm%minDipoleHeight_screw prm%peierlsstress_edge = config%getFloats('peierlsstressedge', requiredSize=size(ini%N_sl)) prm%peierlsstress_screw = config%getFloats('peierlsstressscrew', requiredSize=size(ini%N_sl)) prm%peierlsstress_edge = math_expand(prm%peierlsstress_edge, ini%N_sl) prm%peierlsstress_screw = math_expand(prm%peierlsstress_screw,ini%N_sl) allocate(prm%peierlsstress(prm%sum_N_sl,2)) prm%peierlsstress(:,1) = prm%peierlsstress_edge prm%peierlsstress(:,2) = prm%peierlsstress_screw prm%significantRho = config%getFloat('significantrho') prm%significantN = config%getFloat('significantn', 0.0_pReal) prm%CFLfactor = config%getFloat('cflfactor',defaultVal=2.0_pReal) prm%atomicVolume = config%getFloat('atomicvolume') prm%Dsd0 = config%getFloat('selfdiffusionprefactor') !,'dsd0' prm%selfDiffusionEnergy = config%getFloat('selfdiffusionenergy') !,'qsd' prm%linetensionEffect = config%getFloat('linetension') prm%edgeJogFactor = config%getFloat('edgejog')!,'edgejogs' prm%doublekinkwidth = config%getFloat('doublekinkwidth') prm%solidSolutionEnergy = config%getFloat('solidsolutionenergy') prm%solidSolutionSize = config%getFloat('solidsolutionsize') prm%solidSolutionConcentration = config%getFloat('solidsolutionconcentration') prm%p = config%getFloat('p') prm%q = config%getFloat('q') prm%viscosity = config%getFloat('viscosity') prm%fattack = config%getFloat('attackfrequency') ! ToDo: discuss logic ini%rhoSglScatter = config%getFloat('rhosglscatter') ini%rhoSglRandom = config%getFloat('rhosglrandom',0.0_pReal) if (config%keyExists('/rhosglrandom/')) & ini%rhoSglRandomBinning = config%getFloat('rhosglrandombinning',0.0_pReal) !ToDo: useful default? ! if (rhoSglRandom(instance) < 0.0_pReal) & ! if (rhoSglRandomBinning(instance) <= 0.0_pReal) & prm%surfaceTransmissivity = config%getFloat('surfacetransmissivity',defaultVal=1.0_pReal) prm%grainboundaryTransmissivity = config%getFloat('grainboundarytransmissivity',defaultVal=-1.0_pReal) prm%fEdgeMultiplication = config%getFloat('edgemultiplication') prm%shortRangeStressCorrection = config%keyExists('/shortrangestresscorrection/') !-------------------------------------------------------------------------------------------------- ! sanity checks if (any(prm%burgers < 0.0_pReal)) extmsg = trim(extmsg)//' burgers' if (any(prm%lambda0 <= 0.0_pReal)) extmsg = trim(extmsg)//' lambda0' if (any(ini%rhoSglEdgePos0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglEdgePos0' if (any(ini%rhoSglEdgeNeg0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglEdgeNeg0' if (any(ini%rhoSglScrewPos0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglScrewPos0' if (any(ini%rhoSglScrewNeg0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoSglScrewNeg0' if (any(ini%rhoDipEdge0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoDipEdge0' if (any(ini%rhoDipScrew0 < 0.0_pReal)) extmsg = trim(extmsg)//' rhoDipScrew0' if (any(prm%peierlsstress < 0.0_pReal)) extmsg = trim(extmsg)//' peierlsstress' if (any(prm%minDipoleHeight < 0.0_pReal)) extmsg = trim(extmsg)//' minDipoleHeight' if (prm%viscosity <= 0.0_pReal) extmsg = trim(extmsg)//' viscosity' if (prm%selfDiffusionEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' selfDiffusionEnergy' if (prm%fattack <= 0.0_pReal) extmsg = trim(extmsg)//' fattack' if (prm%doublekinkwidth <= 0.0_pReal) extmsg = trim(extmsg)//' doublekinkwidth' if (prm%Dsd0 < 0.0_pReal) extmsg = trim(extmsg)//' Dsd0' if (prm%atomicVolume <= 0.0_pReal) extmsg = trim(extmsg)//' atomicVolume' ! ToDo: in disloUCLA, the atomic volume is given as a factor if (prm%significantN < 0.0_pReal) extmsg = trim(extmsg)//' significantN' if (prm%significantrho < 0.0_pReal) extmsg = trim(extmsg)//' significantrho' if (prm%atol_rho < 0.0_pReal) extmsg = trim(extmsg)//' atol_rho' if (prm%CFLfactor < 0.0_pReal) extmsg = trim(extmsg)//' CFLfactor' if (prm%p <= 0.0_pReal .or. prm%p > 1.0_pReal) extmsg = trim(extmsg)//' p' if (prm%q < 1.0_pReal .or. prm%q > 2.0_pReal) extmsg = trim(extmsg)//' q' if (prm%linetensionEffect < 0.0_pReal .or. prm%linetensionEffect > 1.0_pReal) & extmsg = trim(extmsg)//' linetensionEffect' if (prm%edgeJogFactor < 0.0_pReal .or. prm%edgeJogFactor > 1.0_pReal) & extmsg = trim(extmsg)//' edgeJogFactor' if (prm%solidSolutionEnergy <= 0.0_pReal) extmsg = trim(extmsg)//' solidSolutionEnergy' if (prm%solidSolutionSize <= 0.0_pReal) extmsg = trim(extmsg)//' solidSolutionSize' if (prm%solidSolutionConcentration <= 0.0_pReal) extmsg = trim(extmsg)//' solidSolutionConcentration' if (prm%grainboundaryTransmissivity > 1.0_pReal) extmsg = trim(extmsg)//' grainboundaryTransmissivity' if (prm%surfaceTransmissivity < 0.0_pReal .or. prm%surfaceTransmissivity > 1.0_pReal) & extmsg = trim(extmsg)//' surfaceTransmissivity' if (prm%fEdgeMultiplication < 0.0_pReal .or. prm%fEdgeMultiplication > 1.0_pReal) & extmsg = trim(extmsg)//' fEdgeMultiplication' endif slipActive !-------------------------------------------------------------------------------------------------- ! allocate state arrays NipcMyPhase = count(material_phaseAt==p) * discretization_nIP sizeDotState = size([ 'rhoSglEdgePosMobile ','rhoSglEdgeNegMobile ', & 'rhoSglScrewPosMobile ','rhoSglScrewNegMobile ', & 'rhoSglEdgePosImmobile ','rhoSglEdgeNegImmobile ', & 'rhoSglScrewPosImmobile','rhoSglScrewNegImmobile', & 'rhoDipEdge ','rhoDipScrew ', & 'gamma ' ]) * prm%sum_N_sl !< "basic" microstructural state variables that are independent from other state variables sizeDependentState = size([ 'rhoForest ']) * prm%sum_N_sl !< microstructural state variables that depend on other state variables sizeState = sizeDotState + sizeDependentState & + size([ 'velocityEdgePos ','velocityEdgeNeg ', & 'velocityScrewPos ','velocityScrewNeg ', & 'maxDipoleHeightEdge ','maxDipoleHeightScrew' ]) * prm%sum_N_sl !< other dependent state variables that are not updated by microstructure sizeDeltaState = sizeDotState call material_allocatePlasticState(p,NipcMyPhase,sizeState,sizeDotState,sizeDeltaState) plasticState(p)%nonlocal = .true. plasticState(p)%offsetDeltaState = 0 ! ToDo: state structure does not follow convention st0%rho => plasticState(p)%state0 (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) stt%rho => plasticState(p)%state (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) dot%rho => plasticState(p)%dotState (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) del%rho => plasticState(p)%deltaState (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:) plasticState(p)%atol(1:10*prm%sum_N_sl) = prm%atol_rho stt%rhoSgl => plasticState(p)%state (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) dot%rhoSgl => plasticState(p)%dotState (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) del%rhoSgl => plasticState(p)%deltaState (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) stt%rhoSglMobile => plasticState(p)%state (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) dot%rhoSglMobile => plasticState(p)%dotState (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) del%rhoSglMobile => plasticState(p)%deltaState (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) stt%rho_sgl_mob_edg_pos => plasticState(p)%state (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:) dot%rho_sgl_mob_edg_pos => plasticState(p)%dotState (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:) del%rho_sgl_mob_edg_pos => plasticState(p)%deltaState (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:) stt%rho_sgl_mob_edg_neg => plasticState(p)%state (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:) dot%rho_sgl_mob_edg_neg => plasticState(p)%dotState (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:) del%rho_sgl_mob_edg_neg => plasticState(p)%deltaState (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:) stt%rho_sgl_mob_scr_pos => plasticState(p)%state (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:) dot%rho_sgl_mob_scr_pos => plasticState(p)%dotState (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:) del%rho_sgl_mob_scr_pos => plasticState(p)%deltaState (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:) stt%rho_sgl_mob_scr_neg => plasticState(p)%state (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) dot%rho_sgl_mob_scr_neg => plasticState(p)%dotState (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) del%rho_sgl_mob_scr_neg => plasticState(p)%deltaState (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:) stt%rhoSglImmobile => plasticState(p)%state (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) dot%rhoSglImmobile => plasticState(p)%dotState (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) del%rhoSglImmobile => plasticState(p)%deltaState (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) stt%rho_sgl_imm_edg_pos => plasticState(p)%state (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:) dot%rho_sgl_imm_edg_pos => plasticState(p)%dotState (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:) del%rho_sgl_imm_edg_pos => plasticState(p)%deltaState (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:) stt%rho_sgl_imm_edg_neg => plasticState(p)%state (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:) dot%rho_sgl_imm_edg_neg => plasticState(p)%dotState (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:) del%rho_sgl_imm_edg_neg => plasticState(p)%deltaState (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:) stt%rho_sgl_imm_scr_pos => plasticState(p)%state (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:) dot%rho_sgl_imm_scr_pos => plasticState(p)%dotState (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:) del%rho_sgl_imm_scr_pos => plasticState(p)%deltaState (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:) stt%rho_sgl_imm_scr_neg => plasticState(p)%state (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) dot%rho_sgl_imm_scr_neg => plasticState(p)%dotState (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) del%rho_sgl_imm_scr_neg => plasticState(p)%deltaState (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:) stt%rhoDip => plasticState(p)%state (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:) dot%rhoDip => plasticState(p)%dotState (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:) del%rhoDip => plasticState(p)%deltaState (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:) stt%rho_dip_edg => plasticState(p)%state (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:) dot%rho_dip_edg => plasticState(p)%dotState (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:) del%rho_dip_edg => plasticState(p)%deltaState (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:) stt%rho_dip_scr => plasticState(p)%state (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:) dot%rho_dip_scr => plasticState(p)%dotState (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:) del%rho_dip_scr => plasticState(p)%deltaState (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:) stt%gamma => plasticState(p)%state (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) dot%gamma => plasticState(p)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) del%gamma => plasticState(p)%deltaState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) plasticState(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl ) = config%getFloat('atol_gamma', defaultVal = 1.0e-2_pReal) if(any(plasticState(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl) < 0.0_pReal)) & extmsg = trim(extmsg)//' atol_gamma' plasticState(p)%slipRate => plasticState(p)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:NipcMyPhase) stt%rho_forest => plasticState(p)%state (11*prm%sum_N_sl + 1:12*prm%sum_N_sl,1:NipcMyPhase) stt%v => plasticState(p)%state (12*prm%sum_N_sl + 1:16*prm%sum_N_sl,1:NipcMyPhase) stt%v_edg_pos => plasticState(p)%state (12*prm%sum_N_sl + 1:13*prm%sum_N_sl,1:NipcMyPhase) stt%v_edg_neg => plasticState(p)%state (13*prm%sum_N_sl + 1:14*prm%sum_N_sl,1:NipcMyPhase) stt%v_scr_pos => plasticState(p)%state (14*prm%sum_N_sl + 1:15*prm%sum_N_sl,1:NipcMyPhase) stt%v_scr_neg => plasticState(p)%state (15*prm%sum_N_sl + 1:16*prm%sum_N_sl,1:NipcMyPhase) allocate(dst%tau_pass(prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) allocate(dst%tau_back(prm%sum_N_sl,NipcMyPhase),source=0.0_pReal) end associate if (NipcMyPhase > 0) call stateInit(ini,p,NipcMyPhase) plasticState(p)%state0 = plasticState(p)%state !-------------------------------------------------------------------------------------------------- ! exit if any parameter is out of range if (extmsg /= '') call IO_error(211,ext_msg=trim(extmsg)//'('//PLASTICITY_NONLOCAL_LABEL//')') enddo allocate(compatibility(2,maxval(param%sum_N_sl),maxval(param%sum_N_sl),nIPneighbors,& discretization_nIP,discretization_nElem), source=0.0_pReal) ! BEGIN DEPRECATED---------------------------------------------------------------------------------- allocate(iRhoU(maxval(param%sum_N_sl),4,Ninstance), source=0) allocate(iV(maxval(param%sum_N_sl),4,Ninstance), source=0) allocate(iD(maxval(param%sum_N_sl),2,Ninstance), source=0) initializeInstances: do p = 1, size(phase_plasticity) NipcMyPhase = count(material_phaseAt==p) * discretization_nIP myPhase2: if (phase_plasticity(p) == PLASTICITY_NONLOCAL_ID) then l = 0 do t = 1,4 do s = 1,param(phase_plasticityInstance(p))%sum_N_sl l = l + 1 iRhoU(s,t,phase_plasticityInstance(p)) = l enddo enddo l = l + (4+2+1+1)*param(phase_plasticityInstance(p))%sum_N_sl ! immobile(4), dipole(2), shear, forest do t = 1,4 do s = 1,param(phase_plasticityInstance(p))%sum_N_sl l = l + 1 iV(s,t,phase_plasticityInstance(p)) = l enddo enddo do t = 1,2 do s = 1,param(phase_plasticityInstance(p))%sum_N_sl l = l + 1 iD(s,t,phase_plasticityInstance(p)) = l enddo enddo if (iD(param(phase_plasticityInstance(p))%sum_N_sl,2,phase_plasticityInstance(p)) /= plasticState(p)%sizeState) & call IO_error(0, ext_msg = 'state indices not properly set ('//PLASTICITY_NONLOCAL_LABEL//')') endif myPhase2 enddo initializeInstances end subroutine plastic_nonlocal_init !-------------------------------------------------------------------------------------------------- !> @brief calculates quantities characterizing the microstructure !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_dependentState(F, Fp, instance, of, ip, el) real(pReal), dimension(3,3), intent(in) :: & F, & Fp integer, intent(in) :: & instance, & of, & ip, & el integer :: & no, & !< neighbor offset neighbor_el, & ! element number of neighboring material point neighbor_ip, & ! integration point of neighboring material point neighbor_instance, & ! instance of this plasticity of neighboring material point c, & ! index of dilsocation character (edge, screw) s, & ! slip system index dir, & n real(pReal) :: & FVsize, & nRealNeighbors ! number of really existing neighbors integer, dimension(2) :: & neighbors real(pReal), dimension(2) :: & rhoExcessGradient, & rhoExcessGradient_over_rho, & rhoTotal real(pReal), dimension(3) :: & rhoExcessDifferences, & normal_latticeConf real(pReal), dimension(3,3) :: & invFe, & !< inverse of elastic deformation gradient invFp, & !< inverse of plastic deformation gradient connections, & invConnections real(pReal), dimension(3,nIPneighbors) :: & connection_latticeConf real(pReal), dimension(2,param(instance)%sum_N_sl) :: & rhoExcess real(pReal), dimension(param(instance)%sum_N_sl) :: & rho_edg_delta, & rho_scr_delta real(pReal), dimension(param(instance)%sum_N_sl,10) :: & rho, & rho0, & rho_neighbor0 real(pReal), dimension(param(instance)%sum_N_sl,param(instance)%sum_N_sl) :: & myInteractionMatrix ! corrected slip interaction matrix real(pReal), dimension(param(instance)%sum_N_sl,nIPneighbors) :: & rho_edg_delta_neighbor, & rho_scr_delta_neighbor real(pReal), dimension(2,maxval(param%sum_N_sl),nIPneighbors) :: & neighbor_rhoExcess, & ! excess density at neighboring material point neighbor_rhoTotal ! total density at neighboring material point real(pReal), dimension(3,param(instance)%sum_N_sl,2) :: & m ! direction of dislocation motion associate(prm => param(instance),dst => microstructure(instance), stt => state(instance)) rho = getRho(instance,of,ip,el) stt%rho_forest(:,of) = matmul(prm%forestProjection_Edge, sum(abs(rho(:,edg)),2)) & + matmul(prm%forestProjection_Screw,sum(abs(rho(:,scr)),2)) ! coefficients are corrected for the line tension effect ! (see Kubin,Devincre,Hoc; 2008; Modeling dislocation storage rates and mean free paths in face-centered cubic crystals) if (any(lattice_structure(material_phaseAt(1,el)) == [LATTICE_bcc_ID,LATTICE_fcc_ID])) then myInteractionMatrix = prm%interactionSlipSlip & * spread(( 1.0_pReal - prm%linetensionEffect & + prm%linetensionEffect & * log(0.35_pReal * prm%burgers * sqrt(max(stt%rho_forest(:,of),prm%significantRho))) & / log(0.35_pReal * prm%burgers * 1e6_pReal))** 2.0_pReal,2,prm%sum_N_sl) else myInteractionMatrix = prm%interactionSlipSlip endif dst%tau_pass(:,of) = prm%mu * prm%burgers & * sqrt(matmul(myInteractionMatrix,sum(abs(rho),2))) !*** calculate the dislocation stress of the neighboring excess dislocation densities !*** zero for material points of local plasticity !################################################################################################# ! ToDo: MD: this is most likely only correct for F_i = I !################################################################################################# rho0 = getRho0(instance,of,ip,el) if (.not. phase_localPlasticity(material_phaseAt(1,el)) .and. prm%shortRangeStressCorrection) then invFp = math_inv33(Fp) invFe = matmul(Fp,math_inv33(F)) rho_edg_delta = rho0(:,mob_edg_pos) - rho0(:,mob_edg_neg) rho_scr_delta = rho0(:,mob_scr_pos) - rho0(:,mob_scr_neg) rhoExcess(1,:) = rho_edg_delta rhoExcess(2,:) = rho_scr_delta FVsize = IPvolume(ip,el) ** (1.0_pReal/3.0_pReal) !* loop through my neighborhood and get the connection vectors (in lattice frame) and the excess densities nRealNeighbors = 0.0_pReal neighbor_rhoTotal = 0.0_pReal do n = 1,nIPneighbors neighbor_el = IPneighborhood(1,n,ip,el) neighbor_ip = IPneighborhood(2,n,ip,el) no = material_phasememberAt(1,neighbor_ip,neighbor_el) if (neighbor_el > 0 .and. neighbor_ip > 0) then neighbor_instance = phase_plasticityInstance(material_phaseAt(1,neighbor_el)) if (neighbor_instance == instance) then nRealNeighbors = nRealNeighbors + 1.0_pReal rho_neighbor0 = getRho0(instance,no,neighbor_ip,neighbor_el) rho_edg_delta_neighbor(:,n) = rho_neighbor0(:,mob_edg_pos) - rho_neighbor0(:,mob_edg_neg) rho_scr_delta_neighbor(:,n) = rho_neighbor0(:,mob_scr_pos) - rho_neighbor0(:,mob_scr_neg) neighbor_rhoTotal(1,:,n) = sum(abs(rho_neighbor0(:,edg)),2) neighbor_rhoTotal(2,:,n) = sum(abs(rho_neighbor0(:,scr)),2) connection_latticeConf(1:3,n) = matmul(invFe, discretization_IPcoords(1:3,neighbor_el+neighbor_ip-1) & - discretization_IPcoords(1:3,el+neighbor_ip-1)) normal_latticeConf = matmul(transpose(invFp), IPareaNormal(1:3,n,ip,el)) if (math_inner(normal_latticeConf,connection_latticeConf(1:3,n)) < 0.0_pReal) & ! neighboring connection points in opposite direction to face normal: must be periodic image connection_latticeConf(1:3,n) = normal_latticeConf * IPvolume(ip,el)/IParea(n,ip,el) ! instead take the surface normal scaled with the diameter of the cell else ! local neighbor or different lattice structure or different constitution instance -> use central values instead connection_latticeConf(1:3,n) = 0.0_pReal rho_edg_delta_neighbor(:,n) = rho_edg_delta rho_scr_delta_neighbor(:,n) = rho_scr_delta endif else ! free surface -> use central values instead connection_latticeConf(1:3,n) = 0.0_pReal rho_edg_delta_neighbor(:,n) = rho_edg_delta rho_scr_delta_neighbor(:,n) = rho_scr_delta endif enddo neighbor_rhoExcess(1,:,:) = rho_edg_delta_neighbor neighbor_rhoExcess(2,:,:) = rho_scr_delta_neighbor !* loop through the slip systems and calculate the dislocation gradient by !* 1. interpolation of the excess density in the neighorhood !* 2. interpolation of the dead dislocation density in the central volume m(1:3,:,1) = prm%slip_direction m(1:3,:,2) = -prm%slip_transverse do s = 1,prm%sum_N_sl ! gradient from interpolation of neighboring excess density ... do c = 1,2 do dir = 1,3 neighbors(1) = 2 * dir - 1 neighbors(2) = 2 * dir connections(dir,1:3) = connection_latticeConf(1:3,neighbors(1)) & - connection_latticeConf(1:3,neighbors(2)) rhoExcessDifferences(dir) = neighbor_rhoExcess(c,s,neighbors(1)) & - neighbor_rhoExcess(c,s,neighbors(2)) enddo invConnections = math_inv33(connections) if (all(dEq0(invConnections))) call IO_error(-1,ext_msg='back stress calculation: inversion error') rhoExcessGradient(c) = math_inner(m(1:3,s,c), matmul(invConnections,rhoExcessDifferences)) enddo ! ... plus gradient from deads ... rhoExcessGradient(1) = rhoExcessGradient(1) + sum(rho(s,imm_edg)) / FVsize rhoExcessGradient(2) = rhoExcessGradient(2) + sum(rho(s,imm_scr)) / FVsize ! ... normalized with the total density ... rhoTotal(1) = (sum(abs(rho(s,edg))) + sum(neighbor_rhoTotal(1,s,:))) / (1.0_pReal + nRealNeighbors) rhoTotal(2) = (sum(abs(rho(s,scr))) + sum(neighbor_rhoTotal(2,s,:))) / (1.0_pReal + nRealNeighbors) rhoExcessGradient_over_rho = 0.0_pReal where(rhoTotal > 0.0_pReal) rhoExcessGradient_over_rho = rhoExcessGradient / rhoTotal ! ... gives the local stress correction when multiplied with a factor dst%tau_back(s,of) = - prm%mu * prm%burgers(s) / (2.0_pReal * PI) & * ( rhoExcessGradient_over_rho(1) / (1.0_pReal - prm%nu) & + rhoExcessGradient_over_rho(2)) enddo endif # 721 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" end associate end subroutine plastic_nonlocal_dependentState !-------------------------------------------------------------------------------------------------- !> @brief calculates plastic velocity gradient and its tangent !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_LpAndItsTangent(Lp,dLp_dMp, & Mp,Temperature,instance,of,ip,el) real(pReal), dimension(3,3), intent(out) :: & Lp !< plastic velocity gradient real(pReal), dimension(3,3,3,3), intent(out) :: & dLp_dMp integer, intent(in) :: & instance, & of, & ip, & !< current integration point el !< current element number real(pReal), intent(in) :: & Temperature !< temperature real(pReal), dimension(3,3), intent(in) :: & Mp !< derivative of Lp with respect to Mp integer :: & ns, & !< short notation for the total number of active slip systems i, & j, & k, & l, & t, & !< dislocation type s !< index of my current slip system real(pReal), dimension(param(instance)%sum_N_sl,8) :: & rhoSgl !< single dislocation densities (including blocked) real(pReal), dimension(param(instance)%sum_N_sl,10) :: & rho real(pReal), dimension(param(instance)%sum_N_sl,4) :: & v, & !< velocity tauNS, & !< resolved shear stress including non Schmid and backstress terms dv_dtau, & !< velocity derivative with respect to the shear stress dv_dtauNS !< velocity derivative with respect to the shear stress real(pReal), dimension(param(instance)%sum_N_sl) :: & tau, & !< resolved shear stress including backstress terms gdotTotal !< shear rate associate(prm => param(instance),dst=>microstructure(instance),stt=>state(instance)) ns = prm%sum_N_sl !*** shortcut to state variables rho = getRho(instance,of,ip,el) rhoSgl = rho(:,sgl) do s = 1,ns tau(s) = math_tensordot(Mp, prm%Schmid(1:3,1:3,s)) tauNS(s,1) = tau(s) tauNS(s,2) = tau(s) if (tau(s) > 0.0_pReal) then tauNS(s,3) = math_tensordot(Mp, +prm%nonSchmid_pos(1:3,1:3,s)) tauNS(s,4) = math_tensordot(Mp, -prm%nonSchmid_neg(1:3,1:3,s)) else tauNS(s,3) = math_tensordot(Mp, +prm%nonSchmid_neg(1:3,1:3,s)) tauNS(s,4) = math_tensordot(Mp, -prm%nonSchmid_pos(1:3,1:3,s)) endif enddo tauNS = tauNS + spread(dst%tau_back(:,of),2,4) tau = tau + dst%tau_back(:,of) ! edges call kinetics(v(:,1), dv_dtau(:,1), dv_dtauNS(:,1), & tau, tauNS(:,1), dst%tau_pass(:,of),1,Temperature, instance) v(:,2) = v(:,1) dv_dtau(:,2) = dv_dtau(:,1) dv_dtauNS(:,2) = dv_dtauNS(:,1) !screws if (prm%nonSchmidActive) then v(:,3:4) = spread(v(:,1),2,2) dv_dtau(:,3:4) = spread(dv_dtau(:,1),2,2) dv_dtauNS(:,3:4) = spread(dv_dtauNS(:,1),2,2) else do t = 3,4 call kinetics(v(:,t), dv_dtau(:,t), dv_dtauNS(:,t), & tau, tauNS(:,t), dst%tau_pass(:,of),2,Temperature, instance) enddo endif stt%v(:,of) = pack(v,.true.) !*** Bauschinger effect forall (s = 1:ns, t = 5:8, rhoSgl(s,t) * v(s,t-4) < 0.0_pReal) & rhoSgl(s,t-4) = rhoSgl(s,t-4) + abs(rhoSgl(s,t)) gdotTotal = sum(rhoSgl(:,1:4) * v, 2) * prm%burgers Lp = 0.0_pReal dLp_dMp = 0.0_pReal do s = 1,ns Lp = Lp + gdotTotal(s) * prm%Schmid(1:3,1:3,s) forall (i=1:3,j=1:3,k=1:3,l=1:3) & dLp_dMp(i,j,k,l) = dLp_dMp(i,j,k,l) & + prm%Schmid(i,j,s) * prm%Schmid(k,l,s) & * sum(rhoSgl(s,1:4) * dv_dtau(s,1:4)) * prm%burgers(s) & + prm%Schmid(i,j,s) & * ( prm%nonSchmid_pos(k,l,s) * rhoSgl(s,3) * dv_dtauNS(s,3) & - prm%nonSchmid_neg(k,l,s) * rhoSgl(s,4) * dv_dtauNS(s,4)) * prm%burgers(s) enddo end associate end subroutine plastic_nonlocal_LpAndItsTangent !-------------------------------------------------------------------------------------------------- !> @brief (instantaneous) incremental change of microstructure !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_deltaState(Mp,instance,of,ip,el) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress integer, intent(in) :: & instance, & ! current instance of this plasticity of, & !< offset ip, & el integer :: & ph, & !< phase ns, & ! short notation for the total number of active slip systems c, & ! character of dislocation t, & ! type of dislocation s ! index of my current slip system real(pReal), dimension(param(instance)%sum_N_sl,10) :: & deltaRhoRemobilization, & ! density increment by remobilization deltaRhoDipole2SingleStress ! density increment by dipole dissociation (by stress change) real(pReal), dimension(param(instance)%sum_N_sl,10) :: & rho ! current dislocation densities real(pReal), dimension(param(instance)%sum_N_sl,4) :: & v ! dislocation glide velocity real(pReal), dimension(param(instance)%sum_N_sl) :: & tau ! current resolved shear stress real(pReal), dimension(param(instance)%sum_N_sl,2) :: & rhoDip, & ! current dipole dislocation densities (screw and edge dipoles) dUpper, & ! current maximum stable dipole distance for edges and screws dUpperOld, & ! old maximum stable dipole distance for edges and screws deltaDUpper ! change in maximum stable dipole distance for edges and screws ph = material_phaseAt(1,el) associate(prm => param(instance),dst => microstructure(instance),del => deltaState(instance)) ns = prm%sum_N_sl !*** shortcut to state variables forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,instance),of) forall (s = 1:ns, c = 1:2) dUpperOld(s,c) = plasticState(ph)%state(iD(s,c,instance),of) rho = getRho(instance,of,ip,el) rhoDip = rho(:,dip) !**************************************************************************** !*** dislocation remobilization (bauschinger effect) where(rho(:,imm) * v < 0.0_pReal) deltaRhoRemobilization(:,mob) = abs(rho(:,imm)) deltaRhoRemobilization(:,imm) = - rho(:,imm) rho(:,mob) = rho(:,mob) + abs(rho(:,imm)) rho(:,imm) = 0.0_pReal elsewhere deltaRhoRemobilization(:,mob) = 0.0_pReal deltaRhoRemobilization(:,imm) = 0.0_pReal endwhere deltaRhoRemobilization(:,dip) = 0.0_pReal !**************************************************************************** !*** calculate dipole formation and dissociation by stress change !*** calculate limits for stable dipole height do s = 1,prm%sum_N_sl tau(s) = math_tensordot(Mp, prm%Schmid(1:3,1:3,s)) +dst%tau_back(s,of) if (abs(tau(s)) < 1.0e-15_pReal) tau(s) = 1.0e-15_pReal enddo dUpper(:,1) = prm%mu * prm%burgers/(8.0_pReal * PI * (1.0_pReal - prm%nu) * abs(tau)) dUpper(:,2) = prm%mu * prm%burgers/(4.0_pReal * PI * abs(tau)) where(dNeq0(sqrt(sum(abs(rho(:,edg)),2)))) & dUpper(:,1) = min(1.0_pReal/sqrt(sum(abs(rho(:,edg)),2)),dUpper(:,1)) where(dNeq0(sqrt(sum(abs(rho(:,scr)),2)))) & dUpper(:,2) = min(1.0_pReal/sqrt(sum(abs(rho(:,scr)),2)),dUpper(:,2)) dUpper = max(dUpper,prm%minDipoleHeight) deltaDUpper = dUpper - dUpperOld !*** dissociation by stress increase deltaRhoDipole2SingleStress = 0.0_pReal forall (c=1:2, s=1:ns, deltaDUpper(s,c) < 0.0_pReal .and. & dNeq0(dUpperOld(s,c) - prm%minDipoleHeight(s,c))) & deltaRhoDipole2SingleStress(s,8+c) = rhoDip(s,c) * deltaDUpper(s,c) & / (dUpperOld(s,c) - prm%minDipoleHeight(s,c)) forall (t=1:4) deltaRhoDipole2SingleStress(:,t) = -0.5_pReal * deltaRhoDipole2SingleStress(:,(t-1)/2+9) forall (s = 1:ns, c = 1:2) plasticState(ph)%state(iD(s,c,instance),of) = dUpper(s,c) plasticState(ph)%deltaState(:,of) = 0.0_pReal del%rho(:,of) = reshape(deltaRhoRemobilization + deltaRhoDipole2SingleStress, [10*ns]) # 936 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" end associate end subroutine plastic_nonlocal_deltaState !--------------------------------------------------------------------------------------------------- !> @brief calculates the rate of change of microstructure !--------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_dotState(Mp, F, Fp, Temperature,timestep, & instance,of,ip,el) real(pReal), dimension(3,3), intent(in) :: & Mp !< MandelStress real(pReal), dimension(3,3,homogenization_maxNgrains,discretization_nIP,discretization_nElem), intent(in) :: & F, & !< elastic deformation gradient Fp !< plastic deformation gradient real(pReal), intent(in) :: & Temperature, & !< temperature timestep !< substepped crystallite time increment integer, intent(in) :: & instance, & of, & ip, & !< current integration point el !< current element number integer :: & ph, & neighbor_instance, & !< instance of my neighbor's plasticity ns, & !< short notation for the total number of active slip systems c, & !< character of dislocation n, & !< index of my current neighbor neighbor_el, & !< element number of my neighbor neighbor_ip, & !< integration point of my neighbor neighbor_n, & !< neighbor index pointing to me when looking from my neighbor opposite_neighbor, & !< index of my opposite neighbor opposite_ip, & !< ip of my opposite neighbor opposite_el, & !< element index of my opposite neighbor opposite_n, & !< neighbor index pointing to me when looking from my opposite neighbor t, & !< type of dislocation no,& !< neighbor offset shortcut np,& !< neighbor phase shortcut topp, & !< type of dislocation with opposite sign to t s !< index of my current slip system real(pReal), dimension(param(instance)%sum_N_sl,10) :: & rho, & rho0, & !< dislocation density at beginning of time step rhoDot, & !< density evolution rhoDotMultiplication, & !< density evolution by multiplication rhoDotFlux, & !< density evolution by flux rhoDotSingle2DipoleGlide, & !< density evolution by dipole formation (by glide) rhoDotAthermalAnnihilation, & !< density evolution by athermal annihilation rhoDotThermalAnnihilation !< density evolution by thermal annihilation real(pReal), dimension(param(instance)%sum_N_sl,8) :: & rhoSgl, & !< current single dislocation densities (positive/negative screw and edge without dipoles) neighbor_rhoSgl0, & !< current single dislocation densities of neighboring ip (positive/negative screw and edge without dipoles) my_rhoSgl0 !< single dislocation densities of central ip (positive/negative screw and edge without dipoles) real(pReal), dimension(param(instance)%sum_N_sl,4) :: & v, & !< current dislocation glide velocity v0, & neighbor_v0, & !< dislocation glide velocity of enighboring ip gdot !< shear rates real(pReal), dimension(param(instance)%sum_N_sl) :: & tau, & !< current resolved shear stress vClimb !< climb velocity of edge dipoles real(pReal), dimension(param(instance)%sum_N_sl,2) :: & rhoDip, & !< current dipole dislocation densities (screw and edge dipoles) dLower, & !< minimum stable dipole distance for edges and screws dUpper !< current maximum stable dipole distance for edges and screws real(pReal), dimension(3,param(instance)%sum_N_sl,4) :: & m !< direction of dislocation motion real(pReal), dimension(3,3) :: & my_F, & !< my total deformation gradient neighbor_F, & !< total deformation gradient of my neighbor my_Fe, & !< my elastic deformation gradient neighbor_Fe, & !< elastic deformation gradient of my neighbor Favg !< average total deformation gradient of me and my neighbor real(pReal), dimension(3) :: & normal_neighbor2me, & !< interface normal pointing from my neighbor to me in neighbor's lattice configuration normal_neighbor2me_defConf, & !< interface normal pointing from my neighbor to me in shared deformed configuration normal_me2neighbor, & !< interface normal pointing from me to my neighbor in my lattice configuration normal_me2neighbor_defConf !< interface normal pointing from me to my neighbor in shared deformed configuration real(pReal) :: & area, & !< area of the current interface transmissivity, & !< overall transmissivity of dislocation flux to neighboring material point lineLength, & !< dislocation line length leaving the current interface selfDiffusion !< self diffusion ph = material_phaseAt(1,el) if (timestep <= 0.0_pReal) then plasticState(ph)%dotState = 0.0_pReal return endif associate(prm => param(instance), & dst => microstructure(instance), & dot => dotState(instance), & stt => state(instance)) ns = prm%sum_N_sl tau = 0.0_pReal gdot = 0.0_pReal rho = getRho(instance,of,ip,el) rhoSgl = rho(:,sgl) rhoDip = rho(:,dip) rho0 = getRho0(instance,of,ip,el) my_rhoSgl0 = rho0(:,sgl) forall (s = 1:ns, t = 1:4) v(s,t) = plasticState(ph)%state(iV(s,t,instance),of) gdot = rhoSgl(:,1:4) * v * spread(prm%burgers,2,4) # 1056 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" !**************************************************************************** !*** limits for stable dipole height do s = 1,ns tau(s) = math_tensordot(Mp, prm%Schmid(1:3,1:3,s)) + dst%tau_back(s,of) if (abs(tau(s)) < 1.0e-15_pReal) tau(s) = 1.0e-15_pReal enddo dLower = prm%minDipoleHeight dUpper(:,1) = prm%mu * prm%burgers/(8.0_pReal * PI * (1.0_pReal - prm%nu) * abs(tau)) dUpper(:,2) = prm%mu * prm%burgers/(4.0_pReal * PI * abs(tau)) where(dNeq0(sqrt(sum(abs(rho(:,edg)),2)))) & dUpper(:,1) = min(1.0_pReal/sqrt(sum(abs(rho(:,edg)),2)),dUpper(:,1)) where(dNeq0(sqrt(sum(abs(rho(:,scr)),2)))) & dUpper(:,2) = min(1.0_pReal/sqrt(sum(abs(rho(:,scr)),2)),dUpper(:,2)) dUpper = max(dUpper,dLower) !**************************************************************************** !*** dislocation multiplication rhoDotMultiplication = 0.0_pReal isBCC: if (lattice_structure(ph) == LATTICE_bcc_ID) then forall (s = 1:ns, sum(abs(v(s,1:4))) > 0.0_pReal) rhoDotMultiplication(s,1:2) = sum(abs(gdot(s,3:4))) / prm%burgers(s) & ! assuming double-cross-slip of screws to be decisive for multiplication * sqrt(stt%rho_forest(s,of)) / prm%lambda0(s) ! & ! mean free path ! * 2.0_pReal * sum(abs(v(s,3:4))) / sum(abs(v(s,1:4))) ! ratio of screw to overall velocity determines edge generation rhoDotMultiplication(s,3:4) = sum(abs(gdot(s,3:4))) /prm%burgers(s) & ! assuming double-cross-slip of screws to be decisive for multiplication * sqrt(stt%rho_forest(s,of)) / prm%lambda0(s) ! & ! mean free path ! * 2.0_pReal * sum(abs(v(s,1:2))) / sum(abs(v(s,1:4))) ! ratio of edge to overall velocity determines screw generation endforall else isBCC rhoDotMultiplication(:,1:4) = spread( & (sum(abs(gdot(:,1:2)),2) * prm%fEdgeMultiplication + sum(abs(gdot(:,3:4)),2)) & * sqrt(stt%rho_forest(:,of)) / prm%lambda0 / prm%burgers, 2, 4) endif isBCC forall (s = 1:ns, t = 1:4) v0(s,t) = plasticState(ph)%state0(iV(s,t,instance),of) !**************************************************************************** !*** calculate dislocation fluxes (only for nonlocal plasticity) rhoDotFlux = 0.0_pReal if (.not. phase_localPlasticity(material_phaseAt(1,el))) then !*** check CFL (Courant-Friedrichs-Lewy) condition for flux if (any( abs(gdot) > 0.0_pReal & ! any active slip system ... .and. prm%CFLfactor * abs(v0) * timestep & > IPvolume(ip,el) / maxval(IParea(:,ip,el)))) then ! ...with velocity above critical value (we use the reference volume and area for simplicity here) # 1116 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" plasticState(ph)%dotState = IEEE_value(1.0_pReal,IEEE_quiet_NaN) ! -> return NaN and, hence, enforce cutback return endif !*** be aware of the definition of slip_transverse = slip_direction x slip_normal !!! !*** opposite sign to our t vector in the (s,t,n) triplet !!! m(1:3,:,1) = prm%slip_direction m(1:3,:,2) = -prm%slip_direction m(1:3,:,3) = -prm%slip_transverse m(1:3,:,4) = prm%slip_transverse my_F = F(1:3,1:3,1,ip,el) my_Fe = matmul(my_F, math_inv33(Fp(1:3,1:3,1,ip,el))) neighbors: do n = 1,nIPneighbors neighbor_el = IPneighborhood(1,n,ip,el) neighbor_ip = IPneighborhood(2,n,ip,el) neighbor_n = IPneighborhood(3,n,ip,el) np = material_phaseAt(1,neighbor_el) no = material_phasememberAt(1,neighbor_ip,neighbor_el) opposite_neighbor = n + mod(n,2) - mod(n+1,2) opposite_el = IPneighborhood(1,opposite_neighbor,ip,el) opposite_ip = IPneighborhood(2,opposite_neighbor,ip,el) opposite_n = IPneighborhood(3,opposite_neighbor,ip,el) if (neighbor_n > 0) then ! if neighbor exists, average deformation gradient neighbor_instance = phase_plasticityInstance(material_phaseAt(1,neighbor_el)) neighbor_F = F(1:3,1:3,1,neighbor_ip,neighbor_el) neighbor_Fe = matmul(neighbor_F, math_inv33(Fp(1:3,1:3,1,neighbor_ip,neighbor_el))) Favg = 0.5_pReal * (my_F + neighbor_F) else ! if no neighbor, take my value as average Favg = my_F endif neighbor_v0 = 0.0_pReal ! needed for check of sign change in flux density below !* FLUX FROM MY NEIGHBOR TO ME !* This is only considered, if I have a neighbor of nonlocal plasticity !* (also nonlocal constitutive law with local properties) that is at least a little bit !* compatible. !* If it's not at all compatible, no flux is arriving, because everything is dammed in front of !* my neighbor's interface. !* The entering flux from my neighbor will be distributed on my slip systems according to the !* compatibility if (neighbor_n > 0) then if (phase_plasticity(material_phaseAt(1,neighbor_el)) == PLASTICITY_NONLOCAL_ID .and. & any(compatibility(:,:,:,n,ip,el) > 0.0_pReal)) then forall (s = 1:ns, t = 1:4) neighbor_v0(s,t) = plasticState(np)%state0(iV (s,t,neighbor_instance),no) neighbor_rhoSgl0(s,t) = max(plasticState(np)%state0(iRhoU(s,t,neighbor_instance),no),0.0_pReal) endforall where (neighbor_rhoSgl0 * IPvolume(neighbor_ip,neighbor_el) ** 0.667_pReal < prm%significantN & .or. neighbor_rhoSgl0 < prm%significantRho) & neighbor_rhoSgl0 = 0.0_pReal normal_neighbor2me_defConf = math_det33(Favg) * matmul(math_inv33(transpose(Favg)), & IPareaNormal(1:3,neighbor_n,neighbor_ip,neighbor_el)) ! normal of the interface in (average) deformed configuration (pointing neighbor => me) normal_neighbor2me = matmul(transpose(neighbor_Fe), normal_neighbor2me_defConf) & / math_det33(neighbor_Fe) ! interface normal in the lattice configuration of my neighbor area = IParea(neighbor_n,neighbor_ip,neighbor_el) * norm2(normal_neighbor2me) normal_neighbor2me = normal_neighbor2me / norm2(normal_neighbor2me) ! normalize the surface normal to unit length do s = 1,ns do t = 1,4 c = (t + 1) / 2 topp = t + mod(t,2) - mod(t+1,2) if (neighbor_v0(s,t) * math_inner(m(1:3,s,t), normal_neighbor2me) > 0.0_pReal & ! flux from my neighbor to me == entering flux for me .and. v0(s,t) * neighbor_v0(s,t) >= 0.0_pReal ) then ! ... only if no sign change in flux density lineLength = neighbor_rhoSgl0(s,t) * neighbor_v0(s,t) & * math_inner(m(1:3,s,t), normal_neighbor2me) * area ! positive line length that wants to enter through this interface where (compatibility(c,:,s,n,ip,el) > 0.0_pReal) & rhoDotFlux(:,t) = rhoDotFlux(1:ns,t) & + lineLength/IPvolume(ip,el)*compatibility(c,:,s,n,ip,el)**2.0_pReal ! transferring to equally signed mobile dislocation type where (compatibility(c,:,s,n,ip,el) < 0.0_pReal) & rhoDotFlux(:,topp) = rhoDotFlux(:,topp) & + lineLength/IPvolume(ip,el)*compatibility(c,:,s,n,ip,el)**2.0_pReal ! transferring to opposite signed mobile dislocation type endif enddo enddo endif; endif !* FLUX FROM ME TO MY NEIGHBOR !* This is not considered, if my opposite neighbor has a different constitutive law than nonlocal (still considered for nonlocal law with local properties). !* Then, we assume, that the opposite(!) neighbor sends an equal amount of dislocations to me. !* So the net flux in the direction of my neighbor is equal to zero: !* leaving flux to neighbor == entering flux from opposite neighbor !* In case of reduced transmissivity, part of the leaving flux is stored as dead dislocation density. !* That means for an interface of zero transmissivity the leaving flux is fully converted to dead dislocations. if (opposite_n > 0) then if (phase_plasticity(material_phaseAt(1,opposite_el)) == PLASTICITY_NONLOCAL_ID) then normal_me2neighbor_defConf = math_det33(Favg) & * matmul(math_inv33(transpose(Favg)),IPareaNormal(1:3,n,ip,el)) ! normal of the interface in (average) deformed configuration (pointing me => neighbor) normal_me2neighbor = matmul(transpose(my_Fe), normal_me2neighbor_defConf) & / math_det33(my_Fe) ! interface normal in my lattice configuration area = IParea(n,ip,el) * norm2(normal_me2neighbor) normal_me2neighbor = normal_me2neighbor / norm2(normal_me2neighbor) ! normalize the surface normal to unit length do s = 1,ns do t = 1,4 c = (t + 1) / 2 if (v0(s,t) * math_inner(m(1:3,s,t), normal_me2neighbor) > 0.0_pReal ) then ! flux from me to my neighbor == leaving flux for me (might also be a pure flux from my mobile density to dead density if interface not at all transmissive) if (v0(s,t) * neighbor_v0(s,t) >= 0.0_pReal) then ! no sign change in flux density transmissivity = sum(compatibility(c,:,s,n,ip,el)**2.0_pReal) ! overall transmissivity from this slip system to my neighbor else ! sign change in flux density means sign change in stress which does not allow for dislocations to arive at the neighbor transmissivity = 0.0_pReal endif lineLength = my_rhoSgl0(s,t) * v0(s,t) & * math_inner(m(1:3,s,t), normal_me2neighbor) * area ! positive line length of mobiles that wants to leave through this interface rhoDotFlux(s,t) = rhoDotFlux(s,t) - lineLength / IPvolume(ip,el) ! subtract dislocation flux from current type rhoDotFlux(s,t+4) = rhoDotFlux(s,t+4) & + lineLength / IPvolume(ip,el) * (1.0_pReal - transmissivity) & * sign(1.0_pReal, v0(s,t)) ! dislocation flux that is not able to leave through interface (because of low transmissivity) will remain as immobile single density at the material point endif enddo enddo endif; endif enddo neighbors endif !**************************************************************************** !*** calculate dipole formation and annihilation !*** formation by glide do c = 1,2 rhoDotSingle2DipoleGlide(:,2*c-1) = -2.0_pReal * dUpper(:,c) / prm%burgers & * ( rhoSgl(:,2*c-1) * abs(gdot(:,2*c)) & ! negative mobile --> positive mobile + rhoSgl(:,2*c) * abs(gdot(:,2*c-1)) & ! positive mobile --> negative mobile + abs(rhoSgl(:,2*c+4)) * abs(gdot(:,2*c-1))) ! positive mobile --> negative immobile rhoDotSingle2DipoleGlide(:,2*c) = -2.0_pReal * dUpper(:,c) / prm%burgers & * ( rhoSgl(:,2*c-1) * abs(gdot(:,2*c)) & ! negative mobile --> positive mobile + rhoSgl(:,2*c) * abs(gdot(:,2*c-1)) & ! positive mobile --> negative mobile + abs(rhoSgl(:,2*c+3)) * abs(gdot(:,2*c))) ! negative mobile --> positive immobile rhoDotSingle2DipoleGlide(:,2*c+3) = -2.0_pReal * dUpper(:,c) / prm%burgers & * rhoSgl(:,2*c+3) * abs(gdot(:,2*c)) ! negative mobile --> positive immobile rhoDotSingle2DipoleGlide(:,2*c+4) = -2.0_pReal * dUpper(:,c) / prm%burgers & * rhoSgl(:,2*c+4) * abs(gdot(:,2*c-1)) ! positive mobile --> negative immobile rhoDotSingle2DipoleGlide(:,c+8) = abs(rhoDotSingle2DipoleGlide(:,2*c+3)) & + abs(rhoDotSingle2DipoleGlide(:,2*c+4)) & - rhoDotSingle2DipoleGlide(:,2*c-1) & - rhoDotSingle2DipoleGlide(:,2*c) enddo !*** athermal annihilation rhoDotAthermalAnnihilation = 0.0_pReal forall (c=1:2) & rhoDotAthermalAnnihilation(:,c+8) = -2.0_pReal * dLower(:,c) / prm%burgers & * ( 2.0_pReal * (rhoSgl(:,2*c-1) * abs(gdot(:,2*c)) + rhoSgl(:,2*c) * abs(gdot(:,2*c-1))) & ! was single hitting single + 2.0_pReal * (abs(rhoSgl(:,2*c+3)) * abs(gdot(:,2*c)) + abs(rhoSgl(:,2*c+4)) * abs(gdot(:,2*c-1))) & ! was single hitting immobile single or was immobile single hit by single + rhoDip(:,c) * (abs(gdot(:,2*c-1)) + abs(gdot(:,2*c)))) ! single knocks dipole constituent ! annihilated screw dipoles leave edge jogs behind on the colinear system if (lattice_structure(ph) == LATTICE_fcc_ID) & forall (s = 1:ns, prm%colinearSystem(s) > 0) & rhoDotAthermalAnnihilation(prm%colinearSystem(s),1:2) = - rhoDotAthermalAnnihilation(s,10) & * 0.25_pReal * sqrt(stt%rho_forest(s,of)) * (dUpper(s,2) + dLower(s,2)) * prm%edgeJogFactor !*** thermally activated annihilation of edge dipoles by climb rhoDotThermalAnnihilation = 0.0_pReal selfDiffusion = prm%Dsd0 * exp(-prm%selfDiffusionEnergy / (kB * Temperature)) vClimb = prm%atomicVolume * selfDiffusion * prm%mu & / ( kB * Temperature * PI * (1.0_pReal-prm%nu) * (dUpper(:,1) + dLower(:,1))) forall (s = 1:ns, dUpper(s,1) > dLower(s,1)) & rhoDotThermalAnnihilation(s,9) = max(- 4.0_pReal * rhoDip(s,1) * vClimb(s) / (dUpper(s,1) - dLower(s,1)), & - rhoDip(s,1) / timestep - rhoDotAthermalAnnihilation(s,9) & - rhoDotSingle2DipoleGlide(s,9)) ! make sure that we do not annihilate more dipoles than we have rhoDot = rhoDotFlux & + rhoDotMultiplication & + rhoDotSingle2DipoleGlide & + rhoDotAthermalAnnihilation & + rhoDotThermalAnnihilation # 1325 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" if ( any(rho(:,mob) + rhoDot(:,1:4) * timestep < -prm%atol_rho) & .or. any(rho(:,dip) + rhoDot(:,9:10) * timestep < -prm%atol_rho)) then plasticState(ph)%dotState = IEEE_value(1.0_pReal,IEEE_quiet_NaN) else dot%rho(:,of) = pack(rhoDot,.true.) dot%gamma(:,of) = sum(gdot,2) endif end associate end subroutine plastic_nonlocal_dotState !-------------------------------------------------------------------------------------------------- !> @brief Compatibility update !> @detail Compatibility is defined as normalized product of signed cosine of the angle between the slip ! plane normals and signed cosine of the angle between the slip directions. Only the largest values ! that sum up to a total of 1 are considered, all others are set to zero. !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_updateCompatibility(orientation,instance,i,e) type(rotation), dimension(1,discretization_nIP,discretization_nElem), intent(in) :: & orientation ! crystal orientation integer, intent(in) :: & instance, & i, & e integer :: & n, & ! neighbor index neighbor_e, & ! element index of my neighbor neighbor_i, & ! integration point index of my neighbor ph, & neighbor_phase, & ns, & ! number of active slip systems s1, & ! slip system index (me) s2 ! slip system index (my neighbor) real(pReal), dimension(2,param(instance)%sum_N_sl,param(instance)%sum_N_sl,nIPneighbors) :: & my_compatibility ! my_compatibility for current element and ip real(pReal) :: & my_compatibilitySum, & thresholdValue, & nThresholdValues logical, dimension(param(instance)%sum_N_sl) :: & belowThreshold type(rotation) :: mis ph = material_phaseAt(1,e) associate(prm => param(instance)) ns = prm%sum_N_sl !*** start out fully compatible my_compatibility = 0.0_pReal forall(s1 = 1:ns) my_compatibility(:,s1,s1,:) = 1.0_pReal neighbors: do n = 1,nIPneighbors neighbor_e = IPneighborhood(1,n,i,e) neighbor_i = IPneighborhood(2,n,i,e) neighbor_phase = material_phaseAt(1,neighbor_e) if (neighbor_e <= 0 .or. neighbor_i <= 0) then !* FREE SURFACE !* Set surface transmissivity to the value specified in the material.config forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%surfaceTransmissivity) elseif (neighbor_phase /= ph) then !* PHASE BOUNDARY !* If we encounter a different nonlocal phase at the neighbor, !* we consider this to be a real "physical" phase boundary, so completely incompatible. !* If one of the two phases has a local plasticity law, !* we do not consider this to be a phase boundary, so completely compatible. if (.not. phase_localPlasticity(neighbor_phase) .and. .not. phase_localPlasticity(ph)) & forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = 0.0_pReal elseif (prm%grainboundaryTransmissivity >= 0.0_pReal) then !* GRAIN BOUNDARY ! !* fixed transmissivity for adjacent ips with different texture (only if explicitly given in material.config) if (material_texture(1,i,e) /= material_texture(1,neighbor_i,neighbor_e) .and. & (.not. phase_localPlasticity(neighbor_phase))) & forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%grainboundaryTransmissivity) else !* GRAIN BOUNDARY ? !* Compatibility defined by relative orientation of slip systems: !* The my_compatibility value is defined as the product of the slip normal projection and the slip direction projection. !* Its sign is always positive for screws, for edges it has the same sign as the slip normal projection. !* Since the sum for each slip system can easily exceed one (which would result in a transmissivity larger than one), !* only values above or equal to a certain threshold value are considered. This threshold value is chosen, such that !* the number of compatible slip systems is minimized with the sum of the original compatibility values exceeding one. !* Finally the smallest compatibility value is decreased until the sum is exactly equal to one. !* All values below the threshold are set to zero. mis = orientation(1,i,e)%misorientation(orientation(1,neighbor_i,neighbor_e)) mySlipSystems: do s1 = 1,ns neighborSlipSystems: do s2 = 1,ns my_compatibility(1,s2,s1,n) = math_inner(prm%slip_normal(1:3,s1), & mis%rotate(prm%slip_normal(1:3,s2))) & * abs(math_inner(prm%slip_direction(1:3,s1), & mis%rotate(prm%slip_direction(1:3,s2)))) my_compatibility(2,s2,s1,n) = abs(math_inner(prm%slip_normal(1:3,s1), & mis%rotate(prm%slip_normal(1:3,s2)))) & * abs(math_inner(prm%slip_direction(1:3,s1), & mis%rotate(prm%slip_direction(1:3,s2)))) enddo neighborSlipSystems my_compatibilitySum = 0.0_pReal belowThreshold = .true. do while (my_compatibilitySum < 1.0_pReal .and. any(belowThreshold)) thresholdValue = maxval(my_compatibility(2,:,s1,n), belowThreshold) ! screws always positive nThresholdValues = real(count(my_compatibility(2,:,s1,n) >= thresholdValue),pReal) where (my_compatibility(2,:,s1,n) >= thresholdValue) belowThreshold = .false. if (my_compatibilitySum + thresholdValue * nThresholdValues > 1.0_pReal) & where (abs(my_compatibility(:,:,s1,n)) >= thresholdValue) & my_compatibility(:,:,s1,n) = sign((1.0_pReal - my_compatibilitySum)/nThresholdValues,& my_compatibility(:,:,s1,n)) my_compatibilitySum = my_compatibilitySum + nThresholdValues * thresholdValue enddo where(belowThreshold) my_compatibility(1,:,s1,n) = 0.0_pReal where(belowThreshold) my_compatibility(2,:,s1,n) = 0.0_pReal enddo mySlipSystems endif enddo neighbors compatibility(:,:,:,:,i,e) = my_compatibility end associate end subroutine plastic_nonlocal_updateCompatibility !-------------------------------------------------------------------------------------------------- !> @brief writes results to HDF5 output file !-------------------------------------------------------------------------------------------------- module subroutine plastic_nonlocal_results(instance,group) integer, intent(in) :: instance character(len=*),intent(in) :: group integer :: o associate(prm => param(instance),dst => microstructure(instance),stt=>state(instance)) outputsLoop: do o = 1,size(prm%output) select case(trim(prm%output(o))) case('rho_sgl_mob_edg_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_edg_pos, 'rho_sgl_mob_edg_pos', & 'positive mobile edge density','1/m²') case('rho_sgl_imm_edg_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_edg_pos, 'rho_sgl_imm_edg_pos',& 'positive immobile edge density','1/m²') case('rho_sgl_mob_edg_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_edg_neg, 'rho_sgl_mob_edg_neg',& 'negative mobile edge density','1/m²') case('rho_sgl_imm_edg_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_edg_neg, 'rho_sgl_imm_edg_neg',& 'negative immobile edge density','1/m²') case('rho_dip_edg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip_edg, 'rho_dip_edg',& 'edge dipole density','1/m²') case('rho_sgl_mob_scr_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_scr_pos, 'rho_sgl_mob_scr_pos',& 'positive mobile screw density','1/m²') case('rho_sgl_imm_scr_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_scr_pos, 'rho_sgl_imm_scr_pos',& 'positive immobile screw density','1/m²') case('rho_sgl_mob_scr_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_mob_scr_neg, 'rho_sgl_mob_scr_neg',& 'negative mobile screw density','1/m²') case('rho_sgl_imm_scr_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_sgl_imm_scr_neg, 'rho_sgl_imm_scr_neg',& 'negative immobile screw density','1/m²') case('rho_dip_scr') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_dip_scr, 'rho_dip_scr',& 'screw dipole density','1/m²') case('rho_forest') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%rho_forest, 'rho_forest',& 'forest density','1/m²') case('v_edg_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_edg_pos, 'v_edg_pos',& 'positive edge velocity','m/s') case('v_edg_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_edg_neg, 'v_edg_neg',& 'negative edge velocity','m/s') case('v_scr_pos') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_scr_pos, 'v_scr_pos',& 'positive srew velocity','m/s') case('v_scr_neg') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%v_scr_neg, 'v_scr_neg',& 'negative screw velocity','m/s') case('gamma') if(prm%sum_N_sl>0) call results_writeDataset(group,stt%gamma,'gamma',& 'plastic shear','1') case('tau_pass') if(prm%sum_N_sl>0) call results_writeDataset(group,dst%tau_pass,'tau_pass',& 'passing stress for slip','Pa') end select enddo outputsLoop end associate end subroutine plastic_nonlocal_results !-------------------------------------------------------------------------------------------------- !> @brief populates the initial dislocation density !-------------------------------------------------------------------------------------------------- subroutine stateInit(ini,phase,NipcMyPhase) type(tInitialParameters) :: & ini integer,intent(in) :: & phase, & NipcMyPhase integer :: & e, & i, & f, & from, & upto, & s, & instance, & phasemember real(pReal), dimension(2) :: & noise, & rnd real(pReal) :: & meanDensity, & totalVolume, & densityBinning, & minimumIpVolume real(pReal), dimension(NipcMyPhase) :: & volume instance = phase_plasticityInstance(phase) associate(stt => state(instance)) if (ini%rhoSglRandom > 0.0_pReal) then ! randomly distribute dislocation segments on random slip system and of random type in the volume do e = 1,discretization_nElem do i = 1,discretization_nIP if (material_phaseAt(1,e) == phase) volume(material_phasememberAt(1,i,e)) = IPvolume(i,e) enddo enddo totalVolume = sum(volume) minimumIPVolume = minval(volume) densityBinning = ini%rhoSglRandomBinning / minimumIpVolume ** (2.0_pReal / 3.0_pReal) ! fill random material points with dislocation segments until the desired overall density is reached meanDensity = 0.0_pReal do while(meanDensity < ini%rhoSglRandom) call random_number(rnd) phasemember = nint(rnd(1)*real(NipcMyPhase,pReal) + 0.5_pReal) s = nint(rnd(2)*real(sum(ini%N_sl),pReal)*4.0_pReal + 0.5_pReal) meanDensity = meanDensity + densityBinning * volume(phasemember) / totalVolume stt%rhoSglMobile(s,phasemember) = densityBinning enddo else ! homogeneous distribution with noise do e = 1, NipcMyPhase do f = 1,size(ini%N_sl,1) from = 1 + sum(ini%N_sl(1:f-1)) upto = sum(ini%N_sl(1:f)) do s = from,upto noise = [math_sampleGaussVar(0.0_pReal, ini%rhoSglScatter), & math_sampleGaussVar(0.0_pReal, ini%rhoSglScatter)] stt%rho_sgl_mob_edg_pos(s,e) = ini%rhoSglEdgePos0(f) + noise(1) stt%rho_sgl_mob_edg_neg(s,e) = ini%rhoSglEdgeNeg0(f) + noise(1) stt%rho_sgl_mob_scr_pos(s,e) = ini%rhoSglScrewPos0(f) + noise(2) stt%rho_sgl_mob_scr_neg(s,e) = ini%rhoSglScrewNeg0(f) + noise(2) enddo stt%rho_dip_edg(from:upto,e) = ini%rhoDipEdge0(f) stt%rho_dip_scr(from:upto,e) = ini%rhoDipScrew0(f) enddo enddo endif end associate end subroutine stateInit !-------------------------------------------------------------------------------------------------- !> @brief calculates kinetics !-------------------------------------------------------------------------------------------------- subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Temperature, instance) integer, intent(in) :: & c, & !< dislocation character (1:edge, 2:screw) instance real(pReal), intent(in) :: & Temperature !< temperature real(pReal), dimension(param(instance)%sum_N_sl), intent(in) :: & tau, & !< resolved external shear stress (without non Schmid effects) tauNS, & !< resolved external shear stress (including non Schmid effects) tauThreshold !< threshold shear stress real(pReal), dimension(param(instance)%sum_N_sl), intent(out) :: & v, & !< velocity dv_dtau, & !< velocity derivative with respect to resolved shear stress (without non Schmid contributions) dv_dtauNS !< velocity derivative with respect to resolved shear stress (including non Schmid contributions) integer :: & ns, & !< short notation for the total number of active slip systems s !< index of my current slip system real(pReal) :: & tauRel_P, & tauRel_S, & tauEff, & !< effective shear stress tPeierls, & !< waiting time in front of a peierls barriers tSolidSolution, & !< waiting time in front of a solid solution obstacle vViscous, & !< viscous glide velocity dtPeierls_dtau, & !< derivative with respect to resolved shear stress dtSolidSolution_dtau, & !< derivative with respect to resolved shear stress meanfreepath_S, & !< mean free travel distance for dislocations between two solid solution obstacles meanfreepath_P, & !< mean free travel distance for dislocations between two Peierls barriers jumpWidth_P, & !< depth of activated area jumpWidth_S, & !< depth of activated area activationLength_P, & !< length of activated dislocation line activationLength_S, & !< length of activated dislocation line activationVolume_P, & !< volume that needs to be activated to overcome barrier activationVolume_S, & !< volume that needs to be activated to overcome barrier activationEnergy_P, & !< energy that is needed to overcome barrier activationEnergy_S, & !< energy that is needed to overcome barrier criticalStress_P, & !< maximum obstacle strength criticalStress_S, & !< maximum obstacle strength mobility !< dislocation mobility associate(prm => param(instance)) ns = prm%sum_N_sl v = 0.0_pReal dv_dtau = 0.0_pReal dv_dtauNS = 0.0_pReal do s = 1,ns if (abs(tau(s)) > tauThreshold(s)) then !* Peierls contribution !* Effective stress includes non Schmid constributions !* The derivative only gives absolute values; the correct sign is taken care of in the formula for the derivative of the velocity tauEff = max(0.0_pReal, abs(tauNS(s)) - tauThreshold(s)) ! ensure that the effective stress is positive meanfreepath_P = prm%burgers(s) jumpWidth_P = prm%burgers(s) activationLength_P = prm%doublekinkwidth *prm%burgers(s) activationVolume_P = activationLength_P * jumpWidth_P * prm%burgers(s) criticalStress_P = prm%peierlsStress(s,c) activationEnergy_P = criticalStress_P * activationVolume_P tauRel_P = min(1.0_pReal, tauEff / criticalStress_P) ! ensure that the activation probability cannot become greater than one tPeierls = 1.0_pReal / prm%fattack & * exp(activationEnergy_P / (kB * Temperature) & * (1.0_pReal - tauRel_P**prm%p)**prm%q) if (tauEff < criticalStress_P) then dtPeierls_dtau = tPeierls * prm%p * prm%q * activationVolume_P / (kB * Temperature) & * (1.0_pReal - tauRel_P**prm%p)**(prm%q-1.0_pReal) * tauRel_P**(prm%p-1.0_pReal) else dtPeierls_dtau = 0.0_pReal endif !* Contribution from solid solution strengthening !* The derivative only gives absolute values; the correct sign is taken care of in the formula for the derivative of the velocity tauEff = abs(tau(s)) - tauThreshold(s) meanfreepath_S = prm%burgers(s) / sqrt(prm%solidSolutionConcentration) jumpWidth_S = prm%solidSolutionSize * prm%burgers(s) activationLength_S = prm%burgers(s) / sqrt(prm%solidSolutionConcentration) activationVolume_S = activationLength_S * jumpWidth_S * prm%burgers(s) activationEnergy_S = prm%solidSolutionEnergy criticalStress_S = activationEnergy_S / activationVolume_S tauRel_S = min(1.0_pReal, tauEff / criticalStress_S) ! ensure that the activation probability cannot become greater than one tSolidSolution = 1.0_pReal / prm%fattack & * exp(activationEnergy_S / (kB * Temperature)* (1.0_pReal - tauRel_S**prm%p)**prm%q) if (tauEff < criticalStress_S) then dtSolidSolution_dtau = tSolidSolution * prm%p * prm%q * activationVolume_S / (kB * Temperature) & * (1.0_pReal - tauRel_S**prm%p)**(prm%q-1.0_pReal)* tauRel_S**(prm%p-1.0_pReal) else dtSolidSolution_dtau = 0.0_pReal endif !* viscous glide velocity tauEff = abs(tau(s)) - tauThreshold(s) mobility = prm%burgers(s) / prm%viscosity vViscous = mobility * tauEff !* Mean velocity results from waiting time at peierls barriers and solid solution obstacles with respective meanfreepath of !* free flight at glide velocity in between. !* adopt sign from resolved stress v(s) = sign(1.0_pReal,tau(s)) & / (tPeierls / meanfreepath_P + tSolidSolution / meanfreepath_S + 1.0_pReal / vViscous) dv_dtau(s) = v(s)**2.0_pReal * (dtSolidSolution_dtau / meanfreepath_S + mobility /vViscous**2.0_pReal) dv_dtauNS(s) = v(s)**2.0_pReal * dtPeierls_dtau / meanfreepath_P endif enddo end associate end subroutine kinetics !-------------------------------------------------------------------------------------------------- !> @brief returns copy of current dislocation densities from state !> @details raw values is rectified !-------------------------------------------------------------------------------------------------- function getRho(instance,of,ip,el) integer, intent(in) :: instance, of,ip,el real(pReal), dimension(param(instance)%sum_N_sl,10) :: getRho associate(prm => param(instance)) getRho = reshape(state(instance)%rho(:,of),[prm%sum_N_sl,10]) ! ensure positive densities (not for imm, they have a sign) getRho(:,mob) = max(getRho(:,mob),0.0_pReal) getRho(:,dip) = max(getRho(:,dip),0.0_pReal) where(abs(getRho) < max(prm%significantN/IPvolume(ip,el)**(2.0_pReal/3.0_pReal),prm%significantRho)) & getRho = 0.0_pReal end associate end function getRho !-------------------------------------------------------------------------------------------------- !> @brief returns copy of current dislocation densities from state !> @details raw values is rectified !-------------------------------------------------------------------------------------------------- function getRho0(instance,of,ip,el) integer, intent(in) :: instance, of,ip,el real(pReal), dimension(param(instance)%sum_N_sl,10) :: getRho0 associate(prm => param(instance)) getRho0 = reshape(state0(instance)%rho(:,of),[prm%sum_N_sl,10]) ! ensure positive densities (not for imm, they have a sign) getRho0(:,mob) = max(getRho0(:,mob),0.0_pReal) getRho0(:,dip) = max(getRho0(:,dip),0.0_pReal) where(abs(getRho0) < max(prm%significantN/IPvolume(ip,el)**(2.0_pReal/3.0_pReal),prm%significantRho)) & getRho0 = 0.0_pReal end associate end function getRho0 end submodule plastic_nonlocal # 44 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/crystallite.f90" 1 !-------------------------------------------------------------------------------------------------- !> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH !> @author Pratheek Shanthraj, Max-Planck-Institut für Eisenforschung GmbH !> @author Franz Roters, Max-Planck-Institut für Eisenforschung GmbH !> @author Philip Eisenlohr, Max-Planck-Institut für Eisenforschung GmbH !> @author Christoph Kords, Max-Planck-Institut für Eisenforschung GmbH !> @author Chen Zhang, Michigan State University !> @brief crystallite state integration functions and reporting of results !-------------------------------------------------------------------------------------------------- module crystallite use prec use IO use HDF5_utilities use DAMASK_interface use config use debug use numerics use rotations use math use FEsolving use material use constitutive use discretization use lattice use results implicit none private real(pReal), dimension(:,:,:), allocatable, public :: & crystallite_dt !< requested time increment of each grain real(pReal), dimension(:,:,:), allocatable :: & crystallite_subdt, & !< substepped time increment of each grain crystallite_subFrac, & !< already calculated fraction of increment crystallite_subStep !< size of next integration step type(rotation), dimension(:,:,:), allocatable :: & crystallite_orientation !< current orientation real(pReal), dimension(:,:,:,:,:), allocatable, public, protected :: & crystallite_Fe, & !< current "elastic" def grad (end of converged time step) crystallite_P, & !< 1st Piola-Kirchhoff stress per grain crystallite_S0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc crystallite_Fp0, & !< plastic def grad at start of FE inc crystallite_Fi0, & !< intermediate def grad at start of FE inc crystallite_F0, & !< def grad at start of FE inc crystallite_Lp0, & !< plastic velocitiy grad at start of FE inc crystallite_Li0 !< intermediate velocitiy grad at start of FE inc real(pReal), dimension(:,:,:,:,:), allocatable, public :: & crystallite_S, & !< current 2nd Piola-Kirchhoff stress vector (end of converged time step) crystallite_partionedS0, & !< 2nd Piola-Kirchhoff stress vector at start of homog inc crystallite_Fp, & !< current plastic def grad (end of converged time step) crystallite_partionedFp0,& !< plastic def grad at start of homog inc crystallite_Fi, & !< current intermediate def grad (end of converged time step) crystallite_partionedFi0,& !< intermediate def grad at start of homog inc crystallite_partionedF, & !< def grad to be reached at end of homog inc crystallite_partionedF0, & !< def grad at start of homog inc crystallite_Lp, & !< current plastic velocitiy grad (end of converged time step) crystallite_partionedLp0, & !< plastic velocity grad at start of homog inc crystallite_Li, & !< current intermediate velocitiy grad (end of converged time step) crystallite_partionedLi0 !< intermediate velocity grad at start of homog inc real(pReal), dimension(:,:,:,:,:), allocatable :: & crystallite_subFp0,& !< plastic def grad at start of crystallite inc crystallite_subFi0,& !< intermediate def grad at start of crystallite inc crystallite_subF, & !< def grad to be reached at end of crystallite inc crystallite_subF0, & !< def grad at start of crystallite inc crystallite_subLp0,& !< plastic velocity grad at start of crystallite inc crystallite_subLi0 !< intermediate velocity grad at start of crystallite inc real(pReal), dimension(:,:,:,:,:,:,:), allocatable, public, protected :: & crystallite_dPdF !< current individual dPdF per grain (end of converged time step) logical, dimension(:,:,:), allocatable, public :: & crystallite_requested !< used by upper level (homogenization) to request crystallite calculation logical, dimension(:,:,:), allocatable :: & crystallite_converged, & !< convergence flag crystallite_todo, & !< flag to indicate need for further computation crystallite_localPlasticity !< indicates this grain to have purely local constitutive law type :: tOutput !< new requested output (per phase) character(len=pStringLen), allocatable, dimension(:) :: & label end type tOutput type(tOutput), allocatable, dimension(:) :: output_constituent type :: tNumerics integer :: & iJacoLpresiduum, & !< frequency of Jacobian update of residuum in Lp nState, & !< state loop limit nStress !< stress loop limit real(pReal) :: & subStepMinCryst, & !< minimum (relative) size of sub-step allowed during cutback subStepSizeCryst, & !< size of first substep when cutback subStepSizeLp, & !< size of first substep when cutback in Lp calculation subStepSizeLi, & !< size of first substep when cutback in Li calculation stepIncreaseCryst, & !< increase of next substep size when previous substep converged rtol_crystalliteState, & !< relative tolerance in state loop rtol_crystalliteStress, & !< relative tolerance in stress loop atol_crystalliteStress !< absolute tolerance in stress loop end type tNumerics type(tNumerics) :: num ! numerics parameters. Better name? procedure(), pointer :: integrateState public :: & crystallite_init, & crystallite_stress, & crystallite_stressTangent, & crystallite_orientations, & crystallite_push33ToRef, & crystallite_results, & crystallite_restartWrite, & crystallite_restartRead, & crystallite_forward contains !-------------------------------------------------------------------------------------------------- !> @brief allocates and initialize per grain variables !-------------------------------------------------------------------------------------------------- subroutine crystallite_init logical, dimension(discretization_nIP,discretization_nElem) :: devNull integer :: & c, & !< counter in integration point component loop i, & !< counter in integration point loop e, & !< counter in element loop cMax, & !< maximum number of integration point components iMax, & !< maximum number of integration points eMax, & !< maximum number of elements myNcomponents !< number of components at current IP write(6,'(/,a)') ' <<<+- crystallite init -+>>>' cMax = homogenization_maxNgrains iMax = discretization_nIP eMax = discretization_nElem allocate(crystallite_partionedF(3,3,cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_S0, & crystallite_F0, crystallite_Fi0,crystallite_Fp0, & crystallite_Li0,crystallite_Lp0, & crystallite_partionedS0, & crystallite_partionedF0,crystallite_partionedFp0,crystallite_partionedFi0, & crystallite_partionedLp0,crystallite_partionedLi0, & crystallite_S,crystallite_P, & crystallite_Fe,crystallite_Fi,crystallite_Fp, & crystallite_Li,crystallite_Lp, & crystallite_subF,crystallite_subF0, & crystallite_subFp0,crystallite_subFi0, & crystallite_subLi0,crystallite_subLp0, & source = crystallite_partionedF) allocate(crystallite_dPdF(3,3,3,3,cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_dt(cMax,iMax,eMax),source=0.0_pReal) allocate(crystallite_subdt,crystallite_subFrac,crystallite_subStep, & source = crystallite_dt) allocate(crystallite_orientation(cMax,iMax,eMax)) allocate(crystallite_localPlasticity(cMax,iMax,eMax), source=.true.) allocate(crystallite_requested(cMax,iMax,eMax), source=.false.) allocate(crystallite_todo(cMax,iMax,eMax), source=.false.) allocate(crystallite_converged(cMax,iMax,eMax), source=.true.) num%subStepMinCryst = config_numerics%getFloat('substepmincryst', defaultVal=1.0e-3_pReal) num%subStepSizeCryst = config_numerics%getFloat('substepsizecryst', defaultVal=0.25_pReal) num%stepIncreaseCryst = config_numerics%getFloat('stepincreasecryst', defaultVal=1.5_pReal) num%subStepSizeLp = config_numerics%getFloat('substepsizelp', defaultVal=0.5_pReal) num%subStepSizeLi = config_numerics%getFloat('substepsizeli', defaultVal=0.5_pReal) num%rtol_crystalliteState = config_numerics%getFloat('rtol_crystallitestate', defaultVal=1.0e-6_pReal) num%rtol_crystalliteStress = config_numerics%getFloat('rtol_crystallitestress',defaultVal=1.0e-6_pReal) num%atol_crystalliteStress = config_numerics%getFloat('atol_crystallitestress',defaultVal=1.0e-8_pReal) num%iJacoLpresiduum = config_numerics%getInt ('ijacolpresiduum', defaultVal=1) num%nState = config_numerics%getInt ('nstate', defaultVal=20) num%nStress = config_numerics%getInt ('nstress', defaultVal=40) if(num%subStepMinCryst <= 0.0_pReal) call IO_error(301,ext_msg='subStepMinCryst') if(num%subStepSizeCryst <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeCryst') if(num%stepIncreaseCryst <= 0.0_pReal) call IO_error(301,ext_msg='stepIncreaseCryst') if(num%subStepSizeLp <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeLp') if(num%subStepSizeLi <= 0.0_pReal) call IO_error(301,ext_msg='subStepSizeLi') if(num%rtol_crystalliteState <= 0.0_pReal) call IO_error(301,ext_msg='rtol_crystalliteState') if(num%rtol_crystalliteStress <= 0.0_pReal) call IO_error(301,ext_msg='rtol_crystalliteStress') if(num%atol_crystalliteStress <= 0.0_pReal) call IO_error(301,ext_msg='atol_crystalliteStress') if(num%iJacoLpresiduum < 1) call IO_error(301,ext_msg='iJacoLpresiduum') if(num%nState < 1) call IO_error(301,ext_msg='nState') if(num%nStress< 1) call IO_error(301,ext_msg='nStress') select case(numerics_integrator) case(1) integrateState => integrateStateFPI case(2) integrateState => integrateStateEuler case(3) integrateState => integrateStateAdaptiveEuler case(4) integrateState => integrateStateRK4 case(5) integrateState => integrateStateRKCK45 end select allocate(output_constituent(size(config_phase))) do c = 1, size(config_phase) allocate(output_constituent(c)%label(1)) output_constituent(c)%label(1)= 'GfortranBug86277' output_constituent(c)%label = config_phase(c)%getStrings('(output)',defaultVal=output_constituent(c)%label ) if (output_constituent(c)%label (1) == 'GfortranBug86277') output_constituent(c)%label = [character(len=pStringLen)::] enddo call config_deallocate('material.config/phase') !-------------------------------------------------------------------------------------------------- ! initialize !$OMP PARALLEL DO PRIVATE(myNcomponents,i,c) do e = FEsolving_execElem(1),FEsolving_execElem(2) myNcomponents = homogenization_Ngrains(material_homogenizationAt(e)) do i = FEsolving_execIP(1), FEsolving_execIP(2); do c = 1, myNcomponents crystallite_Fp0(1:3,1:3,c,i,e) = material_orientation0(c,i,e)%asMatrix() ! plastic def gradient reflects init orientation crystallite_Fp0(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) & / math_det33(crystallite_Fp0(1:3,1:3,c,i,e))**(1.0_pReal/3.0_pReal) crystallite_Fi0(1:3,1:3,c,i,e) = constitutive_initialFi(c,i,e) crystallite_F0(1:3,1:3,c,i,e) = math_I3 crystallite_localPlasticity(c,i,e) = phase_localPlasticity(material_phaseAt(c,e)) crystallite_Fe(1:3,1:3,c,i,e) = math_inv33(matmul(crystallite_Fi0(1:3,1:3,c,i,e), & crystallite_Fp0(1:3,1:3,c,i,e))) ! assuming that euler angles are given in internal strain free configuration crystallite_Fp(1:3,1:3,c,i,e) = crystallite_Fp0(1:3,1:3,c,i,e) crystallite_Fi(1:3,1:3,c,i,e) = crystallite_Fi0(1:3,1:3,c,i,e) crystallite_requested(c,i,e) = .true. enddo; enddo enddo !$OMP END PARALLEL DO if(any(.not. crystallite_localPlasticity) .and. .not. usePingPong) call IO_error(601) ! exit if nonlocal but no ping-pong ToDo: Why not check earlier? or in nonlocal? crystallite_partionedFp0 = crystallite_Fp0 crystallite_partionedFi0 = crystallite_Fi0 crystallite_partionedF0 = crystallite_F0 crystallite_partionedF = crystallite_F0 call crystallite_orientations() !$OMP PARALLEL DO do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Ngrains(material_homogenizationAt(e)) call constitutive_dependentState(crystallite_partionedF0(1:3,1:3,c,i,e), & crystallite_partionedFp0(1:3,1:3,c,i,e), & c,i,e) ! update dependent state variables to be consistent with basic states enddo enddo enddo !$OMP END PARALLEL DO devNull = crystallite_stress() call crystallite_stressTangent # 283 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/crystallite.f90" end subroutine crystallite_init !-------------------------------------------------------------------------------------------------- !> @brief calculate stress (P) !-------------------------------------------------------------------------------------------------- function crystallite_stress(dummyArgumentToPreventInternalCompilerErrorWithGCC) logical, dimension(discretization_nIP,discretization_nElem) :: crystallite_stress real(pReal), intent(in), optional :: & dummyArgumentToPreventInternalCompilerErrorWithGCC real(pReal) :: & formerSubStep integer :: & NiterationCrystallite, & ! number of iterations in crystallite loop c, & !< counter in integration point component loop i, & !< counter in integration point loop e, & !< counter in element loop startIP, endIP, & s # 325 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/crystallite.f90" !-------------------------------------------------------------------------------------------------- ! initialize to starting condition crystallite_subStep = 0.0_pReal !$OMP PARALLEL DO elementLooping1: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2); do c = 1,homogenization_Ngrains(material_homogenizationAt(e)) homogenizationRequestsCalculation: if (crystallite_requested(c,i,e)) then plasticState (material_phaseAt(c,e))%subState0( :,material_phaseMemberAt(c,i,e)) = & plasticState (material_phaseAt(c,e))%partionedState0(:,material_phaseMemberAt(c,i,e)) do s = 1, phase_Nsources(material_phaseAt(c,e)) sourceState(material_phaseAt(c,e))%p(s)%subState0( :,material_phaseMemberAt(c,i,e)) = & sourceState(material_phaseAt(c,e))%p(s)%partionedState0(:,material_phaseMemberAt(c,i,e)) enddo crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_partionedFp0(1:3,1:3,c,i,e) crystallite_subLp0(1:3,1:3,c,i,e) = crystallite_partionedLp0(1:3,1:3,c,i,e) crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_partionedFi0(1:3,1:3,c,i,e) crystallite_subLi0(1:3,1:3,c,i,e) = crystallite_partionedLi0(1:3,1:3,c,i,e) crystallite_subF0(1:3,1:3,c,i,e) = crystallite_partionedF0(1:3,1:3,c,i,e) crystallite_subFrac(c,i,e) = 0.0_pReal crystallite_subStep(c,i,e) = 1.0_pReal/num%subStepSizeCryst crystallite_todo(c,i,e) = .true. crystallite_converged(c,i,e) = .false. ! pretend failed step of 1/subStepSizeCryst endif homogenizationRequestsCalculation enddo; enddo enddo elementLooping1 !$OMP END PARALLEL DO singleRun: if (FEsolving_execELem(1) == FEsolving_execElem(2) .and. & FEsolving_execIP (1) == FEsolving_execIP (2)) then startIP = FEsolving_execIP(1) endIP = startIP else singleRun startIP = 1 endIP = discretization_nIP endif singleRun NiterationCrystallite = 0 cutbackLooping: do while (any(crystallite_todo(:,startIP:endIP,FEsolving_execELem(1):FEsolving_execElem(2)))) NiterationCrystallite = NiterationCrystallite + 1 !$OMP PARALLEL DO PRIVATE(formerSubStep) elementLooping3: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Ngrains(material_homogenizationAt(e)) !-------------------------------------------------------------------------------------------------- ! wind forward if (crystallite_converged(c,i,e)) then formerSubStep = crystallite_subStep(c,i,e) crystallite_subFrac(c,i,e) = crystallite_subFrac(c,i,e) + crystallite_subStep(c,i,e) crystallite_subStep(c,i,e) = min(1.0_pReal - crystallite_subFrac(c,i,e), & num%stepIncreaseCryst * crystallite_subStep(c,i,e)) crystallite_todo(c,i,e) = crystallite_subStep(c,i,e) > 0.0_pReal ! still time left to integrate on? if (crystallite_todo(c,i,e)) then crystallite_subF0 (1:3,1:3,c,i,e) = crystallite_subF(1:3,1:3,c,i,e) crystallite_subLp0(1:3,1:3,c,i,e) = crystallite_Lp (1:3,1:3,c,i,e) crystallite_subLi0(1:3,1:3,c,i,e) = crystallite_Li (1:3,1:3,c,i,e) crystallite_subFp0(1:3,1:3,c,i,e) = crystallite_Fp (1:3,1:3,c,i,e) crystallite_subFi0(1:3,1:3,c,i,e) = crystallite_Fi (1:3,1:3,c,i,e) !if abbrevation, make c and p private in omp plasticState( material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) & = plasticState(material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) do s = 1, phase_Nsources(material_phaseAt(c,e)) sourceState( material_phaseAt(c,e))%p(s)%subState0(:,material_phaseMemberAt(c,i,e)) & = sourceState(material_phaseAt(c,e))%p(s)%state( :,material_phaseMemberAt(c,i,e)) enddo endif !-------------------------------------------------------------------------------------------------- ! cut back (reduced time and restore) else crystallite_subStep(c,i,e) = num%subStepSizeCryst * crystallite_subStep(c,i,e) crystallite_Fp (1:3,1:3,c,i,e) = crystallite_subFp0(1:3,1:3,c,i,e) crystallite_Fi (1:3,1:3,c,i,e) = crystallite_subFi0(1:3,1:3,c,i,e) crystallite_S (1:3,1:3,c,i,e) = crystallite_S0 (1:3,1:3,c,i,e) if (crystallite_subStep(c,i,e) < 1.0_pReal) then ! actual (not initial) cutback crystallite_Lp (1:3,1:3,c,i,e) = crystallite_subLp0(1:3,1:3,c,i,e) crystallite_Li (1:3,1:3,c,i,e) = crystallite_subLi0(1:3,1:3,c,i,e) endif plasticState (material_phaseAt(c,e))%state( :,material_phaseMemberAt(c,i,e)) & = plasticState(material_phaseAt(c,e))%subState0(:,material_phaseMemberAt(c,i,e)) do s = 1, phase_Nsources(material_phaseAt(c,e)) sourceState( material_phaseAt(c,e))%p(s)%state( :,material_phaseMemberAt(c,i,e)) & = sourceState(material_phaseAt(c,e))%p(s)%subState0(:,material_phaseMemberAt(c,i,e)) enddo ! cant restore dotState here, since not yet calculated in first cutback after initialization crystallite_todo(c,i,e) = crystallite_subStep(c,i,e) > num%subStepMinCryst ! still on track or already done (beyond repair) endif !-------------------------------------------------------------------------------------------------- ! prepare for integration if (crystallite_todo(c,i,e)) then crystallite_subF(1:3,1:3,c,i,e) = crystallite_subF0(1:3,1:3,c,i,e) & + crystallite_subStep(c,i,e) *( crystallite_partionedF (1:3,1:3,c,i,e) & -crystallite_partionedF0(1:3,1:3,c,i,e)) crystallite_Fe(1:3,1:3,c,i,e) = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), & math_inv33(crystallite_Fp(1:3,1:3,c,i,e))), & math_inv33(crystallite_Fi(1:3,1:3,c,i,e))) crystallite_subdt(c,i,e) = crystallite_subStep(c,i,e) * crystallite_dt(c,i,e) crystallite_converged(c,i,e) = .false. endif enddo enddo enddo elementLooping3 !$OMP END PARALLEL DO !-------------------------------------------------------------------------------------------------- ! integrate --- requires fully defined state array (basic + dependent state) if (any(crystallite_todo)) call integrateState ! TODO: unroll into proper elementloop to avoid N^2 for single point evaluation where(.not. crystallite_converged .and. crystallite_subStep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further crystallite_todo = .true. ! TODO: again unroll this into proper elementloop to avoid N^2 for single point evaluation enddo cutbackLooping ! return whether converged or not crystallite_stress = .false. elementLooping5: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) crystallite_stress(i,e) = all(crystallite_converged(:,i,e)) enddo enddo elementLooping5 end function crystallite_stress !-------------------------------------------------------------------------------------------------- !> @brief calculate tangent (dPdF) !-------------------------------------------------------------------------------------------------- subroutine crystallite_stressTangent integer :: & c, & !< counter in integration point component loop i, & !< counter in integration point loop e, & !< counter in element loop o, & p real(pReal), dimension(3,3) :: devNull, & invSubFp0,invSubFi0,invFp,invFi, & temp_33_1, temp_33_2, temp_33_3, temp_33_4 real(pReal), dimension(3,3,3,3) :: dSdFe, & dSdF, & dSdFi, & dLidS, & ! tangent in lattice configuration dLidFi, & dLpdS, & dLpdFi, & dFidS, & dFpinvdF, & rhs_3333, & lhs_3333, & temp_3333 real(pReal), dimension(9,9):: temp_99 logical :: error !$OMP PARALLEL DO PRIVATE(dSdF,dSdFe,dSdFi,dLpdS,dLpdFi,dFpinvdF,dLidS,dLidFi,dFidS,o,p, & !$OMP invSubFp0,invSubFi0,invFp,invFi, & !$OMP rhs_3333,lhs_3333,temp_99,temp_33_1,temp_33_2,temp_33_3,temp_33_4,temp_3333,error) elementLooping: do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Ngrains(material_homogenizationAt(e)) call constitutive_SandItsTangents(devNull,dSdFe,dSdFi, & crystallite_Fe(1:3,1:3,c,i,e), & crystallite_Fi(1:3,1:3,c,i,e),c,i,e) call constitutive_LiAndItsTangents(devNull,dLidS,dLidFi, & crystallite_S (1:3,1:3,c,i,e), & crystallite_Fi(1:3,1:3,c,i,e), & c,i,e) invFp = math_inv33(crystallite_Fp(1:3,1:3,c,i,e)) invFi = math_inv33(crystallite_Fi(1:3,1:3,c,i,e)) invSubFp0 = math_inv33(crystallite_subFp0(1:3,1:3,c,i,e)) invSubFi0 = math_inv33(crystallite_subFi0(1:3,1:3,c,i,e)) if (sum(abs(dLidS)) < tol_math_check) then dFidS = 0.0_pReal else lhs_3333 = 0.0_pReal; rhs_3333 = 0.0_pReal do o=1,3; do p=1,3 lhs_3333(1:3,1:3,o,p) = lhs_3333(1:3,1:3,o,p) & + crystallite_subdt(c,i,e)*matmul(invSubFi0,dLidFi(1:3,1:3,o,p)) lhs_3333(1:3,o,1:3,p) = lhs_3333(1:3,o,1:3,p) & + invFi*invFi(p,o) rhs_3333(1:3,1:3,o,p) = rhs_3333(1:3,1:3,o,p) & - crystallite_subdt(c,i,e)*matmul(invSubFi0,dLidS(1:3,1:3,o,p)) enddo; enddo call math_invert(temp_99,error,math_3333to99(lhs_3333)) if (error) then call IO_warning(warning_ID=600,el=e,ip=i,g=c, & ext_msg='inversion error in analytic tangent calculation') dFidS = 0.0_pReal else dFidS = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) endif dLidS = math_mul3333xx3333(dLidFi,dFidS) + dLidS endif call constitutive_LpAndItsTangents(devNull,dLpdS,dLpdFi, & crystallite_S (1:3,1:3,c,i,e), & crystallite_Fi(1:3,1:3,c,i,e),c,i,e) ! call constitutive law to calculate Lp tangent in lattice configuration dLpdS = math_mul3333xx3333(dLpdFi,dFidS) + dLpdS !-------------------------------------------------------------------------------------------------- ! calculate dSdF temp_33_1 = transpose(matmul(invFp,invFi)) temp_33_2 = matmul(crystallite_subF(1:3,1:3,c,i,e),invSubFp0) temp_33_3 = matmul(matmul(crystallite_subF(1:3,1:3,c,i,e),invFp), invSubFi0) do o=1,3; do p=1,3 rhs_3333(p,o,1:3,1:3) = matmul(dSdFe(p,o,1:3,1:3),temp_33_1) temp_3333(1:3,1:3,p,o) = matmul(matmul(temp_33_2,dLpdS(1:3,1:3,p,o)), invFi) & + matmul(temp_33_3,dLidS(1:3,1:3,p,o)) enddo; enddo lhs_3333 = crystallite_subdt(c,i,e)*math_mul3333xx3333(dSdFe,temp_3333) & + math_mul3333xx3333(dSdFi,dFidS) call math_invert(temp_99,error,math_identity2nd(9)+math_3333to99(lhs_3333)) if (error) then call IO_warning(warning_ID=600,el=e,ip=i,g=c, & ext_msg='inversion error in analytic tangent calculation') dSdF = rhs_3333 else dSdF = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333) endif !-------------------------------------------------------------------------------------------------- ! calculate dFpinvdF temp_3333 = math_mul3333xx3333(dLpdS,dSdF) do o=1,3; do p=1,3 dFpinvdF(1:3,1:3,p,o) = -crystallite_subdt(c,i,e) & * matmul(invSubFp0, matmul(temp_3333(1:3,1:3,p,o),invFi)) enddo; enddo !-------------------------------------------------------------------------------------------------- ! assemble dPdF temp_33_1 = matmul(crystallite_S(1:3,1:3,c,i,e),transpose(invFp)) temp_33_2 = matmul(invFp,temp_33_1) temp_33_3 = matmul(crystallite_subF(1:3,1:3,c,i,e),invFp) temp_33_4 = matmul(temp_33_3,crystallite_S(1:3,1:3,c,i,e)) crystallite_dPdF(1:3,1:3,1:3,1:3,c,i,e) = 0.0_pReal do p=1,3 crystallite_dPdF(p,1:3,p,1:3,c,i,e) = transpose(temp_33_2) enddo do o=1,3; do p=1,3 crystallite_dPdF(1:3,1:3,p,o,c,i,e) = crystallite_dPdF(1:3,1:3,p,o,c,i,e) & + matmul(matmul(crystallite_subF(1:3,1:3,c,i,e), & dFpinvdF(1:3,1:3,p,o)),temp_33_1) & + matmul(matmul(temp_33_3,dSdF(1:3,1:3,p,o)), & transpose(invFp)) & + matmul(temp_33_4,transpose(dFpinvdF(1:3,1:3,p,o))) enddo; enddo enddo; enddo enddo elementLooping !$OMP END PARALLEL DO end subroutine crystallite_stressTangent !-------------------------------------------------------------------------------------------------- !> @brief calculates orientations !-------------------------------------------------------------------------------------------------- subroutine crystallite_orientations integer & c, & !< counter in integration point component loop i, & !< counter in integration point loop e !< counter in element loop !$OMP PARALLEL DO do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) do c = 1,homogenization_Ngrains(material_homogenizationAt(e)) call crystallite_orientation(c,i,e)%fromMatrix(transpose(math_rotationalPart(crystallite_Fe(1:3,1:3,c,i,e)))) enddo; enddo; enddo !$OMP END PARALLEL DO nonlocalPresent: if (any(plasticState%nonLocal)) then !$OMP PARALLEL DO do e = FEsolving_execElem(1),FEsolving_execElem(2) do i = FEsolving_execIP(1),FEsolving_execIP(2) if (plasticState(material_phaseAt(1,e))%nonLocal) & call plastic_nonlocal_updateCompatibility(crystallite_orientation, & phase_plasticityInstance(material_phaseAt(i,e)),i,e) enddo; enddo !$OMP END PARALLEL DO endif nonlocalPresent end subroutine crystallite_orientations !-------------------------------------------------------------------------------------------------- !> @brief Map 2nd order tensor to reference config !-------------------------------------------------------------------------------------------------- function crystallite_push33ToRef(ipc,ip,el, tensor33) real(pReal), dimension(3,3) :: crystallite_push33ToRef real(pReal), dimension(3,3), intent(in) :: tensor33 real(pReal), dimension(3,3) :: T integer, intent(in):: & el, & ip, & ipc T = matmul(material_orientation0(ipc,ip,el)%asMatrix(), & ! ToDo: initial orientation correct? transpose(math_inv33(crystallite_subF(1:3,1:3,ipc,ip,el)))) crystallite_push33ToRef = matmul(transpose(T),matmul(tensor33,T)) end function crystallite_push33ToRef !-------------------------------------------------------------------------------------------------- !> @brief writes crystallite results to HDF5 output file !-------------------------------------------------------------------------------------------------- subroutine crystallite_results integer :: p,o real(pReal), allocatable, dimension(:,:,:) :: selected_tensors type(rotation), allocatable, dimension(:) :: selected_rotations character(len=pStringLen) :: group,structureLabel do p=1,size(config_name_phase) group = trim('current/constituent')//'/'//trim(config_name_phase(p))//'/generic' call results_closeGroup(results_addGroup(group)) do o = 1, size(output_constituent(p)%label) select case (output_constituent(p)%label(o)) case('f') selected_tensors = select_tensors(crystallite_partionedF,p) call results_writeDataset(group,selected_tensors,'F',& 'deformation gradient','1') case('fe') selected_tensors = select_tensors(crystallite_Fe,p) call results_writeDataset(group,selected_tensors,'Fe',& 'elastic deformation gradient','1') case('fp') selected_tensors = select_tensors(crystallite_Fp,p) call results_writeDataset(group,selected_tensors,'Fp',& 'plastic deformation gradient','1') case('fi') selected_tensors = select_tensors(crystallite_Fi,p) call results_writeDataset(group,selected_tensors,'Fi',& 'inelastic deformation gradient','1') case('lp') selected_tensors = select_tensors(crystallite_Lp,p) call results_writeDataset(group,selected_tensors,'Lp',& 'plastic velocity gradient','1/s') case('li') selected_tensors = select_tensors(crystallite_Li,p) call results_writeDataset(group,selected_tensors,'Li',& 'inelastic velocity gradient','1/s') case('p') selected_tensors = select_tensors(crystallite_P,p) call results_writeDataset(group,selected_tensors,'P',& 'First Piola-Kirchoff stress','Pa') case('s') selected_tensors = select_tensors(crystallite_S,p) call results_writeDataset(group,selected_tensors,'S',& 'Second Piola-Kirchoff stress','Pa') case('orientation') select case(lattice_structure(p)) case(lattice_ISO_ID) structureLabel = 'iso' case(lattice_FCC_ID) structureLabel = 'fcc' case(lattice_BCC_ID) structureLabel = 'bcc' case(lattice_BCT_ID) structureLabel = 'bct' case(lattice_HEX_ID) structureLabel = 'hex' case(lattice_ORT_ID) structureLabel = 'ort' end select selected_rotations = select_rotations(crystallite_orientation,p) call results_writeDataset(group,selected_rotations,'orientation',& 'crystal orientation as quaternion',structureLabel) end select enddo enddo contains !------------------------------------------------------------------------------------------------ !> @brief select tensors for output !------------------------------------------------------------------------------------------------ function select_tensors(dataset,instance) integer, intent(in) :: instance real(pReal), dimension(:,:,:,:,:), intent(in) :: dataset real(pReal), allocatable, dimension(:,:,:) :: select_tensors integer :: e,i,c,j allocate(select_tensors(3,3,count(material_phaseAt==instance)*discretization_nIP)) j=0 do e = 1, size(material_phaseAt,2) do i = 1, discretization_nIP do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains if (material_phaseAt(c,e) == instance) then j = j + 1 select_tensors(1:3,1:3,j) = dataset(1:3,1:3,c,i,e) endif enddo enddo enddo end function select_tensors !-------------------------------------------------------------------------------------------------- !> @brief select rotations for output !-------------------------------------------------------------------------------------------------- function select_rotations(dataset,instance) integer, intent(in) :: instance type(rotation), dimension(:,:,:), intent(in) :: dataset type(rotation), allocatable, dimension(:) :: select_rotations integer :: e,i,c,j allocate(select_rotations(count(material_phaseAt==instance)*homogenization_maxNgrains*discretization_nIP)) j=0 do e = 1, size(material_phaseAt,2) do i = 1, discretization_nIP do c = 1, size(material_phaseAt,1) !ToDo: this needs to be changed for varying Ngrains if (material_phaseAt(c,e) == instance) then j = j + 1 select_rotations(j) = dataset(c,i,e) endif enddo enddo enddo end function select_rotations end subroutine crystallite_results !-------------------------------------------------------------------------------------------------- !> @brief calculation of stress (P) with time integration based on a residuum in Lp and !> intermediate acceleration of the Newton-Raphson correction !-------------------------------------------------------------------------------------------------- logical function integrateStress(ipc,ip,el,timeFraction) integer, intent(in):: el, & ! element index ip, & ! integration point index ipc ! grain index real(pReal), optional, intent(in) :: timeFraction ! fraction of timestep real(pReal), dimension(3,3):: F, & ! deformation gradient at end of timestep Fp_new, & ! plastic deformation gradient at end of timestep invFp_new, & ! inverse of Fp_new invFp_current, & ! inverse of Fp_current Lpguess, & ! current guess for plastic velocity gradient Lpguess_old, & ! known last good guess for plastic velocity gradient Lp_constitutive, & ! plastic velocity gradient resulting from constitutive law residuumLp, & ! current residuum of plastic velocity gradient residuumLp_old, & ! last residuum of plastic velocity gradient deltaLp, & ! direction of next guess Fi_new, & ! gradient of intermediate deformation stages invFi_new, & invFi_current, & ! inverse of Fi_current Liguess, & ! current guess for intermediate velocity gradient Liguess_old, & ! known last good guess for intermediate velocity gradient Li_constitutive, & ! intermediate velocity gradient resulting from constitutive law residuumLi, & ! current residuum of intermediate velocity gradient residuumLi_old, & ! last residuum of intermediate velocity gradient deltaLi, & ! direction of next guess Fe, & ! elastic deformation gradient Fe_new, & S, & ! 2nd Piola-Kirchhoff Stress in plastic (lattice) configuration A, & B, & temp_33 real(pReal), dimension(9) :: temp_9 ! needed for matrix inversion by LAPACK integer, dimension(9) :: devNull_9 ! needed for matrix inversion by LAPACK real(pReal), dimension(9,9) :: dRLp_dLp, & ! partial derivative of residuum (Jacobian for Newton-Raphson scheme) dRLi_dLi ! partial derivative of residuumI (Jacobian for Newton-Raphson scheme) real(pReal), dimension(3,3,3,3):: dS_dFe, & ! partial derivative of 2nd Piola-Kirchhoff stress dS_dFi, & dFe_dLp, & ! partial derivative of elastic deformation gradient dFe_dLi, & dFi_dLi, & dLp_dFi, & dLi_dFi, & dLp_dS, & dLi_dS real(pReal) steplengthLp, & steplengthLi, & dt, & ! time increment atol_Lp, & atol_Li, & devNull integer NiterationStressLp, & ! number of stress integrations NiterationStressLi, & ! number of inner stress integrations ierr, & ! error indicator for LAPACK o, & p, & jacoCounterLp, & jacoCounterLi ! counters to check for Jacobian update logical :: error external :: & dgesv integrateStress = .false. if (present(timeFraction)) then dt = crystallite_subdt(ipc,ip,el) * timeFraction F = crystallite_subF0(1:3,1:3,ipc,ip,el) & + (crystallite_subF(1:3,1:3,ipc,ip,el) - crystallite_subF0(1:3,1:3,ipc,ip,el)) * timeFraction else dt = crystallite_subdt(ipc,ip,el) F = crystallite_subF(1:3,1:3,ipc,ip,el) endif Lpguess = crystallite_Lp(1:3,1:3,ipc,ip,el) ! take as first guess Liguess = crystallite_Li(1:3,1:3,ipc,ip,el) ! take as first guess call math_invert33(invFp_current,devNull,error,crystallite_subFp0(1:3,1:3,ipc,ip,el)) if (error) return ! error call math_invert33(invFi_current,devNull,error,crystallite_subFi0(1:3,1:3,ipc,ip,el)) if (error) return ! error A = matmul(F,invFp_current) ! intermediate tensor needed later to calculate dFe_dLp jacoCounterLi = 0 steplengthLi = 1.0_pReal residuumLi_old = 0.0_pReal Liguess_old = Liguess NiterationStressLi = 0 LiLoop: do NiterationStressLi = NiterationStressLi + 1 if (NiterationStressLi>num%nStress) return ! error invFi_new = matmul(invFi_current,math_I3 - dt*Liguess) Fi_new = math_inv33(invFi_new) jacoCounterLp = 0 steplengthLp = 1.0_pReal residuumLp_old = 0.0_pReal Lpguess_old = Lpguess NiterationStressLp = 0 LpLoop: do NiterationStressLp = NiterationStressLp + 1 if (NiterationStressLp>num%nStress) return ! error B = math_I3 - dt*Lpguess Fe = matmul(matmul(A,B), invFi_new) call constitutive_SandItsTangents(S, dS_dFe, dS_dFi, & Fe, Fi_new, ipc, ip, el) call constitutive_LpAndItsTangents(Lp_constitutive, dLp_dS, dLp_dFi, & S, Fi_new, ipc, ip, el) !* update current residuum and check for convergence of loop atol_Lp = max(num%rtol_crystalliteStress * max(norm2(Lpguess),norm2(Lp_constitutive)), & ! absolute tolerance from largest acceptable relative error num%atol_crystalliteStress) ! minimum lower cutoff residuumLp = Lpguess - Lp_constitutive if (any(IEEE_is_NaN(residuumLp))) then return ! error elseif (norm2(residuumLp) < atol_Lp) then ! converged if below absolute tolerance exit LpLoop elseif (NiterationStressLp == 1 .or. norm2(residuumLp) < norm2(residuumLp_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... residuumLp_old = residuumLp ! ...remember old values and... Lpguess_old = Lpguess steplengthLp = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) else ! not converged and residuum not improved... steplengthLp = num%subStepSizeLp * steplengthLp ! ...try with smaller step length in same direction Lpguess = Lpguess_old & + deltaLp * stepLengthLp cycle LpLoop endif !* calculate Jacobian for correction term if (mod(jacoCounterLp, num%iJacoLpresiduum) == 0) then jacoCounterLp = jacoCounterLp + 1 do o=1,3; do p=1,3 dFe_dLp(o,1:3,p,1:3) = A(o,p)*transpose(invFi_new) ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j) enddo; enddo dFe_dLp = - dt * dFe_dLp dRLp_dLp = math_identity2nd(9) & - math_3333to99(math_mul3333xx3333(math_mul3333xx3333(dLp_dS,dS_dFe),dFe_dLp)) temp_9 = math_33to9(residuumLp) call dgesv(9,1,dRLp_dLp,9,devNull_9,temp_9,9,ierr) ! solve dRLp/dLp * delta Lp = -res for delta Lp if (ierr /= 0) return ! error deltaLp = - math_9to33(temp_9) endif Lpguess = Lpguess & + deltaLp * steplengthLp enddo LpLoop call constitutive_LiAndItsTangents(Li_constitutive, dLi_dS, dLi_dFi, & S, Fi_new, ipc, ip, el) !* update current residuum and check for convergence of loop atol_Li = max(num%rtol_crystalliteStress * max(norm2(Liguess),norm2(Li_constitutive)), & ! absolute tolerance from largest acceptable relative error num%atol_crystalliteStress) ! minimum lower cutoff residuumLi = Liguess - Li_constitutive if (any(IEEE_is_NaN(residuumLi))) then return ! error elseif (norm2(residuumLi) < atol_Li) then ! converged if below absolute tolerance exit LiLoop elseif (NiterationStressLi == 1 .or. norm2(residuumLi) < norm2(residuumLi_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)... residuumLi_old = residuumLi ! ...remember old values and... Liguess_old = Liguess steplengthLi = 1.0_pReal ! ...proceed with normal step length (calculate new search direction) else ! not converged and residuum not improved... steplengthLi = num%subStepSizeLi �s] for each trans system
18110  t_tw, & !< twin thickness [m] for each twin system
18111  clambdaslip, & !< Adj. parameter for distance between 2 forest dislocations for each slip system
18112  t_tr, & !< martensite lamellar thickness [m] for each trans system and instance
18113  p, & !< p-exponent in glide velocity
18114  q, & !< q-exponent in glide velocity
18115  r, & !< r-exponent in twin nucleation rate
18116  s, & !< s-exponent in trans nucleation rate
18117  gamma_char, & !< characteristic shear for twins
18118  b
18119  real(preal), allocatable, dimension(:,:) :: &
18120  h_sl_sl, & !<
18121  h_sl_tw, & !<
18122  h_tw_tw, & !<
18123  h_sl_tr, & !<
18124  h_tr_tr, & !<
18125  n0_sl, & !< slip system normal
18126  forestprojection, &
18127  c66
18128  real(preal), allocatable, dimension(:,:,:) :: &
18129  p_sl, &
18130  p_tw, &
18131  p_tr, &
18132  c66_tw, &
18133  c66_tr
18134  integer :: &
18135  sum_n_sl, & !< total number of active slip system
18136  sum_n_tw, & !< total number of active twin system
18137  sum_n_tr
18138  integer, allocatable, dimension(:,:) :: &
18139  fcc_twinnucleationslippair ! ToDo: Better name? Is also use for trans
18140  character(len=pStringLen), allocatable, dimension(:) :: &
18141  output
18142  logical :: &
18143  extendeddislocations, & !< consider split into partials for climb calculation
18144  fcctwintransnucleation, & !< twinning and transformation models are for fcc
18145  dipoleformation
18146  end type
18147 
18148  type :: tdislotwinstate
18149  real(preal), dimension(:,:), pointer :: &
18150  rho_mob, &
18151  rho_dip, &
18152  gamma_sl, &
18153  f_tw, &
18154  f_tr
18155  end type tdislotwinstate
18156 
18157  type :: tdislotwinmicrostructure
18158  real(preal), dimension(:,:), allocatable :: &
18159  lambda_sl, & !< mean free path between 2 obstacles seen by a moving dislocation
18160  lambda_tw, & !< mean free path between 2 obstacles seen by a growing twin
18161  lambda_tr, & !< mean free path between 2 obstacles seen by a growing martensite
18162  tau_pass, &
18163  tau_hat_tw, &
18164  tau_hat_tr, &
18165  v_tw, & !< volume of a new twin
18166  v_tr, & !< volume of a new martensite disc
18167  tau_r_tw, & !< stress to bring partials close together (twin)
18168  tau_r_tr
18169  end type tdislotwinmicrostructure
18170 
18171 !--------------------------------------------------------------------------------------------------
18172 ! containers for parameters and state
18173  type(tparameters), allocatable, dimension(:) :: param
18174  type(tdislotwinstate), allocatable, dimension(:) :: &
18175  dotstate, &
18176  state
18177  type(tdislotwinmicrostructure), allocatable, dimension(:) :: dependentstate
18178 
18179 contains
18180 
18181 
18182 !--------------------------------------------------------------------------------------------------
18185 !--------------------------------------------------------------------------------------------------
18186 module subroutine plastic_dislotwin_init
18187 
18188  integer :: &
18189  ninstance, &
18190  p, i, &
18191  nipcmyphase, &
18192  sizestate, sizedotstate, &
18193  startindex, endindex
18194  integer, dimension(:), allocatable :: &
18195  n_sl, n_tw, n_tr
18196  real(preal), allocatable, dimension(:) :: &
18197  rho_mob_0, & !< initial unipolar dislocation density per slip system
18198  rho_dip_0
18199  character(len=pStringLen) :: &
18200  extmsg = ''
18201 
18202  write(6,'(/,a)') ' <<<+- constitutive_'//plasticity_dislotwin_label//' init -+>>>'; flush(6)
18203 
18204  write(6,'(/,a)') ' Ma and Roters, Acta Materialia 52(12):3603–3612, 2004'
18205  write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2004.04.012'
18206 
18207  write(6,'(/,a)') ' Roters et al., Computational Materials Science 39:91–95, 2007'
18208  write(6,'(a)') ' https://doi.org/10.1016/j.commatsci.2006.04.014'
18209 
18210  write(6,'(/,a)') ' Wong et al., Acta Materialia 118:140–151, 2016'
18211  write(6,'(a,/)') ' https://doi.org/10.1016/j.actamat.2016.07.032'
18212 
18213  ninstance = count(phase_plasticity == plasticity_dislotwin_id)
18214 
18215  if (iand(debug_level(debug_constitutive),debug_levelbasic) /= 0) &
18216  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
18217 
18218  allocate(param(ninstance))
18219  allocate(state(ninstance))
18220  allocate(dotstate(ninstance))
18221  allocate(dependentstate(ninstance))
18222 
18223  do p = 1, size(phase_plasticity)
18224  if (phase_plasticity(p) /= plasticity_dislotwin_id) cycle
18225  associate(prm => param(phase_plasticityinstance(p)), &
18226  dot => dotstate(phase_plasticityinstance(p)), &
18227  stt => state(phase_plasticityinstance(p)), &
18228  dst => dependentstate(phase_plasticityinstance(p)), &
18229  config => config_phase(p))
18230 
18231  prm%output = config%getStrings('(output)', defaultval=emptystringarray)
18232 
18233  ! This data is read in already in lattice
18234  prm%mu = lattice_mu(p)
18235  prm%nu = lattice_nu(p)
18236  prm%C66 = lattice_c66(1:6,1:6,p)
18237 
18238 !--------------------------------------------------------------------------------------------------
18239 ! slip related parameters
18240  n_sl = config%getInts('nslip',defaultval=emptyintarray)
18241  prm%sum_N_sl = sum(abs(n_sl))
18242  slipactive: if (prm%sum_N_sl > 0) then
18243  prm%P_sl = lattice_schmidmatrix_slip(n_sl,config%getString('lattice_structure'),&
18244  config%getFloat('c/a',defaultval=0.0_preal))
18245  prm%h_sl_sl = lattice_interaction_slipbyslip(n_sl,config%getFloats('interaction_slipslip'), &
18246  config%getString('lattice_structure'))
18247  prm%forestProjection = lattice_forestprojection_edge(n_sl,config%getString('lattice_structure'),&
18248  config%getFloat('c/a',defaultval=0.0_preal))
18249  prm%forestProjection = transpose(prm%forestProjection)
18250 
18251  prm%n0_sl = lattice_slip_normal(n_sl,config%getString('lattice_structure'),&
18252  config%getFloat('c/a',defaultval=0.0_preal))
18253  prm%fccTwinTransNucleation = merge(.true., .false., lattice_structure(p) == lattice_fcc_id) &
18254  .and. (n_sl(1) == 12)
18255  if(prm%fccTwinTransNucleation) prm%fcc_twinNucleationSlipPair = lattice_fcc_twinnucleationslippair
18256 
18257  rho_mob_0 = config%getFloats('rhoedge0', requiredsize=size(n_sl))
18258  rho_dip_0 = config%getFloats('rhoedgedip0',requiredsize=size(n_sl))
18259  prm%v0 = config%getFloats('v0', requiredsize=size(n_sl))
18260  prm%b_sl = config%getFloats('slipburgers',requiredsize=size(n_sl))
18261  prm%Delta_F = config%getFloats('qedge', requiredsize=size(n_sl))
18262  prm%CLambdaSlip = config%getFloats('clambdaslip',requiredsize=size(n_sl))
18263  prm%p = config%getFloats('p_slip', requiredsize=size(n_sl))
18264  prm%q = config%getFloats('q_slip', requiredsize=size(n_sl))
18265  prm%B = config%getFloats('b', requiredsize=size(n_sl), &
18266  defaultval=[(0.0_preal, i=1,size(n_sl))])
18267 
18268  prm%tau_0 = config%getFloat('solidsolutionstrength')
18269  prm%CEdgeDipMinDistance = config%getFloat('cedgedipmindistance')
18270  prm%D0 = config%getFloat('d0')
18271  prm%Qsd = config%getFloat('qsd')
18272  prm%ExtendedDislocations = config%keyExists('/extend_dislocations/')
18273  if (prm%ExtendedDislocations) then
18274  prm%SFE_0K = config%getFloat('sfe_0k')
18275  prm%dSFE_dT = config%getFloat('dsfe_dt')
18276  endif
18277 
18278  prm%dipoleformation = .not. config%keyExists('/nodipoleformation/')
18279 
18280  ! multiplication factor according to crystal structure (nearest neighbors bcc vs fcc/hex)
18281  ! details: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981
18282  prm%omega = config%getFloat('omega', defaultval = 1000.0_preal) &
18283  * merge(12.0_preal,8.0_preal,any(lattice_structure(p) == [lattice_fcc_id,lattice_hex_id]))
18284 
18285  ! expand: family => system
18286  rho_mob_0 = math_expand(rho_mob_0, n_sl)
18287  rho_dip_0 = math_expand(rho_dip_0, n_sl)
18288  prm%v0 = math_expand(prm%v0, n_sl)
18289  prm%b_sl = math_expand(prm%b_sl, n_sl)
18290  prm%Delta_F = math_expand(prm%Delta_F, n_sl)
18291  prm%CLambdaSlip = math_expand(prm%CLambdaSlip, n_sl)
18292  prm%p = math_expand(prm%p, n_sl)
18293  prm%q = math_expand(prm%q, n_sl)
18294  prm%B = math_expand(prm%B, n_sl)
18295 
18296  ! sanity checks
18297  if ( prm%D0 <= 0.0_preal) extmsg = trim(extmsg)//' D0'
18298  if ( prm%Qsd <= 0.0_preal) extmsg = trim(extmsg)//' Qsd'
18299  if (any(rho_mob_0 < 0.0_preal)) extmsg = trim(extmsg)//' rho_mob_0'
18300  if (any(rho_dip_0 < 0.0_preal)) extmsg = trim(extmsg)//' rho_dip_0'
18301  if (any(prm%v0 < 0.0_preal)) extmsg = trim(extmsg)//' v0'
18302  if (any(prm%b_sl <= 0.0_preal)) extmsg = trim(extmsg)//' b_sl'
18303  if (any(prm%Delta_F <= 0.0_preal)) extmsg = trim(extmsg)//' Delta_F'
18304  if (any(prm%CLambdaSlip <= 0.0_preal)) extmsg = trim(extmsg)//' CLambdaSlip'
18305  if (any(prm%B < 0.0_preal)) extmsg = trim(extmsg)//' B'
18306  if (any(prm%p<=0.0_preal .or. prm%p>1.0_preal)) extmsg = trim(extmsg)//' p'
18307  if (any(prm%q< 1.0_preal .or. prm%q>2.0_preal)) extmsg = trim(extmsg)//' q'
18308  else slipactive
18309  rho_mob_0 = emptyrealarray; rho_dip_0 = emptyrealarray
18310  allocate(prm%b_sl,prm%Delta_F,prm%v0,prm%CLambdaSlip,prm%p,prm%q,prm%B,source=emptyrealarray)
18311  allocate(prm%forestProjection(0,0),prm%h_sl_sl(0,0))
18312  endif slipactive
18313 
18314 !--------------------------------------------------------------------------------------------------
18315 ! twin related parameters
18316  n_tw = config%getInts('ntwin', defaultval=emptyintarray)
18317  prm%sum_N_tw = sum(abs(n_tw))
18318  twinactive: if (prm%sum_N_tw > 0) then
18319  prm%P_tw = lattice_schmidmatrix_twin(n_tw,config%getString('lattice_structure'),&
18320  config%getFloat('c/a',defaultval=0.0_preal))
18321  prm%h_tw_tw = lattice_interaction_twinbytwin(n_tw,&
18322  config%getFloats('interaction_twintwin'), &
18323  config%getString('lattice_structure'))
18324 
18325  prm%b_tw = config%getFloats('twinburgers', requiredsize=size(n_tw))
18326  prm%t_tw = config%getFloats('twinsize', requiredsize=size(n_tw))
18327  prm%r = config%getFloats('r_twin', requiredsize=size(n_tw))
18328 
18329  prm%xc_twin = config%getFloat('xc_twin')
18330  prm%L_tw = config%getFloat('l0_twin')
18331  prm%i_tw = config%getFloat('cmfptwin')
18332 
18333  prm%gamma_char= lattice_characteristicshear_twin(n_tw,config%getString('lattice_structure'),&
18334  config%getFloat('c/a',defaultval=0.0_preal))
18335 
18336  prm%C66_tw = lattice_c66_twin(n_tw,prm%C66,config%getString('lattice_structure'),&
18337  config%getFloat('c/a',defaultval=0.0_preal))
18338 
18339  if (.not. prm%fccTwinTransNucleation) then
18340  prm%dot_N_0_tw = config%getFloats('ndot0_twin')
18341  prm%dot_N_0_tw = math_expand(prm%dot_N_0_tw,n_tw)
18342  endif
18343 
18344  ! expand: family => system
18345  prm%b_tw = math_expand(prm%b_tw,n_tw)
18346  prm%t_tw = math_expand(prm%t_tw,n_tw)
18347  prm%r = math_expand(prm%r,n_tw)
18348 
18349  ! sanity checks
18350  if ( prm%xc_twin < 0.0_preal) extmsg = trim(extmsg)//' xc_twin'
18351  if ( prm%L_tw < 0.0_preal) extmsg = trim(extmsg)//' L_tw'
18352  if ( prm%i_tw < 0.0_preal) extmsg = trim(extmsg)//' i_tw'
18353  if (any(prm%b_tw < 0.0_preal)) extmsg = trim(extmsg)//' b_tw'
18354  if (any(prm%t_tw < 0.0_preal)) extmsg = trim(extmsg)//' t_tw'
18355  if (any(prm%r < 0.0_preal)) extmsg = trim(extmsg)//' r'
18356  if (.not. prm%fccTwinTransNucleation) then
18357  if (any(prm%dot_N_0_tw < 0.0_preal)) extmsg = trim(extmsg)//' dot_N_0_tw'
18358  endif
18359  else twinactive
18360  allocate(prm%gamma_char,prm%b_tw,prm%dot_N_0_tw,prm%t_tw,prm%r,source=emptyrealarray)
18361  allocate(prm%h_tw_tw(0,0))
18362  endif twinactive
18363 
18364 !--------------------------------------------------------------------------------------------------
18365 ! transformation related parameters
18366  n_tr = config%getInts('ntrans', defaultval=emptyintarray)
18367  prm%sum_N_tr = sum(abs(n_tr))
18368  transactive: if (prm%sum_N_tr > 0) then
18369  prm%b_tr = config%getFloats('transburgers')
18370  prm%b_tr = math_expand(prm%b_tr,n_tr)
18371 
18372  prm%h = config%getFloat('transstackheight', defaultval=0.0_preal) ! ToDo: How to handle that???
18373  prm%i_tr = config%getFloat('cmfptrans', defaultval=0.0_preal) ! ToDo: How to handle that???
18374  prm%gamma_fcc_hex = config%getFloat('deltag')
18375  prm%xc_trans = config%getFloat('xc_trans', defaultval=0.0_preal) ! ToDo: How to handle that???
18376  prm%L_tr = config%getFloat('l0_trans')
18377 
18378  prm%h_tr_tr = lattice_interaction_transbytrans(n_tr,config%getFloats('interaction_transtrans'), &
18379  config%getString('lattice_structure'))
18380 
18381  prm%C66_tr = lattice_c66_trans(n_tr,prm%C66,config%getString('trans_lattice_structure'), &
18382  0.0_preal, &
18383  config%getFloat('a_bcc', defaultval=0.0_preal), &
18384  config%getFloat('a_fcc', defaultval=0.0_preal))
18385 
18386  prm%P_tr = lattice_schmidmatrix_trans(n_tr,config%getString('trans_lattice_structure'), &
18387  0.0_preal, &
18388  config%getFloat('a_bcc', defaultval=0.0_preal), &
18389  config%getFloat('a_fcc', defaultval=0.0_preal))
18390 
18391  if (lattice_structure(p) /= lattice_fcc_id) then
18392  prm%dot_N_0_tr = config%getFloats('ndot0_trans')
18393  prm%dot_N_0_tr = math_expand(prm%dot_N_0_tr,n_tr)
18394  endif
18395  prm%t_tr = config%getFloats('lamellarsize')
18396  prm%t_tr = math_expand(prm%t_tr,n_tr)
18397  prm%s = config%getFloats('s_trans',defaultval=[0.0_preal])
18398  prm%s = math_expand(prm%s,n_tr)
18399 
18400  ! sanity checks
18401  if ( prm%xc_trans < 0.0_preal) extmsg = trim(extmsg)//' xc_trans'
18402  if ( prm%L_tr < 0.0_preal) extmsg = trim(extmsg)//' L_tr'
18403  if ( prm%i_tr < 0.0_preal) extmsg = trim(extmsg)//' i_tr'
18404  if (any(prm%t_tr < 0.0_preal)) extmsg = trim(extmsg)//' t_tr'
18405  if (any(prm%s < 0.0_preal)) extmsg = trim(extmsg)//' s'
18406  if (lattice_structure(p) /= lattice_fcc_id) then
18407  if (any(prm%dot_N_0_tr < 0.0_preal)) extmsg = trim(extmsg)//' dot_N_0_tr'
18408  endif
18409  else transactive
18410  allocate(prm%s,prm%b_tr,prm%t_tr,prm%dot_N_0_tr,source=emptyrealarray)
18411  allocate(prm%h_tr_tr(0,0))
18412  endif transactive
18413 
18414 !--------------------------------------------------------------------------------------------------
18415 ! shearband related parameters
18416  prm%sbVelocity = config%getFloat('shearbandvelocity',defaultval=0.0_preal)
18417  if (prm%sbVelocity > 0.0_preal) then
18418  prm%sbResistance = config%getFloat('shearbandresistance')
18419  prm%E_sb = config%getFloat('qedgepersbsystem')
18420  prm%p_sb = config%getFloat('p_shearband')
18421  prm%q_sb = config%getFloat('q_shearband')
18422 
18423  ! sanity checks
18424  if (prm%sbResistance < 0.0_preal) extmsg = trim(extmsg)//' shearbandresistance'
18425  if (prm%E_sb < 0.0_preal) extmsg = trim(extmsg)//' qedgepersbsystem'
18426  if (prm%p_sb <= 0.0_preal) extmsg = trim(extmsg)//' p_shearband'
18427  if (prm%q_sb <= 0.0_preal) extmsg = trim(extmsg)//' q_shearband'
18428  endif
18429 
18430 !--------------------------------------------------------------------------------------------------
18431 ! parameters required for several mechanisms and their interactions
18432  if(prm%sum_N_sl + prm%sum_N_tw + prm%sum_N_tw > 0) &
18433  prm%D = config%getFloat('grainsize')
18434 
18435  twinorslipactive: if (prm%sum_N_tw + prm%sum_N_tr > 0) then
18436  prm%SFE_0K = config%getFloat('sfe_0k')
18437  prm%dSFE_dT = config%getFloat('dsfe_dt')
18438  prm%V_cs = config%getFloat('vcrossslip')
18439  endif twinorslipactive
18440 
18441  slipandtwinactive: if (prm%sum_N_sl * prm%sum_N_tw > 0) then
18442  prm%h_sl_tw = lattice_interaction_slipbytwin(n_sl,n_tw,&
18443  config%getFloats('interaction_sliptwin'), &
18444  config%getString('lattice_structure'))
18445  if (prm%fccTwinTransNucleation .and. size(n_tw) /= 1) extmsg = trim(extmsg)//' interaction_sliptwin'
18446  endif slipandtwinactive
18447 
18448  slipandtransactive: if (prm%sum_N_sl * prm%sum_N_tr > 0) then
18449  prm%h_sl_tr = lattice_interaction_slipbytrans(n_sl,n_tr,&
18450  config%getFloats('interaction_sliptrans'), &
18451  config%getString('lattice_structure'))
18452  if (prm%fccTwinTransNucleation .and. size(n_tr) /= 1) extmsg = trim(extmsg)//' interaction_sliptrans'
18453  endif slipandtransactive
18454 
18455 !--------------------------------------------------------------------------------------------------
18456 ! allocate state arrays
18457  nipcmyphase = count(material_phaseat == p) * discretization_nip
18458  sizedotstate = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl &
18459  + size(['f_tw']) * prm%sum_N_tw &
18460  + size(['f_tr']) * prm%sum_N_tr
18461  sizestate = sizedotstate
18462 
18463  call material_allocateplasticstate(p,nipcmyphase,sizestate,sizedotstate,0)
18464 
18465 !--------------------------------------------------------------------------------------------------
18466 ! locally defined state aliases and initialization of state0 and atol
18467  startindex = 1
18468  endindex = prm%sum_N_sl
18469  stt%rho_mob=>plasticstate(p)%state(startindex:endindex,:)
18470  stt%rho_mob= spread(rho_mob_0,2,nipcmyphase)
18471  dot%rho_mob=>plasticstate(p)%dotState(startindex:endindex,:)
18472  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_rho',defaultval=1.0_preal)
18473  if (any(plasticstate(p)%atol(startindex:endindex) < 0.0_preal)) extmsg = trim(extmsg)//' atol_rho'
18474 
18475  startindex = endindex + 1
18476  endindex = endindex + prm%sum_N_sl
18477  stt%rho_dip=>plasticstate(p)%state(startindex:endindex,:)
18478  stt%rho_dip= spread(rho_dip_0,2,nipcmyphase)
18479  dot%rho_dip=>plasticstate(p)%dotState(startindex:endindex,:)
18480  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_rho',defaultval=1.0_preal)
18481 
18482  startindex = endindex + 1
18483  endindex = endindex + prm%sum_N_sl
18484  stt%gamma_sl=>plasticstate(p)%state(startindex:endindex,:)
18485  dot%gamma_sl=>plasticstate(p)%dotState(startindex:endindex,:)
18486  plasticstate(p)%atol(startindex:endindex) = 1.0e-2_preal
18487  ! global alias
18488  plasticstate(p)%slipRate => plasticstate(p)%dotState(startindex:endindex,:)
18489 
18490  startindex = endindex + 1
18491  endindex = endindex + prm%sum_N_tw
18492  stt%f_tw=>plasticstate(p)%state(startindex:endindex,:)
18493  dot%f_tw=>plasticstate(p)%dotState(startindex:endindex,:)
18494  plasticstate(p)%atol(startindex:endindex) = config%getFloat('f_twin',defaultval=1.0e-7_preal)
18495  if (any(plasticstate(p)%atol(startindex:endindex) < 0.0_preal)) extmsg = trim(extmsg)//' f_twin'
18496 
18497  startindex = endindex + 1
18498  endindex = endindex + prm%sum_N_tr
18499  stt%f_tr=>plasticstate(p)%state(startindex:endindex,:)
18500  dot%f_tr=>plasticstate(p)%dotState(startindex:endindex,:)
18501  plasticstate(p)%atol(startindex:endindex) = config%getFloat('f_trans',defaultval=1.0e-6_preal)
18502  if (any(plasticstate(p)%atol(startindex:endindex) < 0.0_preal)) extmsg = trim(extmsg)//' f_trans'
18503 
18504  allocate(dst%Lambda_sl (prm%sum_N_sl,nipcmyphase),source=0.0_preal)
18505  allocate(dst%tau_pass (prm%sum_N_sl,nipcmyphase),source=0.0_preal)
18506 
18507  allocate(dst%Lambda_tw (prm%sum_N_tw,nipcmyphase),source=0.0_preal)
18508  allocate(dst%tau_hat_tw (prm%sum_N_tw,nipcmyphase),source=0.0_preal)
18509  allocate(dst%tau_r_tw (prm%sum_N_tw,nipcmyphase),source=0.0_preal)
18510  allocate(dst%V_tw (prm%sum_N_tw,nipcmyphase),source=0.0_preal)
18511 
18512  allocate(dst%Lambda_tr (prm%sum_N_tr,nipcmyphase),source=0.0_preal)
18513  allocate(dst%tau_hat_tr (prm%sum_N_tr,nipcmyphase),source=0.0_preal)
18514  allocate(dst%tau_r_tr (prm%sum_N_tr,nipcmyphase),source=0.0_preal)
18515  allocate(dst%V_tr (prm%sum_N_tr,nipcmyphase),source=0.0_preal)
18516 
18517  plasticstate(p)%state0 = plasticstate(p)%state ! ToDo: this could be done centrally
18518 
18519  end associate
18520 
18521 !--------------------------------------------------------------------------------------------------
18522 ! exit if any parameter is out of range
18523  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//plasticity_dislotwin_label//')')
18524 
18525  enddo
18526 
18527 end subroutine plastic_dislotwin_init
18528 
18529 
18530 !--------------------------------------------------------------------------------------------------
18532 !--------------------------------------------------------------------------------------------------
18533 module function plastic_dislotwin_homogenizedc(ipc,ip,el) result(homogenizedc)
18534 
18535  real(preal), dimension(6,6) :: &
18536  homogenizedc
18537  integer, intent(in) :: &
18538  ipc, & !< component-ID of integration point
18539  ip, & !< integration point
18540  el
18541 
18542  integer :: i, &
18543  of
18544  real(preal) :: f_unrotated
18545 
18546  of = material_phasememberat(ipc,ip,el)
18547  associate(prm => param(phase_plasticityinstance(material_phaseat(ipc,el))),&
18548  stt => state(phase_plasticityinstance(material_phaseat(ipc,el))))
18549 
18550  f_unrotated = 1.0_preal &
18551  - sum(stt%f_tw(1:prm%sum_N_tw,of)) &
18552  - sum(stt%f_tr(1:prm%sum_N_tr,of))
18553 
18554  homogenizedc = f_unrotated * prm%C66
18555  do i=1,prm%sum_N_tw
18556  homogenizedc = homogenizedc &
18557  + stt%f_tw(i,of)*prm%C66_tw(1:6,1:6,i)
18558  enddo
18559  do i=1,prm%sum_N_tr
18560  homogenizedc = homogenizedc &
18561  + stt%f_tr(i,of)*prm%C66_tr(1:6,1:6,i)
18562  enddo
18563 
18564  end associate
18565 
18566 end function plastic_dislotwin_homogenizedc
18567 
18568 
18569 !--------------------------------------------------------------------------------------------------
18571 !--------------------------------------------------------------------------------------------------
18572 module subroutine plastic_dislotwin_lpanditstangent(lp,dlp_dmp,mp,t,instance,of)
18573 
18574  real(preal), dimension(3,3), intent(out) :: lp
18575  real(preal), dimension(3,3,3,3), intent(out) :: dlp_dmp
18576  real(preal), dimension(3,3), intent(in) :: mp
18577  integer, intent(in) :: instance,of
18578  real(preal), intent(in) :: t
18579 
18580  integer :: i,k,l,m,n
18581  real(preal) :: &
18582  f_unrotated,stressratio_p,&
18583  boltzmannratio, &
18584  ddot_gamma_dtau, &
18585  tau
18586  real(preal), dimension(param(instance)%sum_N_sl) :: &
18587  dot_gamma_sl,ddot_gamma_dtau_slip
18588  real(preal), dimension(param(instance)%sum_N_tw) :: &
18589  dot_gamma_twin,ddot_gamma_dtau_twin
18590  real(preal), dimension(param(instance)%sum_N_tr) :: &
18591  dot_gamma_tr,ddot_gamma_dtau_trans
18592  real(preal):: dot_gamma_sb
18593  real(preal), dimension(3,3) :: eigvectors, p_sb
18594  real(preal), dimension(3) :: eigvalues
18595  real(preal), dimension(3,6), parameter :: &
18596  sb_scomposition = &
18597  reshape(real([&
18598  1, 0, 1, &
18599  1, 0,-1, &
18600  1, 1, 0, &
18601  1,-1, 0, &
18602  0, 1, 1, &
18603  0, 1,-1 &
18604  ],preal),[ 3,6]), &
18605  sb_mcomposition = &
18606  reshape(real([&
18607  1, 0,-1, &
18608  1, 0,+1, &
18609  1,-1, 0, &
18610  1, 1, 0, &
18611  0, 1,-1, &
18612  0, 1, 1 &
18613  ],preal),[ 3,6])
18614 
18615  associate(prm => param(instance), stt => state(instance))
18616 
18617  f_unrotated = 1.0_preal &
18618  - sum(stt%f_tw(1:prm%sum_N_tw,of)) &
18619  - sum(stt%f_tr(1:prm%sum_N_tr,of))
18620 
18621  lp = 0.0_preal
18622  dlp_dmp = 0.0_preal
18623 
18624  call kinetics_slip(mp,t,instance,of,dot_gamma_sl,ddot_gamma_dtau_slip)
18625  slipcontribution: do i = 1, prm%sum_N_sl
18626  lp = lp + dot_gamma_sl(i)*prm%P_sl(1:3,1:3,i)
18627  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
18628  dlp_dmp(k,l,m,n) = dlp_dmp(k,l,m,n) &
18629  + ddot_gamma_dtau_slip(i) * prm%P_sl(k,l,i) * prm%P_sl(m,n,i)
18630  enddo slipcontribution
18631 
18632  !ToDo: Why do this before shear banding?
18633  lp = lp * f_unrotated
18634  dlp_dmp = dlp_dmp * f_unrotated
18635 
18636  shearbandingcontribution: if(dneq0(prm%sbVelocity)) then
18637 
18638  boltzmannratio = prm%E_sb/(kb*t)
18639  call math_eigh33(mp,eigvalues,eigvectors) ! is Mp symmetric by design?
18640 
18641  do i = 1,6
18642  p_sb = 0.5_preal * math_outer(matmul(eigvectors,sb_scomposition(1:3,i)),&
18643  matmul(eigvectors,sb_mcomposition(1:3,i)))
18644  tau = math_tensordot(mp,p_sb)
18645 
18646  significantshearbandstress: if (abs(tau) > tol_math_check) then
18647  stressratio_p = (abs(tau)/prm%sbResistance)**prm%p_sb
18648  dot_gamma_sb = sign(prm%sbVelocity*exp(-boltzmannratio*(1-stressratio_p)**prm%q_sb), tau)
18649  ddot_gamma_dtau = abs(dot_gamma_sb)*boltzmannratio* prm%p_sb*prm%q_sb/ prm%sbResistance &
18650  * (abs(tau)/prm%sbResistance)**(prm%p_sb-1.0_preal) &
18651  * (1.0_preal-stressratio_p)**(prm%q_sb-1.0_preal)
18652 
18653  lp = lp + dot_gamma_sb * p_sb
18654  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
18655  dlp_dmp(k,l,m,n) = dlp_dmp(k,l,m,n) &
18656  + ddot_gamma_dtau * p_sb(k,l) * p_sb(m,n)
18657  endif significantshearbandstress
18658  enddo
18659 
18660  endif shearbandingcontribution
18661 
18662  call kinetics_twin(mp,t,dot_gamma_sl,instance,of,dot_gamma_twin,ddot_gamma_dtau_twin)
18663  twincontibution: do i = 1, prm%sum_N_tw
18664  lp = lp + dot_gamma_twin(i)*prm%P_tw(1:3,1:3,i) * f_unrotated
18665  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
18666  dlp_dmp(k,l,m,n) = dlp_dmp(k,l,m,n) &
18667  + ddot_gamma_dtau_twin(i)* prm%P_tw(k,l,i)*prm%P_tw(m,n,i) * f_unrotated
18668  enddo twincontibution
18669 
18670  call kinetics_trans(mp,t,dot_gamma_sl,instance,of,dot_gamma_tr,ddot_gamma_dtau_trans)
18671  transcontibution: do i = 1, prm%sum_N_tr
18672  lp = lp + dot_gamma_tr(i)*prm%P_tr(1:3,1:3,i) * f_unrotated
18673  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
18674  dlp_dmp(k,l,m,n) = dlp_dmp(k,l,m,n) &
18675  + ddot_gamma_dtau_trans(i)* prm%P_tr(k,l,i)*prm%P_tr(m,n,i) * f_unrotated
18676  enddo transcontibution
18677 
18678 
18679  end associate
18680 
18681 end subroutine plastic_dislotwin_lpanditstangent
18682 
18683 
18684 !--------------------------------------------------------------------------------------------------
18686 !--------------------------------------------------------------------------------------------------
18687 module subroutine plastic_dislotwin_dotstate(mp,t,instance,of)
18688 
18689  real(preal), dimension(3,3), intent(in):: &
18690  mp
18691  real(preal), intent(in) :: &
18692  t
18693  integer, intent(in) :: &
18694  instance, &
18695  of
18696 
18697  integer :: i
18698  real(preal) :: &
18699  f_unrotated, &
18700  rho_dip_distance, &
18701  v_cl, & !< climb velocity
18702  gamma, & !< stacking fault energy
18703  tau, &
18704  sigma_cl, & !< climb stress
18705  b_d
18706  real(preal), dimension(param(instance)%sum_N_sl) :: &
18707  dot_rho_dip_formation, &
18708  dot_rho_dip_climb, &
18709  rho_dip_distance_min, &
18710  dot_gamma_sl
18711  real(preal), dimension(param(instance)%sum_N_tw) :: &
18712  dot_gamma_twin
18713  real(preal), dimension(param(instance)%sum_N_tr) :: &
18714  dot_gamma_tr
18715 
18716  associate(prm => param(instance), stt => state(instance), &
18717  dot => dotstate(instance), dst => dependentstate(instance))
18718 
18719  f_unrotated = 1.0_preal &
18720  - sum(stt%f_tw(1:prm%sum_N_tw,of)) &
18721  - sum(stt%f_tr(1:prm%sum_N_tr,of))
18722 
18723  call kinetics_slip(mp,t,instance,of,dot_gamma_sl)
18724  dot%gamma_sl(:,of) = abs(dot_gamma_sl)
18725 
18726  rho_dip_distance_min = prm%CEdgeDipMinDistance*prm%b_sl
18727 
18728  slipstate: do i = 1, prm%sum_N_sl
18729  tau = math_tensordot(mp,prm%P_sl(1:3,1:3,i))
18730 
18731  significantslipstress: if (deq0(tau)) then
18732  dot_rho_dip_formation(i) = 0.0_preal
18733  dot_rho_dip_climb(i) = 0.0_preal
18734  else significantslipstress
18735  rho_dip_distance = 3.0_preal*prm%mu*prm%b_sl(i)/(16.0_preal*pi*abs(tau))
18736  rho_dip_distance = math_clip(rho_dip_distance, right = dst%Lambda_sl(i,of))
18737  rho_dip_distance = math_clip(rho_dip_distance, left = rho_dip_distance_min(i))
18738 
18739  if (prm%dipoleFormation) then
18740  dot_rho_dip_formation(i) = 2.0_preal*(rho_dip_distance-rho_dip_distance_min(i))/prm%b_sl(i) &
18741  * stt%rho_mob(i,of)*abs(dot_gamma_sl(i))
18742  else
18743  dot_rho_dip_formation(i) = 0.0_preal
18744  endif
18745 
18746  if (deq(rho_dip_distance,rho_dip_distance_min(i))) then
18747  dot_rho_dip_climb(i) = 0.0_preal
18748  else
18749  !@details: Refer: Argon & Moffat, Acta Metallurgica, Vol. 29, pg 293 to 299, 1981
18750  sigma_cl = dot_product(prm%n0_sl(1:3,i),matmul(mp,prm%n0_sl(1:3,i)))
18751  if (prm%ExtendedDislocations) then
18752  gamma = prm%SFE_0K + prm%dSFE_dT * t
18753  b_d = 24.0_preal*pi*(1.0_preal - prm%nu)/(2.0_preal + prm%nu)* gamma/(prm%mu*prm%b_sl(i))
18754  else
18755  b_d = 1.0_preal
18756  endif
18757  v_cl = 2.0_preal*prm%omega*b_d**2.0_preal*exp(-prm%Qsd/(kb*t)) &
18758  * (exp(abs(sigma_cl)*prm%b_sl(i)**3.0_preal/(kb*t)) - 1.0_preal)
18759 
18760  dot_rho_dip_climb(i) = 4.0_preal*v_cl*stt%rho_dip(i,of) &
18761  / (rho_dip_distance-rho_dip_distance_min(i))
18762  endif
18763  endif significantslipstress
18764  enddo slipstate
18765 
18766  dot%rho_mob(:,of) = abs(dot_gamma_sl)/(prm%b_sl*dst%Lambda_sl(:,of)) &
18767  - dot_rho_dip_formation &
18768  - 2.0_preal*rho_dip_distance_min/prm%b_sl * stt%rho_mob(:,of)*abs(dot_gamma_sl)
18769 
18770  dot%rho_dip(:,of) = dot_rho_dip_formation &
18771  - 2.0_preal*rho_dip_distance_min/prm%b_sl * stt%rho_dip(:,of)*abs(dot_gamma_sl) &
18772  - dot_rho_dip_climb
18773 
18774  call kinetics_twin(mp,t,dot_gamma_sl,instance,of,dot_gamma_twin)
18775  dot%f_tw(:,of) = f_unrotated*dot_gamma_twin/prm%gamma_char
18776 
18777  call kinetics_trans(mp,t,dot_gamma_sl,instance,of,dot_gamma_tr)
18778  dot%f_tr(:,of) = f_unrotated*dot_gamma_tr
18779 
18780  end associate
18781 
18782 end subroutine plastic_dislotwin_dotstate
18783 
18784 
18785 !--------------------------------------------------------------------------------------------------
18787 !--------------------------------------------------------------------------------------------------
18788 module subroutine plastic_dislotwin_dependentstate(t,instance,of)
18789 
18790  integer, intent(in) :: &
18791  instance, &
18792  of
18793  real(preal), intent(in) :: &
18794  t
18795 
18796  real(preal) :: &
18797  sumf_twin,gamma,sumf_trans
18798  real(preal), dimension(param(instance)%sum_N_sl) :: &
18799  inv_lambda_sl_sl, & !< 1/mean free distance between 2 forest dislocations seen by a moving dislocation
18800  inv_lambda_sl_tw, & !< 1/mean free distance between 2 twin stacks from different systems seen by a moving dislocation
18801  inv_lambda_sl_tr
18802  real(preal), dimension(param(instance)%sum_N_tw) :: &
18803  inv_lambda_tw_tw, & !< 1/mean free distance between 2 twin stacks from different systems seen by a growing twin
18804  f_over_t_tw
18805  real(preal), dimension(param(instance)%sum_N_tr) :: &
18806  inv_lambda_tr_tr, & !< 1/mean free distance between 2 martensite stacks from different systems seen by a growing martensite
18807  f_over_t_tr
18808  real(preal), dimension(:), allocatable :: &
18809  x0
18810 
18811 
18812  associate(prm => param(instance),&
18813  stt => state(instance),&
18814  dst => dependentstate(instance))
18815 
18816  sumf_twin = sum(stt%f_tw(1:prm%sum_N_tw,of))
18817  sumf_trans = sum(stt%f_tr(1:prm%sum_N_tr,of))
18818 
18819  gamma = prm%SFE_0K + prm%dSFE_dT * t
18820 
18821  !* rescaled volume fraction for topology
18822  f_over_t_tw = stt%f_tw(1:prm%sum_N_tw,of)/prm%t_tw ! this is per system ...
18823  f_over_t_tr = sumf_trans/prm%t_tr ! but this not
18824  ! ToDo ...Physically correct, but naming could be adjusted
18825 
18826  inv_lambda_sl_sl = sqrt(matmul(prm%forestProjection, &
18827  stt%rho_mob(:,of)+stt%rho_dip(:,of)))/prm%CLambdaSlip
18828 
18829  if (prm%sum_N_tw > 0 .and. prm%sum_N_sl > 0) &
18830  inv_lambda_sl_tw = matmul(prm%h_sl_tw,f_over_t_tw)/(1.0_preal-sumf_twin)
18831 
18832  inv_lambda_tw_tw = matmul(prm%h_tw_tw,f_over_t_tw)/(1.0_preal-sumf_twin)
18833 
18834  if (prm%sum_N_tr > 0 .and. prm%sum_N_sl > 0) &
18835  inv_lambda_sl_tr = matmul(prm%h_sl_tr,f_over_t_tr)/(1.0_preal-sumf_trans)
18836 
18837  inv_lambda_tr_tr = matmul(prm%h_tr_tr,f_over_t_tr)/(1.0_preal-sumf_trans)
18838 
18839  if ((prm%sum_N_tw > 0) .or. (prm%sum_N_tr > 0)) then ! ToDo: better logic needed here
18840  dst%Lambda_sl(:,of) = prm%D &
18841  / (1.0_preal+prm%D*(inv_lambda_sl_sl + inv_lambda_sl_tw + inv_lambda_sl_tr))
18842  else
18843  dst%Lambda_sl(:,of) = prm%D &
18844  / (1.0_preal+prm%D*inv_lambda_sl_sl) !!!!!! correct?
18845  endif
18846 
18847  dst%Lambda_tw(:,of) = prm%i_tw*prm%D/(1.0_preal+prm%D*inv_lambda_tw_tw)
18848  dst%Lambda_tr(:,of) = prm%i_tr*prm%D/(1.0_preal+prm%D*inv_lambda_tr_tr)
18849 
18850  !* threshold stress for dislocation motion
18851  dst%tau_pass(:,of) = prm%mu*prm%b_sl* sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of)))
18852 
18853  !* threshold stress for growing twin/martensite
18854  if(prm%sum_N_tw == prm%sum_N_sl) &
18855  dst%tau_hat_tw(:,of) = gamma/(3.0_preal*prm%b_tw) &
18856  + 3.0_preal*prm%b_tw*prm%mu/(prm%L_tw*prm%b_sl) ! slip burgers here correct?
18857  if(prm%sum_N_tr == prm%sum_N_sl) &
18858  dst%tau_hat_tr(:,of) = gamma/(3.0_preal*prm%b_tr) &
18859  + 3.0_preal*prm%b_tr*prm%mu/(prm%L_tr*prm%b_sl) & ! slip burgers here correct?
18860  + prm%h*prm%gamma_fcc_hex/ (3.0_preal*prm%b_tr)
18861 
18862  dst%V_tw(:,of) = (pi/4.0_preal)*prm%t_tw*dst%Lambda_tw(:,of)**2.0_preal
18863  dst%V_tr(:,of) = (pi/4.0_preal)*prm%t_tr*dst%Lambda_tr(:,of)**2.0_preal
18864 
18865 
18866  x0 = prm%mu*prm%b_tw**2.0_preal/(gamma*8.0_preal*pi)*(2.0_preal+prm%nu)/(1.0_preal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip and is the same for twin and trans
18867  dst%tau_r_tw(:,of) = prm%mu*prm%b_tw/(2.0_preal*pi)*(1.0_preal/(x0+prm%xc_twin)+cos(pi/3.0_preal)/x0)
18868 
18869  x0 = prm%mu*prm%b_tr**2.0_preal/(gamma*8.0_preal*pi)*(2.0_preal+prm%nu)/(1.0_preal-prm%nu) ! ToDo: In the paper, this is the burgers vector for slip
18870  dst%tau_r_tr(:,of) = prm%mu*prm%b_tr/(2.0_preal*pi)*(1.0_preal/(x0+prm%xc_trans)+cos(pi/3.0_preal)/x0)
18871 
18872  end associate
18873 
18874 end subroutine plastic_dislotwin_dependentstate
18875 
18876 
18877 !--------------------------------------------------------------------------------------------------
18879 !--------------------------------------------------------------------------------------------------
18880 module subroutine plastic_dislotwin_results(instance,group)
18881 
18882  integer, intent(in) :: instance
18883  character(len=*), intent(in) :: group
18884 
18885  integer :: o
18886 
18887  associate(prm => param(instance), stt => state(instance), dst => dependentstate(instance))
18888  outputsloop: do o = 1,size(prm%output)
18889  select case(trim(prm%output(o)))
18890 
18891  case('rho_mob')
18892  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_mob,'rho_mob',&
18893  'mobile dislocation density','1/m²')
18894  case('rho_dip')
18895  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_dip,'rho_dip',&
18896  'dislocation dipole density''1/m²')
18897  case('gamma_sl')
18898  if(prm%sum_N_sl>0) call results_writedataset(group,stt%gamma_sl,'gamma_sl',&
18899  'plastic shear','1')
18900  case('lambda_sl')
18901  if(prm%sum_N_sl>0) call results_writedataset(group,dst%Lambda_sl,'Lambda_sl',&
18902  'mean free path for slip','m')
18903  case('tau_pass')
18904  if(prm%sum_N_sl>0) call results_writedataset(group,dst%tau_pass,'tau_pass',&
18905  'passing stress for slip','Pa')
18906 
18907  case('f_tw')
18908  if(prm%sum_N_tw>0) call results_writedataset(group,stt%f_tw,'f_tw',&
18909  'twinned volume fraction','m³/m³')
18910  case('lambda_tw')
18911  if(prm%sum_N_tw>0) call results_writedataset(group,dst%Lambda_tw,'Lambda_tw',&
18912  'mean free path for twinning','m')
18913  case('tau_hat_tw')
18914  if(prm%sum_N_tw>0) call results_writedataset(group,dst%tau_hat_tw,'tau_hat_tw',&
18915  'threshold stress for twinning','Pa')
18916 
18917  case('f_tr')
18918  if(prm%sum_N_tr>0) call results_writedataset(group,stt%f_tr,'f_tr',&
18919  'martensite volume fraction','m³/m³')
18920 
18921  end select
18922  enddo outputsloop
18923  end associate
18924 
18925 end subroutine plastic_dislotwin_results
18926 
18927 
18928 !--------------------------------------------------------------------------------------------------
18930 ! stress, and the resolved stress.
18932 ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
18933 ! have the optional arguments at the end
18934 !--------------------------------------------------------------------------------------------------
18935 pure subroutine kinetics_slip(Mp,T,instance,of, &
18936  dot_gamma_sl,ddot_gamma_dtau_slip,tau_slip)
18938  real(preal), dimension(3,3), intent(in) :: &
18939  mp
18940  real(preal), intent(in) :: &
18941  t
18942  integer, intent(in) :: &
18943  instance, &
18944  of
18945 
18946  real(preal), dimension(param(instance)%sum_N_sl), intent(out) :: &
18947  dot_gamma_sl
18948  real(preal), dimension(param(instance)%sum_N_sl), optional, intent(out) :: &
18949  ddot_gamma_dtau_slip, &
18950  tau_slip
18951  real(preal), dimension(param(instance)%sum_N_sl) :: &
18952  ddot_gamma_dtau
18953 
18954  real(preal), dimension(param(instance)%sum_N_sl) :: &
18955  tau, &
18956  stressratio, &
18957  stressratio_p, &
18958  boltzmannratio, &
18959  v_wait_inverse, & !< inverse of the effective velocity of a dislocation waiting at obstacles (unsigned)
18960  v_run_inverse, & !< inverse of the velocity of a free moving dislocation (unsigned)
18961  dv_wait_inverse_dtau, &
18962  dv_run_inverse_dtau, &
18963  dv_dtau, &
18964  tau_eff
18965  integer :: i
18966 
18967  associate(prm => param(instance), stt => state(instance), dst => dependentstate(instance))
18968 
18969  do i = 1, prm%sum_N_sl
18970  tau(i) = math_tensordot(mp,prm%P_sl(1:3,1:3,i))
18971  enddo
18972 
18973  tau_eff = abs(tau)-dst%tau_pass(:,of)
18974 
18975  significantstress: where(tau_eff > tol_math_check)
18976  stressratio = tau_eff/prm%tau_0
18977  stressratio_p = stressratio** prm%p
18978  boltzmannratio = prm%Delta_F/(kb*t)
18979  v_wait_inverse = prm%v0**(-1.0_preal) * exp(boltzmannratio*(1.0_preal-stressratio_p)** prm%q)
18980  v_run_inverse = prm%B/(tau_eff*prm%b_sl)
18981 
18982  dot_gamma_sl = sign(stt%rho_mob(:,of)*prm%b_sl/(v_wait_inverse+v_run_inverse),tau)
18983 
18984  dv_wait_inverse_dtau = -1.0_preal * v_wait_inverse * prm%p * prm%q * boltzmannratio &
18985  * (stressratio**(prm%p-1.0_preal)) &
18986  * (1.0_preal-stressratio_p)**(prm%q-1.0_preal) &
18987  / prm%tau_0
18988  dv_run_inverse_dtau = -1.0_preal * v_run_inverse/tau_eff
18989  dv_dtau = -1.0_preal * (dv_wait_inverse_dtau+dv_run_inverse_dtau) &
18990  / (v_wait_inverse+v_run_inverse)**2.0_preal
18991  ddot_gamma_dtau = dv_dtau*stt%rho_mob(:,of)*prm%b_sl
18992  else where significantstress
18993  dot_gamma_sl = 0.0_preal
18994  ddot_gamma_dtau = 0.0_preal
18995  end where significantstress
18996 
18997  end associate
18998 
18999  if(present(ddot_gamma_dtau_slip)) ddot_gamma_dtau_slip = ddot_gamma_dtau
19000  if(present(tau_slip)) tau_slip = tau
19001 
19002 end subroutine kinetics_slip
19003 
19004 
19005 !--------------------------------------------------------------------------------------------------
19007 ! stress.
19009 ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
19010 ! have the optional arguments at the end.
19011 !--------------------------------------------------------------------------------------------------
19012 pure subroutine kinetics_twin(Mp,T,dot_gamma_sl,instance,of,&
19013  dot_gamma_twin,ddot_gamma_dtau_twin)
19015  real(preal), dimension(3,3), intent(in) :: &
19016  mp
19017  real(preal), intent(in) :: &
19018  t
19019  integer, intent(in) :: &
19020  instance, &
19021  of
19022  real(preal), dimension(param(instance)%sum_N_sl), intent(in) :: &
19023  dot_gamma_sl
19024 
19025  real(preal), dimension(param(instance)%sum_N_tw), intent(out) :: &
19026  dot_gamma_twin
19027  real(preal), dimension(param(instance)%sum_N_tw), optional, intent(out) :: &
19028  ddot_gamma_dtau_twin
19029 
19030  real, dimension(param(instance)%sum_N_tw) :: &
19031  tau, &
19032  ndot0, &
19033  stressratio_r, &
19034  ddot_gamma_dtau
19035 
19036  integer :: i,s1,s2
19037 
19038  associate(prm => param(instance), stt => state(instance), dst => dependentstate(instance))
19039 
19040  do i = 1, prm%sum_N_tw
19041  tau(i) = math_tensordot(mp,prm%P_tw(1:3,1:3,i))
19042  isfcc: if (prm%fccTwinTransNucleation) then
19043  s1=prm%fcc_twinNucleationSlipPair(1,i)
19044  s2=prm%fcc_twinNucleationSlipPair(2,i)
19045  if (tau(i) < dst%tau_r_tw(i,of)) then ! ToDo: correct?
19046  ndot0=(abs(dot_gamma_sl(s1))*(stt%rho_mob(s2,of)+stt%rho_dip(s2,of))+&
19047  abs(dot_gamma_sl(s2))*(stt%rho_mob(s1,of)+stt%rho_dip(s1,of)))/& ! ToDo: MD: it would be more consistent to use shearrates from state
19048  (prm%L_tw*prm%b_sl(i))*&
19049  (1.0_preal-exp(-prm%V_cs/(kb*t)*(dst%tau_r_tw(i,of)-tau(i)))) ! P_ncs
19050  else
19051  ndot0=0.0_preal
19052  end if
19053  else isfcc
19054  ndot0=prm%dot_N_0_tw(i)
19055  endif isfcc
19056  enddo
19057 
19058  significantstress: where(tau > tol_math_check)
19059  stressratio_r = (dst%tau_hat_tw(:,of)/tau)**prm%r
19060  dot_gamma_twin = prm%gamma_char * dst%V_tw(:,of) * ndot0*exp(-stressratio_r)
19061  ddot_gamma_dtau = (dot_gamma_twin*prm%r/tau)*stressratio_r
19062  else where significantstress
19063  dot_gamma_twin = 0.0_preal
19064  ddot_gamma_dtau = 0.0_preal
19065  end where significantstress
19066 
19067  end associate
19068 
19069  if(present(ddot_gamma_dtau_twin)) ddot_gamma_dtau_twin = ddot_gamma_dtau
19070 
19071 end subroutine kinetics_twin
19072 
19073 
19074 !--------------------------------------------------------------------------------------------------
19076 ! resolved stress.
19078 ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
19079 ! have the optional arguments at the end.
19080 !--------------------------------------------------------------------------------------------------
19081 pure subroutine kinetics_trans(Mp,T,dot_gamma_sl,instance,of,&
19082  dot_gamma_tr,ddot_gamma_dtau_trans)
19084  real(preal), dimension(3,3), intent(in) :: &
19085  mp
19086  real(preal), intent(in) :: &
19087  t
19088  integer, intent(in) :: &
19089  instance, &
19090  of
19091  real(preal), dimension(param(instance)%sum_N_sl), intent(in) :: &
19092  dot_gamma_sl
19093 
19094  real(preal), dimension(param(instance)%sum_N_tr), intent(out) :: &
19095  dot_gamma_tr
19096  real(preal), dimension(param(instance)%sum_N_tr), optional, intent(out) :: &
19097  ddot_gamma_dtau_trans
19098 
19099  real, dimension(param(instance)%sum_N_tr) :: &
19100  tau, &
19101  ndot0, &
19102  stressratio_s, &
19103  ddot_gamma_dtau
19104 
19105  integer :: i,s1,s2
19106  associate(prm => param(instance), stt => state(instance), dst => dependentstate(instance))
19107 
19108  do i = 1, prm%sum_N_tr
19109  tau(i) = math_tensordot(mp,prm%P_tr(1:3,1:3,i))
19110  isfcc: if (prm%fccTwinTransNucleation) then
19111  s1=prm%fcc_twinNucleationSlipPair(1,i)
19112  s2=prm%fcc_twinNucleationSlipPair(2,i)
19113  if (tau(i) < dst%tau_r_tr(i,of)) then ! ToDo: correct?
19114  ndot0=(abs(dot_gamma_sl(s1))*(stt%rho_mob(s2,of)+stt%rho_dip(s2,of))+&
19115  abs(dot_gamma_sl(s2))*(stt%rho_mob(s1,of)+stt%rho_dip(s1,of)))/& ! ToDo: MD: it would be more consistent to use shearrates from state
19116  (prm%L_tr*prm%b_sl(i))*&
19117  (1.0_preal-exp(-prm%V_cs/(kb*t)*(dst%tau_r_tr(i,of)-tau(i)))) ! P_ncs
19118  else
19119  ndot0=0.0_preal
19120  end if
19121  else isfcc
19122  ndot0=prm%dot_N_0_tr(i)
19123  endif isfcc
19124  enddo
19125 
19126  significantstress: where(tau > tol_math_check)
19127  stressratio_s = (dst%tau_hat_tr(:,of)/tau)**prm%s
19128  dot_gamma_tr = dst%V_tr(:,of) * ndot0*exp(-stressratio_s)
19129  ddot_gamma_dtau = (dot_gamma_tr*prm%s/tau)*stressratio_s
19130  else where significantstress
19131  dot_gamma_tr = 0.0_preal
19132  ddot_gamma_dtau = 0.0_preal
19133  end where significantstress
19134 
19135  end associate
19136 
19137  if(present(ddot_gamma_dtau_trans)) ddot_gamma_dtau_trans = ddot_gamma_dtau
19138 
19139 end subroutine kinetics_trans
19140 
19141 end submodule plastic_dislotwin
19142 # 42 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
19143 
19144 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_disloUCLA.f90" 1
19145 !--------------------------------------------------------------------------------------------------
19151 !--------------------------------------------------------------------------------------------------
19152 submodule(constitutive) plastic_disloucla
19153 
19154  real(preal), parameter :: &
19155  kb = 1.38e-23_preal
19156 
19157  type :: tparameters
19158  real(preal) :: &
19159  d = 1.0_preal, &
19160  mu = 1.0_preal, &
19161  d_0 = 1.0_preal, &
19162  q_cl = 1.0_preal
19163  real(preal), allocatable, dimension(:) :: &
19164  b_sl, & !< magnitude of burgers vector [m]
19165  d_a, &
19166  i_sl, & !< Adj. parameter for distance between 2 forest dislocations
19167  atomicvolume, &
19168  tau_0, &
19169  !* mobility law parameters
19170  delta_f, &
19171  v0, &
19172  p, &
19173  q, &
19174  b, &
19175  kink_height, &
19176  w, &
19177  omega
19178  real(preal), allocatable, dimension(:,:) :: &
19179  h_sl_sl, & !< slip resistance from slip activity
19180  forestprojection
19181  real(preal), allocatable, dimension(:,:,:) :: &
19182  p_sl, &
19183  nonschmid_pos, &
19184  nonschmid_neg
19185  integer :: &
19186  sum_n_sl
19187  character(len=pStringLen), allocatable, dimension(:) :: &
19188  output
19189  logical :: &
19190  dipoleformation
19191  end type
19192 
19193  type :: tdislouclastate
19194  real(preal), dimension(:,:), pointer :: &
19195  rho_mob, &
19196  rho_dip, &
19197  gamma_sl
19198  end type tdislouclastate
19199 
19200  type :: tdisloucladependentstate
19201  real(preal), dimension(:,:), allocatable :: &
19202  lambda_sl, &
19203  threshold_stress
19204  end type tdisloucladependentstate
19205 
19206 !--------------------------------------------------------------------------------------------------
19207 ! containers for parameters and state
19208  type(tparameters), allocatable, dimension(:) :: param
19209  type(tdislouclastate), allocatable, dimension(:) :: &
19210  dotstate, &
19211  state
19212  type(tdisloucladependentstate), allocatable, dimension(:) :: dependentstate
19213 
19214 contains
19215 
19216 
19217 !--------------------------------------------------------------------------------------------------
19220 !--------------------------------------------------------------------------------------------------
19221 module subroutine plastic_disloucla_init
19222 
19223  integer :: &
19224  ninstance, &
19225  p, i, &
19226  nipcmyphase, &
19227  sizestate, sizedotstate, &
19228  startindex, endindex
19229  integer, dimension(:), allocatable :: &
19230  n_sl
19231  real(preal),dimension(:), allocatable :: &
19232  rho_mob_0, & !< initial dislocation density
19233  rho_dip_0, & !< initial dipole density
19234  a
19235  character(len=pStringLen) :: &
19236  extmsg = ''
19237 
19238  write(6,'(/,a)') ' <<<+- plastic_'//plasticity_disloucla_label//' init -+>>>'; flush(6)
19239 
19240  write(6,'(/,a)') ' Cereceda et al., International Journal of Plasticity 78:242–256, 2016'
19241  write(6,'(a)') ' https://dx.doi.org/10.1016/j.ijplas.2015.09.002'
19242 
19243  ninstance = count(phase_plasticity == plasticity_disloucla_id)
19244  if (iand(debug_level(debug_constitutive),debug_levelbasic) /= 0) &
19245  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
19246 
19247  allocate(param(ninstance))
19248  allocate(state(ninstance))
19249  allocate(dotstate(ninstance))
19250  allocate(dependentstate(ninstance))
19251 
19252  do p = 1, size(phase_plasticity)
19253  if (phase_plasticity(p) /= plasticity_disloucla_id) cycle
19254  associate(prm => param(phase_plasticityinstance(p)), &
19255  dot => dotstate(phase_plasticityinstance(p)), &
19256  stt => state(phase_plasticityinstance(p)), &
19257  dst => dependentstate(phase_plasticityinstance(p)), &
19258  config => config_phase(p))
19259 
19260  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
19261 
19262  ! This data is read in already in lattice
19263  prm%mu = lattice_mu(p)
19264 
19265 !--------------------------------------------------------------------------------------------------
19266 ! slip related parameters
19267  n_sl = config%getInts('nslip',defaultval=emptyintarray)
19268  prm%sum_N_sl = sum(abs(n_sl))
19269  slipactive: if (prm%sum_N_sl > 0) then
19270  prm%P_sl = lattice_schmidmatrix_slip(n_sl,config%getString('lattice_structure'),&
19271  config%getFloat('c/a',defaultval=0.0_preal))
19272 
19273  if(trim(config%getString('lattice_structure')) == 'bcc') then
19274  a = config%getFloats('nonschmid_coefficients',defaultval = emptyrealarray)
19275  prm%nonSchmid_pos = lattice_nonschmidmatrix(n_sl,a,+1)
19276  prm%nonSchmid_neg = lattice_nonschmidmatrix(n_sl,a,-1)
19277  else
19278  prm%nonSchmid_pos = prm%P_sl
19279  prm%nonSchmid_neg = prm%P_sl
19280  endif
19281 
19282  prm%h_sl_sl = lattice_interaction_slipbyslip(n_sl,config%getFloats('interaction_slipslip'), &
19283  config%getString('lattice_structure'))
19284  prm%forestProjection = lattice_forestprojection_edge(n_sl,config%getString('lattice_structure'),&
19285  config%getFloat('c/a',defaultval=0.0_preal))
19286  prm%forestProjection = transpose(prm%forestProjection)
19287 
19288  rho_mob_0 = config%getFloats('rhoedge0', requiredsize=size(n_sl))
19289  rho_dip_0 = config%getFloats('rhoedgedip0', requiredsize=size(n_sl))
19290  prm%v0 = config%getFloats('v0', requiredsize=size(n_sl))
19291  prm%b_sl = config%getFloats('slipburgers', requiredsize=size(n_sl))
19292  prm%delta_F = config%getFloats('qedge', requiredsize=size(n_sl))
19293 
19294  prm%i_sl = config%getFloats('clambdaslip', requiredsize=size(n_sl))
19295  prm%tau_0 = config%getFloats('tau_peierls', requiredsize=size(n_sl))
19296  prm%p = config%getFloats('p_slip', requiredsize=size(n_sl), &
19297  defaultval=[(1.0_preal,i=1,size(n_sl))])
19298  prm%q = config%getFloats('q_slip', requiredsize=size(n_sl), &
19299  defaultval=[(1.0_preal,i=1,size(n_sl))])
19300  prm%kink_height = config%getFloats('kink_height', requiredsize=size(n_sl))
19301  prm%w = config%getFloats('kink_width', requiredsize=size(n_sl))
19302  prm%omega = config%getFloats('omega', requiredsize=size(n_sl))
19303  prm%B = config%getFloats('friction_coeff', requiredsize=size(n_sl))
19304 
19305  prm%D = config%getFloat('grainsize')
19306  prm%D_0 = config%getFloat('d0')
19307  prm%Q_cl = config%getFloat('qsd')
19308  prm%atomicVolume = config%getFloat('catomicvolume') * prm%b_sl**3.0_preal
19309  prm%D_a = config%getFloat('cedgedipmindistance') * prm%b_sl
19310  prm%dipoleformation = config%getFloat('dipoleformationfactor') > 0.0_preal !should be on by default, ToDo: change to /key/-type key
19311 
19312  ! expand: family => system
19313  rho_mob_0 = math_expand(rho_mob_0, n_sl)
19314  rho_dip_0 = math_expand(rho_dip_0, n_sl)
19315  prm%q = math_expand(prm%q, n_sl)
19316  prm%p = math_expand(prm%p, n_sl)
19317  prm%delta_F = math_expand(prm%delta_F, n_sl)
19318  prm%b_sl = math_expand(prm%b_sl, n_sl)
19319  prm%kink_height = math_expand(prm%kink_height, n_sl)
19320  prm%w = math_expand(prm%w, n_sl)
19321  prm%omega = math_expand(prm%omega, n_sl)
19322  prm%tau_0 = math_expand(prm%tau_0, n_sl)
19323  prm%v0 = math_expand(prm%v0, n_sl)
19324  prm%B = math_expand(prm%B, n_sl)
19325  prm%i_sl = math_expand(prm%i_sl, n_sl)
19326  prm%atomicVolume = math_expand(prm%atomicVolume, n_sl)
19327  prm%D_a = math_expand(prm%D_a, n_sl)
19328 
19329  ! sanity checks
19330  if ( prm%D_0 <= 0.0_preal) extmsg = trim(extmsg)//' D_0'
19331  if ( prm%Q_cl <= 0.0_preal) extmsg = trim(extmsg)//' Q_cl'
19332  if (any(rho_mob_0 < 0.0_preal)) extmsg = trim(extmsg)//' rhoedge0'
19333  if (any(rho_dip_0 < 0.0_preal)) extmsg = trim(extmsg)//' rhoedgedip0'
19334  if (any(prm%v0 < 0.0_preal)) extmsg = trim(extmsg)//' v0'
19335  if (any(prm%b_sl <= 0.0_preal)) extmsg = trim(extmsg)//' b_sl'
19336  if (any(prm%delta_F <= 0.0_preal)) extmsg = trim(extmsg)//' qedge'
19337  if (any(prm%tau_0 < 0.0_preal)) extmsg = trim(extmsg)//' tau_0'
19338  if (any(prm%D_a <= 0.0_preal)) extmsg = trim(extmsg)//' cedgedipmindistance or b_sl'
19339  if (any(prm%atomicVolume <= 0.0_preal)) extmsg = trim(extmsg)//' catomicvolume or b_sl'
19340 
19341  else slipactive
19342  rho_mob_0= emptyrealarray; rho_dip_0 = emptyrealarray
19343  allocate(prm%b_sl,prm%D_a,prm%i_sl,prm%atomicVolume,prm%tau_0, &
19344  prm%delta_F,prm%v0,prm%p,prm%q,prm%B,prm%kink_height,prm%w,prm%omega, &
19345  source = emptyrealarray)
19346  allocate(prm%forestProjection(0,0))
19347  allocate(prm%h_sl_sl (0,0))
19348  endif slipactive
19349 
19350 !--------------------------------------------------------------------------------------------------
19351 ! allocate state arrays
19352  nipcmyphase = count(material_phaseat == p) * discretization_nip
19353  sizedotstate = size(['rho_mob ','rho_dip ','gamma_sl']) * prm%sum_N_sl
19354  sizestate = sizedotstate
19355 
19356  call material_allocateplasticstate(p,nipcmyphase,sizestate,sizedotstate,0)
19357 
19358 !--------------------------------------------------------------------------------------------------
19359 ! state aliases and initialization
19360  startindex = 1
19361  endindex = prm%sum_N_sl
19362  stt%rho_mob => plasticstate(p)%state(startindex:endindex,:)
19363  stt%rho_mob = spread(rho_mob_0,2,nipcmyphase)
19364  dot%rho_mob => plasticstate(p)%dotState(startindex:endindex,:)
19365  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_rho',defaultval=1.0_preal)
19366  if (any(plasticstate(p)%atol(startindex:endindex) < 0.0_preal)) extmsg = trim(extmsg)//' atol_rho'
19367 
19368  startindex = endindex + 1
19369  endindex = endindex + prm%sum_N_sl
19370  stt%rho_dip => plasticstate(p)%state(startindex:endindex,:)
19371  stt%rho_dip = spread(rho_dip_0,2,nipcmyphase)
19372  dot%rho_dip => plasticstate(p)%dotState(startindex:endindex,:)
19373  plasticstate(p)%atol(startindex:endindex) = config%getFloat('atol_rho',defaultval=1.0_preal)
19374 
19375  startindex = endindex + 1
19376  endindex = endindex + prm%sum_N_sl
19377  stt%gamma_sl => plasticstate(p)%state(startindex:endindex,:)
19378  dot%gamma_sl => plasticstate(p)%dotState(startindex:endindex,:)
19379  plasticstate(p)%atol(startindex:endindex) = 1.0e-2_preal
19380  ! global alias
19381  plasticstate(p)%slipRate => plasticstate(p)%dotState(startindex:endindex,:)
19382 
19383  allocate(dst%Lambda_sl(prm%sum_N_sl,nipcmyphase), source=0.0_preal)
19384  allocate(dst%threshold_stress(prm%sum_N_sl,nipcmyphase), source=0.0_preal)
19385 
19386  plasticstate(p)%state0 = plasticstate(p)%state ! ToDo: this could be done centrally
19387 
19388  end associate
19389 
19390 !--------------------------------------------------------------------------------------------------
19391 ! exit if any parameter is out of range
19392  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//plasticity_disloucla_label//')')
19393 
19394  enddo
19395 
19396 end subroutine plastic_disloucla_init
19397 
19398 
19399 !--------------------------------------------------------------------------------------------------
19401 !--------------------------------------------------------------------------------------------------
19402 pure module subroutine plastic_disloucla_lpanditstangent(lp,dlp_dmp, &
19403  mp,t,instance,of)
19404  real(preal), dimension(3,3), intent(out) :: &
19405  lp
19406  real(preal), dimension(3,3,3,3), intent(out) :: &
19407  dlp_dmp
19408 
19409  real(preal), dimension(3,3), intent(in) :: &
19410  mp
19411  real(preal), intent(in) :: &
19412  t
19413  integer, intent(in) :: &
19414  instance, &
19415  of
19416 
19417  integer :: &
19418  i,k,l,m,n
19419  real(preal), dimension(param(instance)%sum_N_sl) :: &
19420  dot_gamma_pos,dot_gamma_neg, &
19421  ddot_gamma_dtau_pos,ddot_gamma_dtau_neg
19422 
19423  lp = 0.0_preal
19424  dlp_dmp = 0.0_preal
19425 
19426  associate(prm => param(instance))
19427 
19428  call kinetics(mp,t,instance,of,dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg)
19429  do i = 1, prm%sum_N_sl
19430  lp = lp + (dot_gamma_pos(i)+dot_gamma_neg(i))*prm%P_sl(1:3,1:3,i)
19431  forall (k=1:3,l=1:3,m=1:3,n=1:3) &
19432  dlp_dmp(k,l,m,n) = dlp_dmp(k,l,m,n) &
19433  + ddot_gamma_dtau_pos(i) * prm%P_sl(k,l,i) * prm%nonSchmid_pos(m,n,i) &
19434  + ddot_gamma_dtau_neg(i) * prm%P_sl(k,l,i) * prm%nonSchmid_neg(m,n,i)
19435  enddo
19436 
19437  end associate
19438 
19439 end subroutine plastic_disloucla_lpanditstangent
19440 
19441 
19442 !--------------------------------------------------------------------------------------------------
19444 !--------------------------------------------------------------------------------------------------
19445 module subroutine plastic_disloucla_dotstate(mp,t,instance,of)
19446 
19447  real(preal), dimension(3,3), intent(in) :: &
19448  mp
19449  real(preal), intent(in) :: &
19450  t
19451  integer, intent(in) :: &
19452  instance, &
19453  of
19454 
19455  real(preal) :: &
19456  vacancydiffusion
19457  real(preal), dimension(param(instance)%sum_N_sl) :: &
19458  gdot_pos, gdot_neg,&
19459  tau_pos,&
19460  tau_neg, &
19461  v_cl, &
19462  dot_rho_dip_formation, &
19463  dot_rho_dip_climb, &
19464  dip_distance
19465 
19466  associate(prm => param(instance), stt => state(instance),dot => dotstate(instance), dst => dependentstate(instance))
19467 
19468  call kinetics(mp,t,instance,of,&
19469  gdot_pos,gdot_neg, &
19470  tau_pos_out = tau_pos,tau_neg_out = tau_neg)
19471 
19472  dot%gamma_sl(:,of) = (gdot_pos+gdot_neg) ! ToDo: needs to be abs
19473  vacancydiffusion = prm%D_0*exp(-prm%Q_cl/(kb*t))
19474 
19475  where(deq0(tau_pos)) ! ToDo: use avg of pos and neg
19476  dot_rho_dip_formation = 0.0_preal
19477  dot_rho_dip_climb = 0.0_preal
19478  else where
19479  dip_distance = math_clip(3.0_preal*prm%mu*prm%b_sl/(16.0_preal*pi*abs(tau_pos)), &
19480  prm%D_a, & ! lower limit
19481  dst%Lambda_sl(:,of)) ! upper limit
19482  dot_rho_dip_formation = merge(2.0_preal*dip_distance* stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of))/prm%b_sl, & ! ToDo: ignore region of spontaneous annihilation
19483  0.0_preal, &
19484  prm%dipoleformation)
19485  v_cl = (3.0_preal*prm%mu*vacancydiffusion*prm%atomicVolume/(2.0_preal*pi*kb*t)) &
19486  * (1.0_preal/(dip_distance+prm%D_a))
19487  dot_rho_dip_climb = (4.0_preal*v_cl*stt%rho_dip(:,of))/(dip_distance-prm%D_a) ! ToDo: Discuss with Franz: Stress dependency?
19488  end where
19489 
19490  dot%rho_mob(:,of) = abs(dot%gamma_sl(:,of))/(prm%b_sl*dst%Lambda_sl(:,of)) & ! multiplication
19491  - dot_rho_dip_formation &
19492  - (2.0_preal*prm%D_a)/prm%b_sl*stt%rho_mob(:,of)*abs(dot%gamma_sl(:,of)) ! Spontaneous annihilation of 2 single edge dislocations
19493  dot%rho_dip(:,of) = dot_rho_dip_formation &
19494  - (2.0_preal*prm%D_a)/prm%b_sl*stt%rho_dip(:,of)*abs(dot%gamma_sl(:,of)) & ! Spontaneous annihilation of a single edge dislocation with a dipole constituent
19495  - dot_rho_dip_climb
19496 
19497  end associate
19498 
19499 end subroutine plastic_disloucla_dotstate
19500 
19501 
19502 !--------------------------------------------------------------------------------------------------
19504 !--------------------------------------------------------------------------------------------------
19505 module subroutine plastic_disloucla_dependentstate(instance,of)
19506 
19507  integer, intent(in) :: &
19508  instance, &
19509  of
19510 
19511  real(preal), dimension(param(instance)%sum_N_sl) :: &
19512  dislocationspacing
19513 
19514  associate(prm => param(instance), stt => state(instance),dst => dependentstate(instance))
19515 
19516  dislocationspacing = sqrt(matmul(prm%forestProjection,stt%rho_mob(:,of)+stt%rho_dip(:,of)))
19517  dst%threshold_stress(:,of) = prm%mu*prm%b_sl &
19518  * sqrt(matmul(prm%h_sl_sl,stt%rho_mob(:,of)+stt%rho_dip(:,of)))
19519 
19520  dst%Lambda_sl(:,of) = prm%D/(1.0_preal+prm%D*dislocationspacing/prm%i_sl)
19521 
19522  end associate
19523 
19524 end subroutine plastic_disloucla_dependentstate
19525 
19526 
19527 !--------------------------------------------------------------------------------------------------
19529 !--------------------------------------------------------------------------------------------------
19530 module subroutine plastic_disloucla_results(instance,group)
19531 
19532  integer, intent(in) :: instance
19533  character(len=*), intent(in) :: group
19534 
19535  integer :: o
19536 
19537  associate(prm => param(instance), stt => state(instance), dst => dependentstate(instance))
19538  outputsloop: do o = 1,size(prm%output)
19539  select case(trim(prm%output(o)))
19540  case('edge_density') ! ToDo: should be rho_mob
19541  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_mob,'rho_mob',&
19542  'mobile dislocation density','1/m²')
19543  case('dipole_density') ! ToDo: should be rho_dip
19544  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_dip,'rho_dip',&
19545  'dislocation dipole density''1/m²')
19546  case('shear_rate_slip') ! should be gamma
19547  if(prm%sum_N_sl>0) call results_writedataset(group,stt%gamma_sl,'dot_gamma_sl',& ! this is not dot!!
19548  'plastic shear','1')
19549  case('mfp_slip') !ToDo: should be Lambda
19550  if(prm%sum_N_sl>0) call results_writedataset(group,dst%Lambda_sl,'Lambda_sl',&
19551  'mean free path for slip','m')
19552  case('threshold_stress_slip') !ToDo: should be tau_pass
19553  if(prm%sum_N_sl>0) call results_writedataset(group,dst%threshold_stress,'tau_pass',&
19554  'threshold stress for slip','Pa')
19555  end select
19556  enddo outputsloop
19557  end associate
19558 
19559 end subroutine plastic_disloucla_results
19560 
19561 
19562 !--------------------------------------------------------------------------------------------------
19564 ! stress, and the resolved stress.
19566 ! NOTE: Against the common convention, the result (i.e. intent(out)) variables are the last to
19567 ! have the optional arguments at the end
19568 !--------------------------------------------------------------------------------------------------
19569 pure subroutine kinetics(Mp,T,instance,of, &
19570  dot_gamma_pos,dot_gamma_neg,ddot_gamma_dtau_pos,ddot_gamma_dtau_neg,tau_pos_out,tau_neg_out)
19572  real(preal), dimension(3,3), intent(in) :: &
19573  mp
19574  real(preal), intent(in) :: &
19575  t
19576  integer, intent(in) :: &
19577  instance, &
19578  of
19579 
19580  real(preal), intent(out), dimension(param(instance)%sum_N_sl) :: &
19581  dot_gamma_pos, &
19582  dot_gamma_neg
19583  real(preal), intent(out), optional, dimension(param(instance)%sum_N_sl) :: &
19584  ddot_gamma_dtau_pos, &
19585  ddot_gamma_dtau_neg, &
19586  tau_pos_out, &
19587  tau_neg_out
19588  real(preal), dimension(param(instance)%sum_N_sl) :: &
19589  stressratio, &
19590  stressratio_p,stressratio_pminus1, &
19591  dvel, vel, &
19592  tau_pos,tau_neg, &
19593  t_n, t_k, dtk,dtn, &
19594  needsgoodname ! ToDo: @Karo: any idea?
19595  integer :: j
19596 
19597  associate(prm => param(instance), stt => state(instance), dst => dependentstate(instance))
19598 
19599  do j = 1, prm%sum_N_sl
19600  tau_pos(j) = math_tensordot(mp,prm%nonSchmid_pos(1:3,1:3,j))
19601  tau_neg(j) = math_tensordot(mp,prm%nonSchmid_neg(1:3,1:3,j))
19602  enddo
19603 
19604 
19605  if (present(tau_pos_out)) tau_pos_out = tau_pos
19606  if (present(tau_neg_out)) tau_neg_out = tau_neg
19607 
19608  associate(boltzmannratio => prm%delta_F/(kb*t), &
19609  dot_gamma_0 => stt%rho_mob(:,of)*prm%b_sl*prm%v0, &
19610  effectivelength => dst%Lambda_sl(:,of) - prm%w)
19611 
19612  significantpositivetau: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check)
19613  stressratio = (abs(tau_pos)-dst%threshold_stress(:,of))/prm%tau_0
19614  stressratio_p = stressratio** prm%p
19615  stressratio_pminus1 = stressratio**(prm%p-1.0_preal)
19616  needsgoodname = exp(-boltzmannratio*(1-stressratio_p) ** prm%q)
19617 
19618  t_n = prm%b_sl/(needsgoodname*prm%omega*effectivelength)
19619  t_k = effectivelength * prm%B /(2.0_preal*prm%b_sl*tau_pos)
19620 
19621  vel = prm%kink_height/(t_n + t_k)
19622 
19623  dot_gamma_pos = dot_gamma_0 * sign(vel,tau_pos) * 0.5_preal
19624  else where significantpositivetau
19625  dot_gamma_pos = 0.0_preal
19626  end where significantpositivetau
19627 
19628  if (present(ddot_gamma_dtau_pos)) then
19629  significantpositivetau2: where(abs(tau_pos)-dst%threshold_stress(:,of) > tol_math_check)
19630  dtn = -1.0_preal * t_n * boltzmannratio * prm%p * prm%q * (1.0_preal-stressratio_p)**(prm%q - 1.0_preal) &
19631  * (stressratio)**(prm%p - 1.0_preal) / prm%tau_0
19632  dtk = -1.0_preal * t_k / tau_pos
19633 
19634  dvel = -1.0_preal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_preal
19635 
19636  ddot_gamma_dtau_pos = dot_gamma_0 * dvel* 0.5_preal
19637  else where significantpositivetau2
19638  ddot_gamma_dtau_pos = 0.0_preal
19639  end where significantpositivetau2
19640  endif
19641 
19642  significantnegativetau: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check)
19643  stressratio = (abs(tau_neg)-dst%threshold_stress(:,of))/prm%tau_0
19644  stressratio_p = stressratio** prm%p
19645  stressratio_pminus1 = stressratio**(prm%p-1.0_preal)
19646  needsgoodname = exp(-boltzmannratio*(1-stressratio_p) ** prm%q)
19647 
19648  t_n = prm%b_sl/(needsgoodname*prm%omega*effectivelength)
19649  t_k = effectivelength * prm%B /(2.0_preal*prm%b_sl*tau_pos)
19650 
19651  vel = prm%kink_height/(t_n + t_k)
19652 
19653  dot_gamma_neg = dot_gamma_0 * sign(vel,tau_neg) * 0.5_preal
19654  else where significantnegativetau
19655  dot_gamma_neg = 0.0_preal
19656  end where significantnegativetau
19657 
19658  if (present(ddot_gamma_dtau_neg)) then
19659  significantnegativetau2: where(abs(tau_neg)-dst%threshold_stress(:,of) > tol_math_check)
19660  dtn = -1.0_preal * t_n * boltzmannratio * prm%p * prm%q * (1.0_preal-stressratio_p)**(prm%q - 1.0_preal) &
19661  * (stressratio)**(prm%p - 1.0_preal) / prm%tau_0
19662  dtk = -1.0_preal * t_k / tau_neg
19663 
19664  dvel = -1.0_preal * prm%kink_height * (dtk + dtn) / (t_n + t_k)**2.0_preal
19665 
19666  ddot_gamma_dtau_neg = dot_gamma_0 * dvel * 0.5_preal
19667  else where significantnegativetau2
19668  ddot_gamma_dtau_neg = 0.0_preal
19669  end where significantnegativetau2
19670  end if
19671 
19672  end associate
19673  end associate
19674 
19675 end subroutine kinetics
19676 
19677 end submodule plastic_disloucla
19678 # 43 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
19679 
19680 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90" 1
19681 !--------------------------------------------------------------------------------------------------
19686 !--------------------------------------------------------------------------------------------------
19687 submodule(constitutive) plastic_nonlocal
19688  use geometry_plastic_nonlocal, only: &
19689  nipneighbors => geometry_plastic_nonlocal_nipneighbors, &
19690  ipneighborhood => geometry_plastic_nonlocal_ipneighborhood, &
19694 
19695  real(preal), parameter :: &
19696  kb = 1.38e-23_preal
19697 
19698  ! storage order of dislocation types
19699  integer, dimension(8), parameter :: &
19700  sgl = [1,2,3,4,5,6,7,8]
19701  integer, dimension(5), parameter :: &
19702  edg = [1,2,5,6,9], & !< edge
19703  scr = [3,4,7,8,10]
19704  integer, dimension(4), parameter :: &
19705  mob = [1,2,3,4], & !< mobile
19706  imm = [5,6,7,8]
19707  integer, dimension(2), parameter :: &
19708  dip = [9,10], & !< dipole
19709  imm_edg = imm(1:2), &
19710  imm_scr = imm(3:4)
19711  integer, parameter :: &
19712  mob_edg_pos = 1, & !< mobile edge positive
19713  mob_edg_neg = 2, &
19714  mob_scr_pos = 3, &
19715  mob_scr_neg = 4
19716 
19717  ! BEGIN DEPRECATED
19718  integer, dimension(:,:,:), allocatable :: &
19719  irhou, & !< state indices for unblocked density
19720  iv, & !< state indices for dislcation velocities
19721  id
19722  !END DEPRECATED
19723 
19724  real(preal), dimension(:,:,:,:,:,:), allocatable :: &
19725  compatibility
19726 
19727  type :: tinitialparameters
19728  real(preal) :: &
19729  rhosglscatter, & !< standard deviation of scatter in initial dislocation density
19730  rhosglrandom, &
19731  rhosglrandombinning
19732  real(preal), dimension(:), allocatable :: &
19733  rhosgledgepos0, & !< initial edge_pos dislocation density
19734  rhosgledgeneg0, & !< initial edge_neg dislocation density
19735  rhosglscrewpos0, & !< initial screw_pos dislocation density
19736  rhosglscrewneg0, & !< initial screw_neg dislocation density
19737  rhodipedge0, & !< initial edge dipole dislocation density
19738  rhodipscrew0
19739  integer, dimension(:) ,allocatable :: &
19740  n_sl
19741  end type tinitialparameters
19742 
19743  type :: tparameters
19744  real(preal) :: &
19745  atomicvolume, & !< atomic volume
19746  dsd0, & !< prefactor for self-diffusion coefficient
19747  selfdiffusionenergy, & !< activation enthalpy for diffusion
19748  atol_rho, & !< absolute tolerance for dislocation density in state integration
19749  significantrho, & !< density considered significant
19750  significantn, & !< number of dislocations considered significant
19751  doublekinkwidth, & !< width of a doubkle kink in multiples of the burgers vector length b
19752  solidsolutionenergy, & !< activation energy for solid solution in J
19753  solidsolutionsize, & !< solid solution obstacle size in multiples of the burgers vector length
19754  solidsolutionconcentration, & !< concentration of solid solution in atomic parts
19755  p, & !< parameter for kinetic law (Kocks,Argon,Ashby)
19756  q, & !< parameter for kinetic law (Kocks,Argon,Ashby)
19757  viscosity, & !< viscosity for dislocation glide in Pa s
19758  fattack, & !< attack frequency in Hz
19759  surfacetransmissivity, & !< transmissivity at free surface
19760  grainboundarytransmissivity, & !< transmissivity at grain boundary (identified by different texture)
19761  cflfactor, & !< safety factor for CFL flux condition
19762  fedgemultiplication, & !< factor that determines how much edge dislocations contribute to multiplication (0...1)
19763  linetensioneffect, &
19764  edgejogfactor, &
19765  mu, &
19766  nu
19767  real(preal), dimension(:), allocatable :: &
19768  mindipoleheight_edge, & !< minimum stable edge dipole height
19769  mindipoleheight_screw, & !< minimum stable screw dipole height
19770  peierlsstress_edge, &
19771  peierlsstress_screw, &
19772  lambda0, & !< mean free path prefactor for each
19773  burgers
19774  real(preal), dimension(:,:), allocatable :: &
19775  slip_normal, &
19776  slip_direction, &
19777  slip_transverse, &
19778  mindipoleheight, & ! edge and screw
19779  peierlsstress, & ! edge and screw
19780  interactionslipslip ,& !< coefficients for slip-slip interaction
19781  forestprojection_edge, & !< matrix of forest projections of edge dislocations
19782  forestprojection_screw
19783  real(preal), dimension(:,:,:), allocatable :: &
19784  schmid, & !< Schmid contribution
19785  nonschmid_pos, &
19786  nonschmid_neg
19787  integer :: &
19788  sum_n_sl
19789  integer, dimension(:), allocatable :: &
19790  colinearsystem
19791  character(len=pStringLen), dimension(:), allocatable :: &
19792  output
19793  logical :: &
19794  shortrangestresscorrection, & !< use of short range stress correction by excess density gradient term
19795  nonschmidactive = .false.
19796  end type tparameters
19797 
19798  type :: tnonlocalmicrostructure
19799  real(preal), allocatable, dimension(:,:) :: &
19800  tau_pass, &
19801  tau_back
19802  end type tnonlocalmicrostructure
19803 
19804  type :: tnonlocalstate
19805  real(preal), pointer, dimension(:,:) :: &
19806  rho, & ! < all dislocations
19807  rhosgl, &
19808  rhosglmobile, & ! iRhoU
19809  rho_sgl_mob_edg_pos, &
19810  rho_sgl_mob_edg_neg, &
19811  rho_sgl_mob_scr_pos, &
19812  rho_sgl_mob_scr_neg, &
19813  rhosglimmobile, &
19814  rho_sgl_imm_edg_pos, &
19815  rho_sgl_imm_edg_neg, &
19816  rho_sgl_imm_scr_pos, &
19817  rho_sgl_imm_scr_neg, &
19818  rhodip, &
19819  rho_dip_edg, &
19820  rho_dip_scr, &
19821  rho_forest, &
19822  gamma, &
19823  v, &
19824  v_edg_pos, &
19825  v_edg_neg, &
19826  v_scr_pos, &
19827  v_scr_neg
19828  end type tnonlocalstate
19829 
19830  type(tnonlocalstate), allocatable, dimension(:) :: &
19831  deltastate, &
19832  dotstate, &
19833  state, &
19834  state0
19835 
19836  type(tparameters), dimension(:), allocatable :: param
19837 
19838  type(tnonlocalmicrostructure), dimension(:), allocatable :: microstructure
19839 
19840 contains
19841 
19842 !--------------------------------------------------------------------------------------------------
19845 !--------------------------------------------------------------------------------------------------
19846 module subroutine plastic_nonlocal_init
19847 
19848  integer :: &
19849  ninstance, &
19850  p, &
19851  nipcmyphase, &
19852  sizestate, sizedotstate, sizedependentstate, sizedeltastate, &
19853  s1, s2, &
19854  s, t, l
19855  real(preal), dimension(:), allocatable :: &
19856  a
19857  character(len=pStringLen) :: &
19858  extmsg = ''
19859  type(tinitialparameters) :: &
19860  ini
19861 
19862  write(6,'(/,a)') ' <<<+- constitutive_'//plasticity_nonlocal_label//' init -+>>>'; flush(6)
19863 
19864  write(6,'(/,a)') ' Reuber et al., Acta Materialia 71:333–348, 2014'
19865  write(6,'(a)') ' https://doi.org/10.1016/j.actamat.2014.03.012'
19866 
19867  write(6,'(/,a)') ' Kords, Dissertation RWTH Aachen, 2014'
19868  write(6,'(a)') ' http://publications.rwth-aachen.de/record/229993'
19869 
19870  ninstance = count(phase_plasticity == plasticity_nonlocal_id)
19871  if (iand(debug_level(debug_constitutive),debug_levelbasic) /= 0) &
19872  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
19873 
19874  allocate(param(ninstance))
19875  allocate(state(ninstance))
19876  allocate(state0(ninstance))
19877  allocate(dotstate(ninstance))
19878  allocate(deltastate(ninstance))
19879  allocate(microstructure(ninstance))
19880 
19881  do p=1, size(config_phase)
19882  if (phase_plasticity(p) /= plasticity_nonlocal_id) cycle
19883 
19884  associate(prm => param(phase_plasticityinstance(p)), &
19885  dot => dotstate(phase_plasticityinstance(p)), &
19886  stt => state(phase_plasticityinstance(p)), &
19887  st0 => state0(phase_plasticityinstance(p)), &
19888  del => deltastate(phase_plasticityinstance(p)), &
19889  dst => microstructure(phase_plasticityinstance(p)), &
19890  config => config_phase(p))
19891 
19892  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
19893 
19894  prm%atol_rho = config%getFloat('atol_rho',defaultval=1.0e4_preal)
19895 
19896  ! This data is read in already in lattice
19897  prm%mu = lattice_mu(p)
19898  prm%nu = lattice_nu(p)
19899 
19900  ini%N_sl = config%getInts('nslip',defaultval=emptyintarray)
19901  prm%sum_N_sl = sum(abs(ini%N_sl))
19902  slipactive: if (prm%sum_N_sl > 0) then
19903  prm%Schmid = lattice_schmidmatrix_slip(ini%N_sl,config%getString('lattice_structure'),&
19904  config%getFloat('c/a',defaultval=0.0_preal))
19905 
19906  if(trim(config%getString('lattice_structure')) == 'bcc') then
19907  a = config%getFloats('nonschmid_coefficients',defaultval = emptyrealarray)
19908  if(size(a) > 0) prm%nonSchmidActive = .true.
19909  prm%nonSchmid_pos = lattice_nonschmidmatrix(ini%N_sl,a,+1)
19910  prm%nonSchmid_neg = lattice_nonschmidmatrix(ini%N_sl,a,-1)
19911  else
19912  prm%nonSchmid_pos = prm%Schmid
19913  prm%nonSchmid_neg = prm%Schmid
19914  endif
19915 
19916  prm%interactionSlipSlip = lattice_interaction_slipbyslip(ini%N_sl, &
19917  config%getFloats('interaction_slipslip'), &
19918  config%getString('lattice_structure'))
19919 
19920  prm%forestProjection_edge = lattice_forestprojection_edge(ini%N_sl,config%getString('lattice_structure'),&
19921  config%getFloat('c/a',defaultval=0.0_preal))
19922  prm%forestProjection_screw = lattice_forestprojection_screw(ini%N_sl,config%getString('lattice_structure'),&
19923  config%getFloat('c/a',defaultval=0.0_preal))
19924 
19925  prm%slip_direction = lattice_slip_direction(ini%N_sl,config%getString('lattice_structure'),&
19926  config%getFloat('c/a',defaultval=0.0_preal))
19927  prm%slip_transverse = lattice_slip_transverse(ini%N_sl,config%getString('lattice_structure'),&
19928  config%getFloat('c/a',defaultval=0.0_preal))
19929  prm%slip_normal = lattice_slip_normal(ini%N_sl,config%getString('lattice_structure'),&
19930  config%getFloat('c/a',defaultval=0.0_preal))
19931 
19932  ! collinear systems (only for octahedral slip systems in fcc)
19933  allocate(prm%colinearSystem(prm%sum_N_sl), source = -1)
19934  do s1 = 1, prm%sum_N_sl
19935  do s2 = 1, prm%sum_N_sl
19936  if (all(deq0(math_cross(prm%slip_direction(1:3,s1),prm%slip_direction(1:3,s2)))) .and. &
19937  any(dneq0(math_cross(prm%slip_normal (1:3,s1),prm%slip_normal (1:3,s2))))) &
19938  prm%colinearSystem(s1) = s2
19939  enddo
19940  enddo
19941 
19942  ini%rhoSglEdgePos0 = config%getFloats('rhosgledgepos0', requiredsize=size(ini%N_sl))
19943  ini%rhoSglEdgeNeg0 = config%getFloats('rhosgledgeneg0', requiredsize=size(ini%N_sl))
19944  ini%rhoSglScrewPos0 = config%getFloats('rhosglscrewpos0', requiredsize=size(ini%N_sl))
19945  ini%rhoSglScrewNeg0 = config%getFloats('rhosglscrewneg0', requiredsize=size(ini%N_sl))
19946  ini%rhoDipEdge0 = config%getFloats('rhodipedge0', requiredsize=size(ini%N_sl))
19947  ini%rhoDipScrew0 = config%getFloats('rhodipscrew0', requiredsize=size(ini%N_sl))
19948 
19949  prm%lambda0 = config%getFloats('lambda0', requiredsize=size(ini%N_sl))
19950  prm%burgers = config%getFloats('burgers', requiredsize=size(ini%N_sl))
19951 
19952  prm%lambda0 = math_expand(prm%lambda0,ini%N_sl)
19953  prm%burgers = math_expand(prm%burgers,ini%N_sl)
19954 
19955  prm%minDipoleHeight_edge = config%getFloats('minimumdipoleheightedge', requiredsize=size(ini%N_sl))
19956  prm%minDipoleHeight_screw = config%getFloats('minimumdipoleheightscrew', requiredsize=size(ini%N_sl))
19957  prm%minDipoleHeight_edge = math_expand(prm%minDipoleHeight_edge, ini%N_sl)
19958  prm%minDipoleHeight_screw = math_expand(prm%minDipoleHeight_screw,ini%N_sl)
19959  allocate(prm%minDipoleHeight(prm%sum_N_sl,2))
19960  prm%minDipoleHeight(:,1) = prm%minDipoleHeight_edge
19961  prm%minDipoleHeight(:,2) = prm%minDipoleHeight_screw
19962 
19963  prm%peierlsstress_edge = config%getFloats('peierlsstressedge', requiredsize=size(ini%N_sl))
19964  prm%peierlsstress_screw = config%getFloats('peierlsstressscrew', requiredsize=size(ini%N_sl))
19965  prm%peierlsstress_edge = math_expand(prm%peierlsstress_edge, ini%N_sl)
19966  prm%peierlsstress_screw = math_expand(prm%peierlsstress_screw,ini%N_sl)
19967  allocate(prm%peierlsstress(prm%sum_N_sl,2))
19968  prm%peierlsstress(:,1) = prm%peierlsstress_edge
19969  prm%peierlsstress(:,2) = prm%peierlsstress_screw
19970 
19971  prm%significantRho = config%getFloat('significantrho')
19972  prm%significantN = config%getFloat('significantn', 0.0_preal)
19973  prm%CFLfactor = config%getFloat('cflfactor',defaultval=2.0_preal)
19974 
19975  prm%atomicVolume = config%getFloat('atomicvolume')
19976  prm%Dsd0 = config%getFloat('selfdiffusionprefactor') !,'dsd0'
19977  prm%selfDiffusionEnergy = config%getFloat('selfdiffusionenergy') !,'qsd'
19978  prm%linetensionEffect = config%getFloat('linetension')
19979  prm%edgeJogFactor = config%getFloat('edgejog')!,'edgejogs'
19980  prm%doublekinkwidth = config%getFloat('doublekinkwidth')
19981  prm%solidSolutionEnergy = config%getFloat('solidsolutionenergy')
19982  prm%solidSolutionSize = config%getFloat('solidsolutionsize')
19983  prm%solidSolutionConcentration = config%getFloat('solidsolutionconcentration')
19984 
19985  prm%p = config%getFloat('p')
19986  prm%q = config%getFloat('q')
19987  prm%viscosity = config%getFloat('viscosity')
19988  prm%fattack = config%getFloat('attackfrequency')
19989 
19990  ! ToDo: discuss logic
19991  ini%rhoSglScatter = config%getFloat('rhosglscatter')
19992  ini%rhoSglRandom = config%getFloat('rhosglrandom',0.0_preal)
19993  if (config%keyExists('/rhosglrandom/')) &
19994  ini%rhoSglRandomBinning = config%getFloat('rhosglrandombinning',0.0_preal) !ToDo: useful default?
19995  ! if (rhoSglRandom(instance) < 0.0_pReal) &
19996  ! if (rhoSglRandomBinning(instance) <= 0.0_pReal) &
19997 
19998  prm%surfaceTransmissivity = config%getFloat('surfacetransmissivity',defaultval=1.0_preal)
19999  prm%grainboundaryTransmissivity = config%getFloat('grainboundarytransmissivity',defaultval=-1.0_preal)
20000  prm%fEdgeMultiplication = config%getFloat('edgemultiplication')
20001  prm%shortRangeStressCorrection = config%keyExists('/shortrangestresscorrection/')
20002 
20003 !--------------------------------------------------------------------------------------------------
20004 ! sanity checks
20005  if (any(prm%burgers < 0.0_preal)) extmsg = trim(extmsg)//' burgers'
20006  if (any(prm%lambda0 <= 0.0_preal)) extmsg = trim(extmsg)//' lambda0'
20007 
20008  if (any(ini%rhoSglEdgePos0 < 0.0_preal)) extmsg = trim(extmsg)//' rhoSglEdgePos0'
20009  if (any(ini%rhoSglEdgeNeg0 < 0.0_preal)) extmsg = trim(extmsg)//' rhoSglEdgeNeg0'
20010  if (any(ini%rhoSglScrewPos0 < 0.0_preal)) extmsg = trim(extmsg)//' rhoSglScrewPos0'
20011  if (any(ini%rhoSglScrewNeg0 < 0.0_preal)) extmsg = trim(extmsg)//' rhoSglScrewNeg0'
20012  if (any(ini%rhoDipEdge0 < 0.0_preal)) extmsg = trim(extmsg)//' rhoDipEdge0'
20013  if (any(ini%rhoDipScrew0 < 0.0_preal)) extmsg = trim(extmsg)//' rhoDipScrew0'
20014 
20015  if (any(prm%peierlsstress < 0.0_preal)) extmsg = trim(extmsg)//' peierlsstress'
20016  if (any(prm%minDipoleHeight < 0.0_preal)) extmsg = trim(extmsg)//' minDipoleHeight'
20017 
20018  if (prm%viscosity <= 0.0_preal) extmsg = trim(extmsg)//' viscosity'
20019  if (prm%selfDiffusionEnergy <= 0.0_preal) extmsg = trim(extmsg)//' selfDiffusionEnergy'
20020  if (prm%fattack <= 0.0_preal) extmsg = trim(extmsg)//' fattack'
20021  if (prm%doublekinkwidth <= 0.0_preal) extmsg = trim(extmsg)//' doublekinkwidth'
20022  if (prm%Dsd0 < 0.0_preal) extmsg = trim(extmsg)//' Dsd0'
20023  if (prm%atomicVolume <= 0.0_preal) extmsg = trim(extmsg)//' atomicVolume' ! ToDo: in disloUCLA, the atomic volume is given as a factor
20024 
20025  if (prm%significantN < 0.0_preal) extmsg = trim(extmsg)//' significantN'
20026  if (prm%significantrho < 0.0_preal) extmsg = trim(extmsg)//' significantrho'
20027  if (prm%atol_rho < 0.0_preal) extmsg = trim(extmsg)//' atol_rho'
20028  if (prm%CFLfactor < 0.0_preal) extmsg = trim(extmsg)//' CFLfactor'
20029 
20030  if (prm%p <= 0.0_preal .or. prm%p > 1.0_preal) extmsg = trim(extmsg)//' p'
20031  if (prm%q < 1.0_preal .or. prm%q > 2.0_preal) extmsg = trim(extmsg)//' q'
20032 
20033  if (prm%linetensionEffect < 0.0_preal .or. prm%linetensionEffect > 1.0_preal) &
20034  extmsg = trim(extmsg)//' linetensionEffect'
20035  if (prm%edgeJogFactor < 0.0_preal .or. prm%edgeJogFactor > 1.0_preal) &
20036  extmsg = trim(extmsg)//' edgeJogFactor'
20037 
20038  if (prm%solidSolutionEnergy <= 0.0_preal) extmsg = trim(extmsg)//' solidSolutionEnergy'
20039  if (prm%solidSolutionSize <= 0.0_preal) extmsg = trim(extmsg)//' solidSolutionSize'
20040  if (prm%solidSolutionConcentration <= 0.0_preal) extmsg = trim(extmsg)//' solidSolutionConcentration'
20041 
20042  if (prm%grainboundaryTransmissivity > 1.0_preal) extmsg = trim(extmsg)//' grainboundaryTransmissivity'
20043  if (prm%surfaceTransmissivity < 0.0_preal .or. prm%surfaceTransmissivity > 1.0_preal) &
20044  extmsg = trim(extmsg)//' surfaceTransmissivity'
20045 
20046  if (prm%fEdgeMultiplication < 0.0_preal .or. prm%fEdgeMultiplication > 1.0_preal) &
20047  extmsg = trim(extmsg)//' fEdgeMultiplication'
20048 
20049  endif slipactive
20050 
20051 !--------------------------------------------------------------------------------------------------
20052 ! allocate state arrays
20053  nipcmyphase = count(material_phaseat==p) * discretization_nip
20054  sizedotstate = size([ 'rhoSglEdgePosMobile ','rhoSglEdgeNegMobile ', &
20055  'rhoSglScrewPosMobile ','rhoSglScrewNegMobile ', &
20056  'rhoSglEdgePosImmobile ','rhoSglEdgeNegImmobile ', &
20057  'rhoSglScrewPosImmobile','rhoSglScrewNegImmobile', &
20058  'rhoDipEdge ','rhoDipScrew ', &
20059  'gamma ' ]) * prm%sum_N_sl
20060  sizedependentstate = size([ 'rhoForest ']) * prm%sum_N_sl
20061  sizestate = sizedotstate + sizedependentstate &
20062  + size([ 'velocityEdgePos ','velocityEdgeNeg ', &
20063  'velocityScrewPos ','velocityScrewNeg ', &
20064  'maxDipoleHeightEdge ','maxDipoleHeightScrew' ]) * prm%sum_N_sl
20065  sizedeltastate = sizedotstate
20066 
20067  call material_allocateplasticstate(p,nipcmyphase,sizestate,sizedotstate,sizedeltastate)
20068 
20069  plasticstate(p)%nonlocal = .true.
20070  plasticstate(p)%offsetDeltaState = 0 ! ToDo: state structure does not follow convention
20071 
20072  st0%rho => plasticstate(p)%state0 (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
20073  stt%rho => plasticstate(p)%state (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
20074  dot%rho => plasticstate(p)%dotState (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
20075  del%rho => plasticstate(p)%deltaState (0*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
20076  plasticstate(p)%atol(1:10*prm%sum_N_sl) = prm%atol_rho
20077 
20078  stt%rhoSgl => plasticstate(p)%state (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
20079  dot%rhoSgl => plasticstate(p)%dotState (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
20080  del%rhoSgl => plasticstate(p)%deltaState (0*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
20081 
20082  stt%rhoSglMobile => plasticstate(p)%state (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
20083  dot%rhoSglMobile => plasticstate(p)%dotState (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
20084  del%rhoSglMobile => plasticstate(p)%deltaState (0*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
20085 
20086  stt%rho_sgl_mob_edg_pos => plasticstate(p)%state (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:)
20087  dot%rho_sgl_mob_edg_pos => plasticstate(p)%dotState (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:)
20088  del%rho_sgl_mob_edg_pos => plasticstate(p)%deltaState (0*prm%sum_N_sl+1: 1*prm%sum_N_sl,:)
20089 
20090  stt%rho_sgl_mob_edg_neg => plasticstate(p)%state (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:)
20091  dot%rho_sgl_mob_edg_neg => plasticstate(p)%dotState (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:)
20092  del%rho_sgl_mob_edg_neg => plasticstate(p)%deltaState (1*prm%sum_N_sl+1: 2*prm%sum_N_sl,:)
20093 
20094  stt%rho_sgl_mob_scr_pos => plasticstate(p)%state (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:)
20095  dot%rho_sgl_mob_scr_pos => plasticstate(p)%dotState (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:)
20096  del%rho_sgl_mob_scr_pos => plasticstate(p)%deltaState (2*prm%sum_N_sl+1: 3*prm%sum_N_sl,:)
20097 
20098  stt%rho_sgl_mob_scr_neg => plasticstate(p)%state (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
20099  dot%rho_sgl_mob_scr_neg => plasticstate(p)%dotState (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
20100  del%rho_sgl_mob_scr_neg => plasticstate(p)%deltaState (3*prm%sum_N_sl+1: 4*prm%sum_N_sl,:)
20101 
20102  stt%rhoSglImmobile => plasticstate(p)%state (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
20103  dot%rhoSglImmobile => plasticstate(p)%dotState (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
20104  del%rhoSglImmobile => plasticstate(p)%deltaState (4*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
20105 
20106  stt%rho_sgl_imm_edg_pos => plasticstate(p)%state (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:)
20107  dot%rho_sgl_imm_edg_pos => plasticstate(p)%dotState (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:)
20108  del%rho_sgl_imm_edg_pos => plasticstate(p)%deltaState (4*prm%sum_N_sl+1: 5*prm%sum_N_sl,:)
20109 
20110  stt%rho_sgl_imm_edg_neg => plasticstate(p)%state (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:)
20111  dot%rho_sgl_imm_edg_neg => plasticstate(p)%dotState (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:)
20112  del%rho_sgl_imm_edg_neg => plasticstate(p)%deltaState (5*prm%sum_N_sl+1: 6*prm%sum_N_sl,:)
20113 
20114  stt%rho_sgl_imm_scr_pos => plasticstate(p)%state (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:)
20115  dot%rho_sgl_imm_scr_pos => plasticstate(p)%dotState (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:)
20116  del%rho_sgl_imm_scr_pos => plasticstate(p)%deltaState (6*prm%sum_N_sl+1: 7*prm%sum_N_sl,:)
20117 
20118  stt%rho_sgl_imm_scr_neg => plasticstate(p)%state (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
20119  dot%rho_sgl_imm_scr_neg => plasticstate(p)%dotState (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
20120  del%rho_sgl_imm_scr_neg => plasticstate(p)%deltaState (7*prm%sum_N_sl+1: 8*prm%sum_N_sl,:)
20121 
20122  stt%rhoDip => plasticstate(p)%state (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
20123  dot%rhoDip => plasticstate(p)%dotState (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
20124  del%rhoDip => plasticstate(p)%deltaState (8*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
20125 
20126  stt%rho_dip_edg => plasticstate(p)%state (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:)
20127  dot%rho_dip_edg => plasticstate(p)%dotState (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:)
20128  del%rho_dip_edg => plasticstate(p)%deltaState (8*prm%sum_N_sl+1: 9*prm%sum_N_sl,:)
20129 
20130  stt%rho_dip_scr => plasticstate(p)%state (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
20131  dot%rho_dip_scr => plasticstate(p)%dotState (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
20132  del%rho_dip_scr => plasticstate(p)%deltaState (9*prm%sum_N_sl+1:10*prm%sum_N_sl,:)
20133 
20134  stt%gamma => plasticstate(p)%state (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:nipcmyphase)
20135  dot%gamma => plasticstate(p)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:nipcmyphase)
20136  del%gamma => plasticstate(p)%deltaState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:nipcmyphase)
20137  plasticstate(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl ) = config%getFloat('atol_gamma', defaultval = 1.0e-2_preal)
20138  if(any(plasticstate(p)%atol(10*prm%sum_N_sl+1:11*prm%sum_N_sl) < 0.0_preal)) &
20139  extmsg = trim(extmsg)//' atol_gamma'
20140  plasticstate(p)%slipRate => plasticstate(p)%dotState (10*prm%sum_N_sl + 1:11*prm%sum_N_sl,1:nipcmyphase)
20141 
20142  stt%rho_forest => plasticstate(p)%state (11*prm%sum_N_sl + 1:12*prm%sum_N_sl,1:nipcmyphase)
20143  stt%v => plasticstate(p)%state (12*prm%sum_N_sl + 1:16*prm%sum_N_sl,1:nipcmyphase)
20144  stt%v_edg_pos => plasticstate(p)%state (12*prm%sum_N_sl + 1:13*prm%sum_N_sl,1:nipcmyphase)
20145  stt%v_edg_neg => plasticstate(p)%state (13*prm%sum_N_sl + 1:14*prm%sum_N_sl,1:nipcmyphase)
20146  stt%v_scr_pos => plasticstate(p)%state (14*prm%sum_N_sl + 1:15*prm%sum_N_sl,1:nipcmyphase)
20147  stt%v_scr_neg => plasticstate(p)%state (15*prm%sum_N_sl + 1:16*prm%sum_N_sl,1:nipcmyphase)
20148 
20149  allocate(dst%tau_pass(prm%sum_N_sl,nipcmyphase),source=0.0_preal)
20150  allocate(dst%tau_back(prm%sum_N_sl,nipcmyphase),source=0.0_preal)
20151  end associate
20152 
20153  if (nipcmyphase > 0) call stateinit(ini,p,nipcmyphase)
20154  plasticstate(p)%state0 = plasticstate(p)%state
20155 
20156 !--------------------------------------------------------------------------------------------------
20157 ! exit if any parameter is out of range
20158  if (extmsg /= '') call io_error(211,ext_msg=trim(extmsg)//'('//plasticity_nonlocal_label//')')
20159 
20160  enddo
20161 
20162  allocate(compatibility(2,maxval(param%sum_N_sl),maxval(param%sum_N_sl),nipneighbors,&
20163  discretization_nip,discretization_nelem), source=0.0_preal)
20164 
20165 ! BEGIN DEPRECATED----------------------------------------------------------------------------------
20166  allocate(irhou(maxval(param%sum_N_sl),4,ninstance), source=0)
20167  allocate(iv(maxval(param%sum_N_sl),4,ninstance), source=0)
20168  allocate(id(maxval(param%sum_N_sl),2,ninstance), source=0)
20169 
20170  initializeinstances: do p = 1, size(phase_plasticity)
20171  nipcmyphase = count(material_phaseat==p) * discretization_nip
20172  myphase2: if (phase_plasticity(p) == plasticity_nonlocal_id) then
20173  l = 0
20174  do t = 1,4
20175  do s = 1,param(phase_plasticityinstance(p))%sum_N_sl
20176  l = l + 1
20177  irhou(s,t,phase_plasticityinstance(p)) = l
20178  enddo
20179  enddo
20180  l = l + (4+2+1+1)*param(phase_plasticityinstance(p))%sum_N_sl ! immobile(4), dipole(2), shear, forest
20181  do t = 1,4
20182  do s = 1,param(phase_plasticityinstance(p))%sum_N_sl
20183  l = l + 1
20184  iv(s,t,phase_plasticityinstance(p)) = l
20185  enddo
20186  enddo
20187  do t = 1,2
20188  do s = 1,param(phase_plasticityinstance(p))%sum_N_sl
20189  l = l + 1
20190  id(s,t,phase_plasticityinstance(p)) = l
20191  enddo
20192  enddo
20193  if (id(param(phase_plasticityinstance(p))%sum_N_sl,2,phase_plasticityinstance(p)) /= plasticstate(p)%sizeState) &
20194  call io_error(0, ext_msg = 'state indices not properly set ('//plasticity_nonlocal_label//')')
20195  endif myphase2
20196  enddo initializeinstances
20197 
20198 end subroutine plastic_nonlocal_init
20199 
20200 
20201 !--------------------------------------------------------------------------------------------------
20203 !--------------------------------------------------------------------------------------------------
20204 module subroutine plastic_nonlocal_dependentstate(f, fp, instance, of, ip, el)
20205 
20206  real(preal), dimension(3,3), intent(in) :: &
20207  f, &
20208  fp
20209  integer, intent(in) :: &
20210  instance, &
20211  of, &
20212  ip, &
20213  el
20214 
20215  integer :: &
20216  no, & !< neighbor offset
20217  neighbor_el, & ! element number of neighboring material point
20218  neighbor_ip, & ! integration point of neighboring material point
20219  neighbor_instance, & ! instance of this plasticity of neighboring material point
20220  c, & ! index of dilsocation character (edge, screw)
20221  s, & ! slip system index
20222  dir, &
20223  n
20224  real(preal) :: &
20225  fvsize, &
20226  nrealneighbors ! number of really existing neighbors
20227  integer, dimension(2) :: &
20228  neighbors
20229  real(preal), dimension(2) :: &
20230  rhoexcessgradient, &
20231  rhoexcessgradient_over_rho, &
20232  rhototal
20233  real(preal), dimension(3) :: &
20234  rhoexcessdifferences, &
20235  normal_latticeconf
20236  real(preal), dimension(3,3) :: &
20237  invfe, & !< inverse of elastic deformation gradient
20238  invfp, & !< inverse of plastic deformation gradient
20239  connections, &
20240  invconnections
20241  real(preal), dimension(3,nIPneighbors) :: &
20242  connection_latticeconf
20243  real(preal), dimension(2,param(instance)%sum_N_sl) :: &
20244  rhoexcess
20245  real(preal), dimension(param(instance)%sum_N_sl) :: &
20246  rho_edg_delta, &
20247  rho_scr_delta
20248  real(preal), dimension(param(instance)%sum_N_sl,10) :: &
20249  rho, &
20250  rho0, &
20251  rho_neighbor0
20252  real(preal), dimension(param(instance)%sum_N_sl,param(instance)%sum_N_sl) :: &
20253  myinteractionmatrix ! corrected slip interaction matrix
20254  real(preal), dimension(param(instance)%sum_N_sl,nIPneighbors) :: &
20255  rho_edg_delta_neighbor, &
20256  rho_scr_delta_neighbor
20257  real(preal), dimension(2,maxval(param%sum_N_sl),nIPneighbors) :: &
20258  neighbor_rhoexcess, & ! excess density at neighboring material point
20259  neighbor_rhototal ! total density at neighboring material point
20260  real(preal), dimension(3,param(instance)%sum_N_sl,2) :: &
20261  m ! direction of dislocation motion
20262 
20263  associate(prm => param(instance),dst => microstructure(instance), stt => state(instance))
20264 
20265  rho = getrho(instance,of,ip,el)
20266 
20267  stt%rho_forest(:,of) = matmul(prm%forestProjection_Edge, sum(abs(rho(:,edg)),2)) &
20268  + matmul(prm%forestProjection_Screw,sum(abs(rho(:,scr)),2))
20269 
20270 
20271  ! coefficients are corrected for the line tension effect
20272  ! (see Kubin,Devincre,Hoc; 2008; Modeling dislocation storage rates and mean free paths in face-centered cubic crystals)
20273  if (any(lattice_structure(material_phaseat(1,el)) == [lattice_bcc_id,lattice_fcc_id])) then
20274  myinteractionmatrix = prm%interactionSlipSlip &
20275  * spread(( 1.0_preal - prm%linetensionEffect &
20276  + prm%linetensionEffect &
20277  * log(0.35_preal * prm%burgers * sqrt(max(stt%rho_forest(:,of),prm%significantRho))) &
20278  / log(0.35_preal * prm%burgers * 1e6_preal))** 2.0_preal,2,prm%sum_N_sl)
20279  else
20280  myinteractionmatrix = prm%interactionSlipSlip
20281  endif
20282 
20283  dst%tau_pass(:,of) = prm%mu * prm%burgers &
20284  * sqrt(matmul(myinteractionmatrix,sum(abs(rho),2)))
20285 
20286 !*** calculate the dislocation stress of the neighboring excess dislocation densities
20287 !*** zero for material points of local plasticity
20288 
20289  !#################################################################################################
20290  ! ToDo: MD: this is most likely only correct for F_i = I
20291  !#################################################################################################
20292 
20293  rho0 = getrho0(instance,of,ip,el)
20294  if (.not. phase_localplasticity(material_phaseat(1,el)) .and. prm%shortRangeStressCorrection) then
20295  invfp = math_inv33(fp)
20296  invfe = matmul(fp,math_inv33(f))
20297 
20298  rho_edg_delta = rho0(:,mob_edg_pos) - rho0(:,mob_edg_neg)
20299  rho_scr_delta = rho0(:,mob_scr_pos) - rho0(:,mob_scr_neg)
20300 
20301  rhoexcess(1,:) = rho_edg_delta
20302  rhoexcess(2,:) = rho_scr_delta
20303 
20304  fvsize = ipvolume(ip,el) ** (1.0_preal/3.0_preal)
20305 
20306  !* loop through my neighborhood and get the connection vectors (in lattice frame) and the excess densities
20307 
20308  nrealneighbors = 0.0_preal
20309  neighbor_rhototal = 0.0_preal
20310  do n = 1,nipneighbors
20311  neighbor_el = ipneighborhood(1,n,ip,el)
20312  neighbor_ip = ipneighborhood(2,n,ip,el)
20313  no = material_phasememberat(1,neighbor_ip,neighbor_el)
20314  if (neighbor_el > 0 .and. neighbor_ip > 0) then
20315  neighbor_instance = phase_plasticityinstance(material_phaseat(1,neighbor_el))
20316  if (neighbor_instance == instance) then
20317 
20318  nrealneighbors = nrealneighbors + 1.0_preal
20319  rho_neighbor0 = getrho0(instance,no,neighbor_ip,neighbor_el)
20320 
20321  rho_edg_delta_neighbor(:,n) = rho_neighbor0(:,mob_edg_pos) - rho_neighbor0(:,mob_edg_neg)
20322  rho_scr_delta_neighbor(:,n) = rho_neighbor0(:,mob_scr_pos) - rho_neighbor0(:,mob_scr_neg)
20323 
20324  neighbor_rhototal(1,:,n) = sum(abs(rho_neighbor0(:,edg)),2)
20325  neighbor_rhototal(2,:,n) = sum(abs(rho_neighbor0(:,scr)),2)
20326 
20327  connection_latticeconf(1:3,n) = matmul(invfe, discretization_ipcoords(1:3,neighbor_el+neighbor_ip-1) &
20328  - discretization_ipcoords(1:3,el+neighbor_ip-1))
20329  normal_latticeconf = matmul(transpose(invfp), ipareanormal(1:3,n,ip,el))
20330  if (math_inner(normal_latticeconf,connection_latticeconf(1:3,n)) < 0.0_preal) & ! neighboring connection points in opposite direction to face normal: must be periodic image
20331  connection_latticeconf(1:3,n) = normal_latticeconf * ipvolume(ip,el)/iparea(n,ip,el) ! instead take the surface normal scaled with the diameter of the cell
20332  else
20333  ! local neighbor or different lattice structure or different constitution instance -> use central values instead
20334  connection_latticeconf(1:3,n) = 0.0_preal
20335  rho_edg_delta_neighbor(:,n) = rho_edg_delta
20336  rho_scr_delta_neighbor(:,n) = rho_scr_delta
20337  endif
20338  else
20339  ! free surface -> use central values instead
20340  connection_latticeconf(1:3,n) = 0.0_preal
20341  rho_edg_delta_neighbor(:,n) = rho_edg_delta
20342  rho_scr_delta_neighbor(:,n) = rho_scr_delta
20343  endif
20344  enddo
20345 
20346  neighbor_rhoexcess(1,:,:) = rho_edg_delta_neighbor
20347  neighbor_rhoexcess(2,:,:) = rho_scr_delta_neighbor
20348 
20349  !* loop through the slip systems and calculate the dislocation gradient by
20350  !* 1. interpolation of the excess density in the neighorhood
20351  !* 2. interpolation of the dead dislocation density in the central volume
20352  m(1:3,:,1) = prm%slip_direction
20353  m(1:3,:,2) = -prm%slip_transverse
20354 
20355  do s = 1,prm%sum_N_sl
20356 
20357  ! gradient from interpolation of neighboring excess density ...
20358  do c = 1,2
20359  do dir = 1,3
20360  neighbors(1) = 2 * dir - 1
20361  neighbors(2) = 2 * dir
20362  connections(dir,1:3) = connection_latticeconf(1:3,neighbors(1)) &
20363  - connection_latticeconf(1:3,neighbors(2))
20364  rhoexcessdifferences(dir) = neighbor_rhoexcess(c,s,neighbors(1)) &
20365  - neighbor_rhoexcess(c,s,neighbors(2))
20366  enddo
20367  invconnections = math_inv33(connections)
20368  if (all(deq0(invconnections))) call io_error(-1,ext_msg='back stress calculation: inversion error')
20369 
20370  rhoexcessgradient(c) = math_inner(m(1:3,s,c), matmul(invconnections,rhoexcessdifferences))
20371  enddo
20372 
20373  ! ... plus gradient from deads ...
20374  rhoexcessgradient(1) = rhoexcessgradient(1) + sum(rho(s,imm_edg)) / fvsize
20375  rhoexcessgradient(2) = rhoexcessgradient(2) + sum(rho(s,imm_scr)) / fvsize
20376 
20377  ! ... normalized with the total density ...
20378  rhototal(1) = (sum(abs(rho(s,edg))) + sum(neighbor_rhototal(1,s,:))) / (1.0_preal + nrealneighbors)
20379  rhototal(2) = (sum(abs(rho(s,scr))) + sum(neighbor_rhototal(2,s,:))) / (1.0_preal + nrealneighbors)
20380 
20381  rhoexcessgradient_over_rho = 0.0_preal
20382  where(rhototal > 0.0_preal) rhoexcessgradient_over_rho = rhoexcessgradient / rhototal
20383 
20384  ! ... gives the local stress correction when multiplied with a factor
20385  dst%tau_back(s,of) = - prm%mu * prm%burgers(s) / (2.0_preal * pi) &
20386  * ( rhoexcessgradient_over_rho(1) / (1.0_preal - prm%nu) &
20387  + rhoexcessgradient_over_rho(2))
20388  enddo
20389  endif
20390 
20391 # 721 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90"
20392 
20393  end associate
20394 
20395 end subroutine plastic_nonlocal_dependentstate
20396 
20397 
20398 !--------------------------------------------------------------------------------------------------
20400 !--------------------------------------------------------------------------------------------------
20401 module subroutine plastic_nonlocal_lpanditstangent(lp,dlp_dmp, &
20402  mp,temperature,instance,of,ip,el)
20403  real(preal), dimension(3,3), intent(out) :: &
20404  lp
20405  real(preal), dimension(3,3,3,3), intent(out) :: &
20406  dlp_dmp
20407  integer, intent(in) :: &
20408  instance, &
20409  of, &
20410  ip, & !< current integration point
20411  el
20412  real(preal), intent(in) :: &
20413  temperature
20414 
20415  real(preal), dimension(3,3), intent(in) :: &
20416  mp
20417 
20418  integer :: &
20419  ns, & !< short notation for the total number of active slip systems
20420  i, &
20421  j, &
20422  k, &
20423  l, &
20424  t, & !< dislocation type
20425  s
20426  real(preal), dimension(param(instance)%sum_N_sl,8) :: &
20427  rhosgl
20428  real(preal), dimension(param(instance)%sum_N_sl,10) :: &
20429  rho
20430  real(preal), dimension(param(instance)%sum_N_sl,4) :: &
20431  v, & !< velocity
20432  tauns, & !< resolved shear stress including non Schmid and backstress terms
20433  dv_dtau, & !< velocity derivative with respect to the shear stress
20434  dv_dtauns
20435  real(preal), dimension(param(instance)%sum_N_sl) :: &
20436  tau, & !< resolved shear stress including backstress terms
20437  gdottotal
20438 
20439  associate(prm => param(instance),dst=>microstructure(instance),stt=>state(instance))
20440  ns = prm%sum_N_sl
20441 
20442  !*** shortcut to state variables
20443  rho = getrho(instance,of,ip,el)
20444  rhosgl = rho(:,sgl)
20445 
20446  do s = 1,ns
20447  tau(s) = math_tensordot(mp, prm%Schmid(1:3,1:3,s))
20448  tauns(s,1) = tau(s)
20449  tauns(s,2) = tau(s)
20450  if (tau(s) > 0.0_preal) then
20451  tauns(s,3) = math_tensordot(mp, +prm%nonSchmid_pos(1:3,1:3,s))
20452  tauns(s,4) = math_tensordot(mp, -prm%nonSchmid_neg(1:3,1:3,s))
20453  else
20454  tauns(s,3) = math_tensordot(mp, +prm%nonSchmid_neg(1:3,1:3,s))
20455  tauns(s,4) = math_tensordot(mp, -prm%nonSchmid_pos(1:3,1:3,s))
20456  endif
20457  enddo
20458  tauns = tauns + spread(dst%tau_back(:,of),2,4)
20459  tau = tau + dst%tau_back(:,of)
20460 
20461  ! edges
20462  call kinetics(v(:,1), dv_dtau(:,1), dv_dtauns(:,1), &
20463  tau, tauns(:,1), dst%tau_pass(:,of),1,temperature, instance)
20464  v(:,2) = v(:,1)
20465  dv_dtau(:,2) = dv_dtau(:,1)
20466  dv_dtauns(:,2) = dv_dtauns(:,1)
20467 
20468  !screws
20469  if (prm%nonSchmidActive) then
20470  v(:,3:4) = spread(v(:,1),2,2)
20471  dv_dtau(:,3:4) = spread(dv_dtau(:,1),2,2)
20472  dv_dtauns(:,3:4) = spread(dv_dtauns(:,1),2,2)
20473  else
20474  do t = 3,4
20475  call kinetics(v(:,t), dv_dtau(:,t), dv_dtauns(:,t), &
20476  tau, tauns(:,t), dst%tau_pass(:,of),2,temperature, instance)
20477  enddo
20478  endif
20479 
20480  stt%v(:,of) = pack(v,.true.)
20481 
20482  !*** Bauschinger effect
20483  forall (s = 1:ns, t = 5:8, rhosgl(s,t) * v(s,t-4) < 0.0_preal) &
20484  rhosgl(s,t-4) = rhosgl(s,t-4) + abs(rhosgl(s,t))
20485 
20486  gdottotal = sum(rhosgl(:,1:4) * v, 2) * prm%burgers
20487 
20488  lp = 0.0_preal
20489  dlp_dmp = 0.0_preal
20490  do s = 1,ns
20491  lp = lp + gdottotal(s) * prm%Schmid(1:3,1:3,s)
20492  forall (i=1:3,j=1:3,k=1:3,l=1:3) &
20493  dlp_dmp(i,j,k,l) = dlp_dmp(i,j,k,l) &
20494  + prm%Schmid(i,j,s) * prm%Schmid(k,l,s) &
20495  * sum(rhosgl(s,1:4) * dv_dtau(s,1:4)) * prm%burgers(s) &
20496  + prm%Schmid(i,j,s) &
20497  * ( prm%nonSchmid_pos(k,l,s) * rhosgl(s,3) * dv_dtauns(s,3) &
20498  - prm%nonSchmid_neg(k,l,s) * rhosgl(s,4) * dv_dtauns(s,4)) * prm%burgers(s)
20499  enddo
20500 
20501  end associate
20502 
20503 end subroutine plastic_nonlocal_lpanditstangent
20504 
20505 
20506 !--------------------------------------------------------------------------------------------------
20508 !--------------------------------------------------------------------------------------------------
20509 module subroutine plastic_nonlocal_deltastate(mp,instance,of,ip,el)
20510 
20511  real(preal), dimension(3,3), intent(in) :: &
20512  mp
20513  integer, intent(in) :: &
20514  instance, & ! current instance of this plasticity
20515  of, & !< offset
20516  ip, &
20517  el
20518 
20519  integer :: &
20520  ph, & !< phase
20521  ns, & ! short notation for the total number of active slip systems
20522  c, & ! character of dislocation
20523  t, & ! type of dislocation
20524  s ! index of my current slip system
20525  real(preal), dimension(param(instance)%sum_N_sl,10) :: &
20526  deltarhoremobilization, & ! density increment by remobilization
20527  deltarhodipole2singlestress ! density increment by dipole dissociation (by stress change)
20528  real(preal), dimension(param(instance)%sum_N_sl,10) :: &
20529  rho ! current dislocation densities
20530  real(preal), dimension(param(instance)%sum_N_sl,4) :: &
20531  v ! dislocation glide velocity
20532  real(preal), dimension(param(instance)%sum_N_sl) :: &
20533  tau ! current resolved shear stress
20534  real(preal), dimension(param(instance)%sum_N_sl,2) :: &
20535  rhodip, & ! current dipole dislocation densities (screw and edge dipoles)
20536  dupper, & ! current maximum stable dipole distance for edges and screws
20537  dupperold, & ! old maximum stable dipole distance for edges and screws
20538  deltadupper ! change in maximum stable dipole distance for edges and screws
20539 
20540  ph = material_phaseat(1,el)
20541 
20542  associate(prm => param(instance),dst => microstructure(instance),del => deltastate(instance))
20543  ns = prm%sum_N_sl
20544 
20545  !*** shortcut to state variables
20546  forall (s = 1:ns, t = 1:4) v(s,t) = plasticstate(ph)%state(iv(s,t,instance),of)
20547  forall (s = 1:ns, c = 1:2) dupperold(s,c) = plasticstate(ph)%state(id(s,c,instance),of)
20548 
20549  rho = getrho(instance,of,ip,el)
20550  rhodip = rho(:,dip)
20551 
20552  !****************************************************************************
20553  !*** dislocation remobilization (bauschinger effect)
20554  where(rho(:,imm) * v < 0.0_preal)
20555  deltarhoremobilization(:,mob) = abs(rho(:,imm))
20556  deltarhoremobilization(:,imm) = - rho(:,imm)
20557  rho(:,mob) = rho(:,mob) + abs(rho(:,imm))
20558  rho(:,imm) = 0.0_preal
20559  elsewhere
20560  deltarhoremobilization(:,mob) = 0.0_preal
20561  deltarhoremobilization(:,imm) = 0.0_preal
20562  endwhere
20563  deltarhoremobilization(:,dip) = 0.0_preal
20564 
20565  !****************************************************************************
20566  !*** calculate dipole formation and dissociation by stress change
20567 
20568  !*** calculate limits for stable dipole height
20569  do s = 1,prm%sum_N_sl
20570  tau(s) = math_tensordot(mp, prm%Schmid(1:3,1:3,s)) +dst%tau_back(s,of)
20571  if (abs(tau(s)) < 1.0e-15_preal) tau(s) = 1.0e-15_preal
20572  enddo
20573 
20574  dupper(:,1) = prm%mu * prm%burgers/(8.0_preal * pi * (1.0_preal - prm%nu) * abs(tau))
20575  dupper(:,2) = prm%mu * prm%burgers/(4.0_preal * pi * abs(tau))
20576 
20577  where(dneq0(sqrt(sum(abs(rho(:,edg)),2)))) &
20578  dupper(:,1) = min(1.0_preal/sqrt(sum(abs(rho(:,edg)),2)),dupper(:,1))
20579  where(dneq0(sqrt(sum(abs(rho(:,scr)),2)))) &
20580  dupper(:,2) = min(1.0_preal/sqrt(sum(abs(rho(:,scr)),2)),dupper(:,2))
20581 
20582  dupper = max(dupper,prm%minDipoleHeight)
20583  deltadupper = dupper - dupperold
20584 
20585 
20586  !*** dissociation by stress increase
20587  deltarhodipole2singlestress = 0.0_preal
20588  forall (c=1:2, s=1:ns, deltadupper(s,c) < 0.0_preal .and. &
20589  dneq0(dupperold(s,c) - prm%minDipoleHeight(s,c))) &
20590  deltarhodipole2singlestress(s,8+c) = rhodip(s,c) * deltadupper(s,c) &
20591  / (dupperold(s,c) - prm%minDipoleHeight(s,c))
20592 
20593  forall (t=1:4) deltarhodipole2singlestress(:,t) = -0.5_preal * deltarhodipole2singlestress(:,(t-1)/2+9)
20594  forall (s = 1:ns, c = 1:2) plasticstate(ph)%state(id(s,c,instance),of) = dupper(s,c)
20595 
20596  plasticstate(ph)%deltaState(:,of) = 0.0_preal
20597  del%rho(:,of) = reshape(deltarhoremobilization + deltarhodipole2singlestress, [10*ns])
20598 
20599 # 936 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90"
20600 
20601  end associate
20602 
20603 end subroutine plastic_nonlocal_deltastate
20604 
20605 
20606 !---------------------------------------------------------------------------------------------------
20608 !---------------------------------------------------------------------------------------------------
20609 module subroutine plastic_nonlocal_dotstate(mp, f, fp, temperature,timestep, &
20610  instance,of,ip,el)
20611 
20612  real(preal), dimension(3,3), intent(in) :: &
20613  mp
20614  real(preal), dimension(3,3,homogenization_maxNgrains,discretization_nIP,discretization_nElem), intent(in) :: &
20615  f, & !< elastic deformation gradient
20616  fp
20617  real(preal), intent(in) :: &
20618  temperature, & !< temperature
20619  timestep
20620  integer, intent(in) :: &
20621  instance, &
20622  of, &
20623  ip, & !< current integration point
20624  el
20625 
20626  integer :: &
20627  ph, &
20628  neighbor_instance, & !< instance of my neighbor's plasticity
20629  ns, & !< short notation for the total number of active slip systems
20630  c, & !< character of dislocation
20631  n, & !< index of my current neighbor
20632  neighbor_el, & !< element number of my neighbor
20633  neighbor_ip, & !< integration point of my neighbor
20634  neighbor_n, & !< neighbor index pointing to me when looking from my neighbor
20635  opposite_neighbor, & !< index of my opposite neighbor
20636  opposite_ip, & !< ip of my opposite neighbor
20637  opposite_el, & !< element index of my opposite neighbor
20638  opposite_n, & !< neighbor index pointing to me when looking from my opposite neighbor
20639  t, & !< type of dislocation
20640  no,& !< neighbor offset shortcut
20641  np,& !< neighbor phase shortcut
20642  topp, & !< type of dislocation with opposite sign to t
20643  s !< index of my current slip system
20644  real(pReal), dimension(param(instance)%sum_N_sl,10) :: &
20645  rho, &
20646  rho0, & !< dislocation density at beginning of time step
20647  rhoDot, & !< density evolution
20648  rhoDotMultiplication, & !< density evolution by multiplication
20649  rhoDotFlux, & !< density evolution by flux
20650  rhoDotSingle2DipoleGlide, & !< density evolution by dipole formation (by glide)
20651  rhoDotAthermalAnnihilation, & !< density evolution by athermal annihilation
20652  rhoDotThermalAnnihilation !< density evolution by thermal annihilation
20653  real(pReal), dimension(param(instance)%sum_N_sl,8) :: &
20654  rhoSgl, & !< current single dislocation densities (positive/negative screw and edge without dipoles)
20655  neighbor_rhoSgl0, & !< current single dislocation densities of neighboring ip (positive/negative screw and edge without dipoles)
20656  my_rhoSgl0 !< single dislocation densities of central ip (positive/negative screw and edge without dipoles)
20657  real(pReal), dimension(param(instance)%sum_N_sl,4) :: &
20658  v, & !< current dislocation glide velocity
20659  v0, &
20660  neighbor_v0, & !< dislocation glide velocity of enighboring ip
20661  gdot !< shear rates
20662  real(pReal), dimension(param(instance)%sum_N_sl) :: &
20663  tau, & !< current resolved shear stress
20664  vClimb !< climb velocity of edge dipoles
20665  real(pReal), dimension(param(instance)%sum_N_sl,2) :: &
20666  rhoDip, & !< current dipole dislocation densities (screw and edge dipoles)
20667  dLower, & !< minimum stable dipole distance for edges and screws
20668  dUpper !< current maximum stable dipole distance for edges and screws
20669  real(pReal), dimension(3,param(instance)%sum_N_sl,4) :: &
20670  m !< direction of dislocation motion
20671  real(pReal), dimension(3,3) :: &
20672  my_F, & !< my total deformation gradient
20673  neighbor_F, & !< total deformation gradient of my neighbor
20674  my_Fe, & !< my elastic deformation gradient
20675  neighbor_Fe, & !< elastic deformation gradient of my neighbor
20676  Favg !< average total deformation gradient of me and my neighbor
20677  real(pReal), dimension(3) :: &
20678  normal_neighbor2me, & !< interface normal pointing from my neighbor to me in neighbor's lattice configuration
20679  normal_neighbor2me_defconf, & !< interface normal pointing from my neighbor to me in shared deformed configuration
20680  normal_me2neighbor, & !< interface normal pointing from me to my neighbor in my lattice configuration
20681  normal_me2neighbor_defconf
20682  real(preal) :: &
20683  area, & !< area of the current interface
20684  transmissivity, & !< overall transmissivity of dislocation flux to neighboring material point
20685  linelength, & !< dislocation line length leaving the current interface
20686  selfdiffusion
20687 
20688  ph = material_phaseat(1,el)
20689  if (timestep <= 0.0_preal) then
20690  plasticstate(ph)%dotState = 0.0_preal
20691  return
20692  endif
20693 
20694  associate(prm => param(instance), &
20695  dst => microstructure(instance), &
20696  dot => dotstate(instance), &
20697  stt => state(instance))
20698  ns = prm%sum_N_sl
20699 
20700  tau = 0.0_preal
20701  gdot = 0.0_preal
20702 
20703  rho = getrho(instance,of,ip,el)
20704  rhosgl = rho(:,sgl)
20705  rhodip = rho(:,dip)
20706  rho0 = getrho0(instance,of,ip,el)
20707  my_rhosgl0 = rho0(:,sgl)
20708 
20709  forall (s = 1:ns, t = 1:4) v(s,t) = plasticstate(ph)%state(iv(s,t,instance),of)
20710  gdot = rhosgl(:,1:4) * v * spread(prm%burgers,2,4)
20711 
20712 # 1056 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90"
20713 
20714  !****************************************************************************
20715  !*** limits for stable dipole height
20716  do s = 1,ns
20717  tau(s) = math_tensordot(mp, prm%Schmid(1:3,1:3,s)) + dst%tau_back(s,of)
20718  if (abs(tau(s)) < 1.0e-15_preal) tau(s) = 1.0e-15_preal
20719  enddo
20720 
20721  dlower = prm%minDipoleHeight
20722  dupper(:,1) = prm%mu * prm%burgers/(8.0_preal * pi * (1.0_preal - prm%nu) * abs(tau))
20723  dupper(:,2) = prm%mu * prm%burgers/(4.0_preal * pi * abs(tau))
20724 
20725  where(dneq0(sqrt(sum(abs(rho(:,edg)),2)))) &
20726  dupper(:,1) = min(1.0_preal/sqrt(sum(abs(rho(:,edg)),2)),dupper(:,1))
20727  where(dneq0(sqrt(sum(abs(rho(:,scr)),2)))) &
20728  dupper(:,2) = min(1.0_preal/sqrt(sum(abs(rho(:,scr)),2)),dupper(:,2))
20729 
20730  dupper = max(dupper,dlower)
20731 
20732  !****************************************************************************
20733  !*** dislocation multiplication
20734  rhodotmultiplication = 0.0_preal
20735  isbcc: if (lattice_structure(ph) == lattice_bcc_id) then
20736  forall (s = 1:ns, sum(abs(v(s,1:4))) > 0.0_preal)
20737  rhodotmultiplication(s,1:2) = sum(abs(gdot(s,3:4))) / prm%burgers(s) & ! assuming double-cross-slip of screws to be decisive for multiplication
20738  * sqrt(stt%rho_forest(s,of)) / prm%lambda0(s) ! & ! mean free path
20739  ! * 2.0_pReal * sum(abs(v(s,3:4))) / sum(abs(v(s,1:4))) ! ratio of screw to overall velocity determines edge generation
20740  rhodotmultiplication(s,3:4) = sum(abs(gdot(s,3:4))) /prm%burgers(s) & ! assuming double-cross-slip of screws to be decisive for multiplication
20741  * sqrt(stt%rho_forest(s,of)) / prm%lambda0(s) ! & ! mean free path
20742  ! * 2.0_pReal * sum(abs(v(s,1:2))) / sum(abs(v(s,1:4))) ! ratio of edge to overall velocity determines screw generation
20743  endforall
20744 
20745  else isbcc
20746  rhodotmultiplication(:,1:4) = spread( &
20747  (sum(abs(gdot(:,1:2)),2) * prm%fEdgeMultiplication + sum(abs(gdot(:,3:4)),2)) &
20748  * sqrt(stt%rho_forest(:,of)) / prm%lambda0 / prm%burgers, 2, 4)
20749  endif isbcc
20750 
20751  forall (s = 1:ns, t = 1:4) v0(s,t) = plasticstate(ph)%state0(iv(s,t,instance),of)
20752 
20753  !****************************************************************************
20754  !*** calculate dislocation fluxes (only for nonlocal plasticity)
20755  rhodotflux = 0.0_preal
20756  if (.not. phase_localplasticity(material_phaseat(1,el))) then
20757 
20758  !*** check CFL (Courant-Friedrichs-Lewy) condition for flux
20759  if (any( abs(gdot) > 0.0_preal & ! any active slip system ...
20760  .and. prm%CFLfactor * abs(v0) * timestep &
20761  > ipvolume(ip,el) / maxval(iparea(:,ip,el)))) then ! ...with velocity above critical value (we use the reference volume and area for simplicity here)
20762 # 1116 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90"
20763  plasticstate(ph)%dotState = ieee_value(1.0_preal,ieee_quiet_nan) ! -> return NaN and, hence, enforce cutback
20764  return
20765  endif
20766 
20767 
20768  !*** be aware of the definition of slip_transverse = slip_direction x slip_normal !!!
20769  !*** opposite sign to our t vector in the (s,t,n) triplet !!!
20770 
20771  m(1:3,:,1) = prm%slip_direction
20772  m(1:3,:,2) = -prm%slip_direction
20773  m(1:3,:,3) = -prm%slip_transverse
20774  m(1:3,:,4) = prm%slip_transverse
20775 
20776  my_f = f(1:3,1:3,1,ip,el)
20777  my_fe = matmul(my_f, math_inv33(fp(1:3,1:3,1,ip,el)))
20778 
20779  neighbors: do n = 1,nipneighbors
20780 
20781  neighbor_el = ipneighborhood(1,n,ip,el)
20782  neighbor_ip = ipneighborhood(2,n,ip,el)
20783  neighbor_n = ipneighborhood(3,n,ip,el)
20784  np = material_phaseat(1,neighbor_el)
20785  no = material_phasememberat(1,neighbor_ip,neighbor_el)
20786 
20787  opposite_neighbor = n + mod(n,2) - mod(n+1,2)
20788  opposite_el = ipneighborhood(1,opposite_neighbor,ip,el)
20789  opposite_ip = ipneighborhood(2,opposite_neighbor,ip,el)
20790  opposite_n = ipneighborhood(3,opposite_neighbor,ip,el)
20791 
20792  if (neighbor_n > 0) then ! if neighbor exists, average deformation gradient
20793  neighbor_instance = phase_plasticityinstance(material_phaseat(1,neighbor_el))
20794  neighbor_f = f(1:3,1:3,1,neighbor_ip,neighbor_el)
20795  neighbor_fe = matmul(neighbor_f, math_inv33(fp(1:3,1:3,1,neighbor_ip,neighbor_el)))
20796  favg = 0.5_preal * (my_f + neighbor_f)
20797  else ! if no neighbor, take my value as average
20798  favg = my_f
20799  endif
20800 
20801  neighbor_v0 = 0.0_preal ! needed for check of sign change in flux density below
20802 
20803  !* FLUX FROM MY NEIGHBOR TO ME
20804  !* This is only considered, if I have a neighbor of nonlocal plasticity
20805  !* (also nonlocal constitutive law with local properties) that is at least a little bit
20806  !* compatible.
20807  !* If it's not at all compatible, no flux is arriving, because everything is dammed in front of
20808  !* my neighbor's interface.
20809  !* The entering flux from my neighbor will be distributed on my slip systems according to the
20810  !* compatibility
20811  if (neighbor_n > 0) then
20812  if (phase_plasticity(material_phaseat(1,neighbor_el)) == plasticity_nonlocal_id .and. &
20813  any(compatibility(:,:,:,n,ip,el) > 0.0_preal)) then
20814 
20815  forall (s = 1:ns, t = 1:4)
20816  neighbor_v0(s,t) = plasticstate(np)%state0(iv(s,t,neighbor_instance),no)
20817  neighbor_rhosgl0(s,t) = max(plasticstate(np)%state0(irhou(s,t,neighbor_instance),no),0.0_preal)
20818  endforall
20819 
20820  where (neighbor_rhosgl0 * ipvolume(neighbor_ip,neighbor_el) ** 0.667_preal < prm%significantN &
20821  .or. neighbor_rhosgl0 < prm%significantRho) &
20822  neighbor_rhosgl0 = 0.0_preal
20823  normal_neighbor2me_defconf = math_det33(favg) * matmul(math_inv33(transpose(favg)), &
20824  ipareanormal(1:3,neighbor_n,neighbor_ip,neighbor_el)) ! normal of the interface in (average) deformed configuration (pointing neighbor => me)
20825  normal_neighbor2me = matmul(transpose(neighbor_fe), normal_neighbor2me_defconf) &
20826  / math_det33(neighbor_fe) ! interface normal in the lattice configuration of my neighbor
20827  area = iparea(neighbor_n,neighbor_ip,neighbor_el) * norm2(normal_neighbor2me)
20828  normal_neighbor2me = normal_neighbor2me / norm2(normal_neighbor2me) ! normalize the surface normal to unit length
20829  do s = 1,ns
20830  do t = 1,4
20831  c = (t + 1) / 2
20832  topp = t + mod(t,2) - mod(t+1,2)
20833  if (neighbor_v0(s,t) * math_inner(m(1:3,s,t), normal_neighbor2me) > 0.0_preal & ! flux from my neighbor to me == entering flux for me
20834  .and. v0(s,t) * neighbor_v0(s,t) >= 0.0_preal ) then ! ... only if no sign change in flux density
20835  linelength = neighbor_rhosgl0(s,t) * neighbor_v0(s,t) &
20836  * math_inner(m(1:3,s,t), normal_neighbor2me) * area ! positive line length that wants to enter through this interface
20837  where (compatibility(c,:,s,n,ip,el) > 0.0_preal) &
20838  rhodotflux(:,t) = rhodotflux(1:ns,t) &
20839  + linelength/ipvolume(ip,el)*compatibility(c,:,s,n,ip,el)**2.0_preal ! transferring to equally signed mobile dislocation type
20840  where (compatibility(c,:,s,n,ip,el) < 0.0_preal) &
20841  rhodotflux(:,topp) = rhodotflux(:,topp) &
20842  + linelength/ipvolume(ip,el)*compatibility(c,:,s,n,ip,el)**2.0_preal ! transferring to opposite signed mobile dislocation type
20843 
20844  endif
20845  enddo
20846  enddo
20847  endif; endif
20848 
20849 
20850  !* FLUX FROM ME TO MY NEIGHBOR
20851  !* This is not considered, if my opposite neighbor has a different constitutive law than nonlocal (still considered for nonlocal law with local properties).
20852  !* Then, we assume, that the opposite(!) neighbor sends an equal amount of dislocations to me.
20853  !* So the net flux in the direction of my neighbor is equal to zero:
20854  !* leaving flux to neighbor == entering flux from opposite neighbor
20855  !* In case of reduced transmissivity, part of the leaving flux is stored as dead dislocation density.
20856  !* That means for an interface of zero transmissivity the leaving flux is fully converted to dead dislocations.
20857  if (opposite_n > 0) then
20858  if (phase_plasticity(material_phaseat(1,opposite_el)) == plasticity_nonlocal_id) then
20859 
20860  normal_me2neighbor_defconf = math_det33(favg) &
20861  * matmul(math_inv33(transpose(favg)),ipareanormal(1:3,n,ip,el)) ! normal of the interface in (average) deformed configuration (pointing me => neighbor)
20862  normal_me2neighbor = matmul(transpose(my_fe), normal_me2neighbor_defconf) &
20863  / math_det33(my_fe) ! interface normal in my lattice configuration
20864  area = iparea(n,ip,el) * norm2(normal_me2neighbor)
20865  normal_me2neighbor = normal_me2neighbor / norm2(normal_me2neighbor) ! normalize the surface normal to unit length
20866  do s = 1,ns
20867  do t = 1,4
20868  c = (t + 1) / 2
20869  if (v0(s,t) * math_inner(m(1:3,s,t), normal_me2neighbor) > 0.0_preal ) then ! flux from me to my neighbor == leaving flux for me (might also be a pure flux from my mobile density to dead density if interface not at all transmissive)
20870  if (v0(s,t) * neighbor_v0(s,t) >= 0.0_preal) then ! no sign change in flux density
20871  transmissivity = sum(compatibility(c,:,s,n,ip,el)**2.0_preal) ! overall transmissivity from this slip system to my neighbor
20872  else ! sign change in flux density means sign change in stress which does not allow for dislocations to arive at the neighbor
20873  transmissivity = 0.0_preal
20874  endif
20875  linelength = my_rhosgl0(s,t) * v0(s,t) &
20876  * math_inner(m(1:3,s,t), normal_me2neighbor) * area ! positive line length of mobiles that wants to leave through this interface
20877  rhodotflux(s,t) = rhodotflux(s,t) - linelength / ipvolume(ip,el) ! subtract dislocation flux from current type
20878  rhodotflux(s,t+4) = rhodotflux(s,t+4) &
20879  + linelength / ipvolume(ip,el) * (1.0_preal - transmissivity) &
20880  * sign(1.0_preal, v0(s,t)) ! dislocation flux that is not able to leave through interface (because of low transmissivity) will remain as immobile single density at the material point
20881  endif
20882  enddo
20883  enddo
20884  endif; endif
20885 
20886  enddo neighbors
20887  endif
20888 
20889 
20890 
20891  !****************************************************************************
20892  !*** calculate dipole formation and annihilation
20893 
20894  !*** formation by glide
20895  do c = 1,2
20896  rhodotsingle2dipoleglide(:,2*c-1) = -2.0_preal * dupper(:,c) / prm%burgers &
20897  * ( rhosgl(:,2*c-1) * abs(gdot(:,2*c)) & ! negative mobile --> positive mobile
20898  + rhosgl(:,2*c) * abs(gdot(:,2*c-1)) & ! positive mobile --> negative mobile
20899  + abs(rhosgl(:,2*c+4)) * abs(gdot(:,2*c-1))) ! positive mobile --> negative immobile
20900 
20901  rhodotsingle2dipoleglide(:,2*c) = -2.0_preal * dupper(:,c) / prm%burgers &
20902  * ( rhosgl(:,2*c-1) * abs(gdot(:,2*c)) & ! negative mobile --> positive mobile
20903  + rhosgl(:,2*c) * abs(gdot(:,2*c-1)) & ! positive mobile --> negative mobile
20904  + abs(rhosgl(:,2*c+3)) * abs(gdot(:,2*c))) ! negative mobile --> positive immobile
20905 
20906  rhodotsingle2dipoleglide(:,2*c+3) = -2.0_preal * dupper(:,c) / prm%burgers &
20907  * rhosgl(:,2*c+3) * abs(gdot(:,2*c)) ! negative mobile --> positive immobile
20908 
20909  rhodotsingle2dipoleglide(:,2*c+4) = -2.0_preal * dupper(:,c) / prm%burgers &
20910  * rhosgl(:,2*c+4) * abs(gdot(:,2*c-1)) ! positive mobile --> negative immobile
20911 
20912  rhodotsingle2dipoleglide(:,c+8) = abs(rhodotsingle2dipoleglide(:,2*c+3)) &
20913  + abs(rhodotsingle2dipoleglide(:,2*c+4)) &
20914  - rhodotsingle2dipoleglide(:,2*c-1) &
20915  - rhodotsingle2dipoleglide(:,2*c)
20916  enddo
20917 
20918 
20919  !*** athermal annihilation
20920  rhodotathermalannihilation = 0.0_preal
20921  forall (c=1:2) &
20922  rhodotathermalannihilation(:,c+8) = -2.0_preal * dlower(:,c) / prm%burgers &
20923  * ( 2.0_preal * (rhosgl(:,2*c-1) * abs(gdot(:,2*c)) + rhosgl(:,2*c) * abs(gdot(:,2*c-1))) & ! was single hitting single
20924  + 2.0_preal * (abs(rhosgl(:,2*c+3)) * abs(gdot(:,2*c)) + abs(rhosgl(:,2*c+4)) * abs(gdot(:,2*c-1))) & ! was single hitting immobile single or was immobile single hit by single
20925  + rhodip(:,c) * (abs(gdot(:,2*c-1)) + abs(gdot(:,2*c)))) ! single knocks dipole constituent
20926 
20927  ! annihilated screw dipoles leave edge jogs behind on the colinear system
20928  if (lattice_structure(ph) == lattice_fcc_id) &
20929  forall (s = 1:ns, prm%colinearSystem(s) > 0) &
20930  rhodotathermalannihilation(prm%colinearSystem(s),1:2) = - rhodotathermalannihilation(s,10) &
20931  * 0.25_preal * sqrt(stt%rho_forest(s,of)) * (dupper(s,2) + dlower(s,2)) * prm%edgeJogFactor
20932 
20933 
20934  !*** thermally activated annihilation of edge dipoles by climb
20935  rhodotthermalannihilation = 0.0_preal
20936  selfdiffusion = prm%Dsd0 * exp(-prm%selfDiffusionEnergy / (kb * temperature))
20937  vclimb = prm%atomicVolume * selfdiffusion * prm%mu &
20938  / ( kb * temperature * pi * (1.0_preal-prm%nu) * (dupper(:,1) + dlower(:,1)))
20939  forall (s = 1:ns, dupper(s,1) > dlower(s,1)) &
20940  rhodotthermalannihilation(s,9) = max(- 4.0_preal * rhodip(s,1) * vclimb(s) / (dupper(s,1) - dlower(s,1)), &
20941  - rhodip(s,1) / timestep - rhodotathermalannihilation(s,9) &
20942  - rhodotsingle2dipoleglide(s,9)) ! make sure that we do not annihilate more dipoles than we have
20943 
20944  rhodot = rhodotflux &
20945  + rhodotmultiplication &
20946  + rhodotsingle2dipoleglide &
20947  + rhodotathermalannihilation &
20948  + rhodotthermalannihilation
20949 
20950 # 1325 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/constitutive_plastic_nonlocal.f90"
20951 
20952 
20953  if ( any(rho(:,mob) + rhodot(:,1:4) * timestep < -prm%atol_rho) &
20954  .or. any(rho(:,dip) + rhodot(:,9:10) * timestep < -prm%atol_rho)) then
20955 
20956 
20957 
20958 
20959 
20960 
20961  plasticstate(ph)%dotState = ieee_value(1.0_preal,ieee_quiet_nan)
20962  else
20963  dot%rho(:,of) = pack(rhodot,.true.)
20964  dot%gamma(:,of) = sum(gdot,2)
20965  endif
20966 
20967  end associate
20968 
20969 end subroutine plastic_nonlocal_dotstate
20970 
20971 
20972 !--------------------------------------------------------------------------------------------------
20975 ! plane normals and signed cosine of the angle between the slip directions. Only the largest values
20976 ! that sum up to a total of 1 are considered, all others are set to zero.
20977 !--------------------------------------------------------------------------------------------------
20978 module subroutine plastic_nonlocal_updatecompatibility(orientation,instance,i,e)
20979 
20980  type(rotation), dimension(1,discretization_nIP,discretization_nElem), intent(in) :: &
20981  orientation ! crystal orientation
20982  integer, intent(in) :: &
20983  instance, &
20984  i, &
20985  e
20986 
20987  integer :: &
20988  n, & ! neighbor index
20989  neighbor_e, & ! element index of my neighbor
20990  neighbor_i, & ! integration point index of my neighbor
20991  ph, &
20992  neighbor_phase, &
20993  ns, & ! number of active slip systems
20994  s1, & ! slip system index (me)
20995  s2 ! slip system index (my neighbor)
20996  real(preal), dimension(2,param(instance)%sum_N_sl,param(instance)%sum_N_sl,nIPneighbors) :: &
20997  my_compatibility ! my_compatibility for current element and ip
20998  real(preal) :: &
20999  my_compatibilitysum, &
21000  thresholdvalue, &
21001  nthresholdvalues
21002  logical, dimension(param(instance)%sum_N_sl) :: &
21003  belowthreshold
21004  type(rotation) :: mis
21005 
21006  ph = material_phaseat(1,e)
21007 
21008  associate(prm => param(instance))
21009  ns = prm%sum_N_sl
21010 
21011  !*** start out fully compatible
21012  my_compatibility = 0.0_preal
21013  forall(s1 = 1:ns) my_compatibility(:,s1,s1,:) = 1.0_preal
21014 
21015  neighbors: do n = 1,nipneighbors
21016  neighbor_e = ipneighborhood(1,n,i,e)
21017  neighbor_i = ipneighborhood(2,n,i,e)
21018 
21019  neighbor_phase = material_phaseat(1,neighbor_e)
21020 
21021  if (neighbor_e <= 0 .or. neighbor_i <= 0) then
21022  !* FREE SURFACE
21023  !* Set surface transmissivity to the value specified in the material.config
21024  forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%surfaceTransmissivity)
21025  elseif (neighbor_phase /= ph) then
21026  !* PHASE BOUNDARY
21027  !* If we encounter a different nonlocal phase at the neighbor,
21028  !* we consider this to be a real "physical" phase boundary, so completely incompatible.
21029  !* If one of the two phases has a local plasticity law,
21030  !* we do not consider this to be a phase boundary, so completely compatible.
21031  if (.not. phase_localplasticity(neighbor_phase) .and. .not. phase_localplasticity(ph)) &
21032  forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = 0.0_preal
21033  elseif (prm%grainboundaryTransmissivity >= 0.0_preal) then
21034  !* GRAIN BOUNDARY !
21035  !* fixed transmissivity for adjacent ips with different texture (only if explicitly given in material.config)
21036  if (material_texture(1,i,e) /= material_texture(1,neighbor_i,neighbor_e) .and. &
21037  (.not. phase_localplasticity(neighbor_phase))) &
21038  forall(s1 = 1:ns) my_compatibility(:,s1,s1,n) = sqrt(prm%grainboundaryTransmissivity)
21039  else
21040  !* GRAIN BOUNDARY ?
21041  !* Compatibility defined by relative orientation of slip systems:
21042  !* The my_compatibility value is defined as the product of the slip normal projection and the slip direction projection.
21043  !* Its sign is always positive for screws, for edges it has the same sign as the slip normal projection.
21044  !* Since the sum for each slip system can easily exceed one (which would result in a transmissivity larger than one),
21045  !* only values above or equal to a certain threshold value are considered. This threshold value is chosen, such that
21046  !* the number of compatible slip systems is minimized with the sum of the original compatibility values exceeding one.
21047  !* Finally the smallest compatibility value is decreased until the sum is exactly equal to one.
21048  !* All values below the threshold are set to zero.
21049  mis = orientation(1,i,e)%misorientation(orientation(1,neighbor_i,neighbor_e))
21050  myslipsystems: do s1 = 1,ns
21051  neighborslipsystems: do s2 = 1,ns
21052  my_compatibility(1,s2,s1,n) = math_inner(prm%slip_normal(1:3,s1), &
21053  mis%rotate(prm%slip_normal(1:3,s2))) &
21054  * abs(math_inner(prm%slip_direction(1:3,s1), &
21055  mis%rotate(prm%slip_direction(1:3,s2))))
21056  my_compatibility(2,s2,s1,n) = abs(math_inner(prm%slip_normal(1:3,s1), &
21057  mis%rotate(prm%slip_normal(1:3,s2)))) &
21058  * abs(math_inner(prm%slip_direction(1:3,s1), &
21059  mis%rotate(prm%slip_direction(1:3,s2))))
21060  enddo neighborslipsystems
21061 
21062  my_compatibilitysum = 0.0_preal
21063  belowthreshold = .true.
21064  do while (my_compatibilitysum < 1.0_preal .and. any(belowthreshold))
21065  thresholdvalue = maxval(my_compatibility(2,:,s1,n), belowthreshold) ! screws always positive
21066  nthresholdvalues = real(count(my_compatibility(2,:,s1,n) >= thresholdvalue),preal)
21067  where (my_compatibility(2,:,s1,n) >= thresholdvalue) belowthreshold = .false.
21068  if (my_compatibilitysum + thresholdvalue * nthresholdvalues > 1.0_preal) &
21069  where (abs(my_compatibility(:,:,s1,n)) >= thresholdvalue) &
21070  my_compatibility(:,:,s1,n) = sign((1.0_preal - my_compatibilitysum)/nthresholdvalues,&
21071  my_compatibility(:,:,s1,n))
21072  my_compatibilitysum = my_compatibilitysum + nthresholdvalues * thresholdvalue
21073  enddo
21074 
21075  where(belowthreshold) my_compatibility(1,:,s1,n) = 0.0_preal
21076  where(belowthreshold) my_compatibility(2,:,s1,n) = 0.0_preal
21077 
21078  enddo myslipsystems
21079  endif
21080 
21081  enddo neighbors
21082 
21083  compatibility(:,:,:,:,i,e) = my_compatibility
21084 
21085  end associate
21086 
21087 end subroutine plastic_nonlocal_updatecompatibility
21088 
21089 
21090 !--------------------------------------------------------------------------------------------------
21092 !--------------------------------------------------------------------------------------------------
21093 module subroutine plastic_nonlocal_results(instance,group)
21094 
21095  integer, intent(in) :: instance
21096  character(len=*),intent(in) :: group
21097 
21098  integer :: o
21099 
21100  associate(prm => param(instance),dst => microstructure(instance),stt=>state(instance))
21101  outputsloop: do o = 1,size(prm%output)
21102  select case(trim(prm%output(o)))
21103  case('rho_sgl_mob_edg_pos')
21104  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_sgl_mob_edg_pos, 'rho_sgl_mob_edg_pos', &
21105  'positive mobile edge density','1/m²')
21106  case('rho_sgl_imm_edg_pos')
21107  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_sgl_imm_edg_pos, 'rho_sgl_imm_edg_pos',&
21108  'positive immobile edge density','1/m²')
21109  case('rho_sgl_mob_edg_neg')
21110  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_sgl_mob_edg_neg, 'rho_sgl_mob_edg_neg',&
21111  'negative mobile edge density','1/m²')
21112  case('rho_sgl_imm_edg_neg')
21113  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_sgl_imm_edg_neg, 'rho_sgl_imm_edg_neg',&
21114  'negative immobile edge density','1/m²')
21115  case('rho_dip_edg')
21116  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_dip_edg, 'rho_dip_edg',&
21117  'edge dipole density','1/m²')
21118  case('rho_sgl_mob_scr_pos')
21119  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_sgl_mob_scr_pos, 'rho_sgl_mob_scr_pos',&
21120  'positive mobile screw density','1/m²')
21121  case('rho_sgl_imm_scr_pos')
21122  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_sgl_imm_scr_pos, 'rho_sgl_imm_scr_pos',&
21123  'positive immobile screw density','1/m²')
21124  case('rho_sgl_mob_scr_neg')
21125  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_sgl_mob_scr_neg, 'rho_sgl_mob_scr_neg',&
21126  'negative mobile screw density','1/m²')
21127  case('rho_sgl_imm_scr_neg')
21128  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_sgl_imm_scr_neg, 'rho_sgl_imm_scr_neg',&
21129  'negative immobile screw density','1/m²')
21130  case('rho_dip_scr')
21131  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_dip_scr, 'rho_dip_scr',&
21132  'screw dipole density','1/m²')
21133  case('rho_forest')
21134  if(prm%sum_N_sl>0) call results_writedataset(group,stt%rho_forest, 'rho_forest',&
21135  'forest density','1/m²')
21136  case('v_edg_pos')
21137  if(prm%sum_N_sl>0) call results_writedataset(group,stt%v_edg_pos, 'v_edg_pos',&
21138  'positive edge velocity','m/s')
21139  case('v_edg_neg')
21140  if(prm%sum_N_sl>0) call results_writedataset(group,stt%v_edg_neg, 'v_edg_neg',&
21141  'negative edge velocity','m/s')
21142  case('v_scr_pos')
21143  if(prm%sum_N_sl>0) call results_writedataset(group,stt%v_scr_pos, 'v_scr_pos',&
21144  'positive srew velocity','m/s')
21145  case('v_scr_neg')
21146  if(prm%sum_N_sl>0) call results_writedataset(group,stt%v_scr_neg, 'v_scr_neg',&
21147  'negative screw velocity','m/s')
21148  case('gamma')
21149  if(prm%sum_N_sl>0) call results_writedataset(group,stt%gamma,'gamma',&
21150  'plastic shear','1')
21151  case('tau_pass')
21152  if(prm%sum_N_sl>0) call results_writedataset(group,dst%tau_pass,'tau_pass',&
21153  'passing stress for slip','Pa')
21154  end select
21155  enddo outputsloop
21156  end associate
21157 
21158 end subroutine plastic_nonlocal_results
21159 
21160 
21161 !--------------------------------------------------------------------------------------------------
21163 !--------------------------------------------------------------------------------------------------
21164 subroutine stateinit(ini,phase,NipcMyPhase)
21166  type(tinitialparameters) :: &
21167  ini
21168  integer,intent(in) :: &
21169  phase, &
21170  NipcMyPhase
21171  integer :: &
21172  e, &
21173  i, &
21174  f, &
21175  from, &
21176  upto, &
21177  s, &
21178  instance, &
21179  phasemember
21180  real(pReal), dimension(2) :: &
21181  noise, &
21182  rnd
21183  real(pReal) :: &
21184  meanDensity, &
21185  totalVolume, &
21186  densityBinning, &
21187  minimumIpVolume
21188  real(pReal), dimension(NipcMyPhase) :: &
21189  volume
21190 
21191  instance = phase_plasticityinstance(phase)
21192  associate(stt => state(instance))
21193 
21194  if (ini%rhoSglRandom > 0.0_preal) then ! randomly distribute dislocation segments on random slip system and of random type in the volume
21195  do e = 1,discretization_nelem
21196  do i = 1,discretization_nip
21197  if (material_phaseat(1,e) == phase) volume(material_phasememberat(1,i,e)) = ipvolume(i,e)
21198  enddo
21199  enddo
21200  totalvolume = sum(volume)
21201  minimumipvolume = minval(volume)
21202  densitybinning = ini%rhoSglRandomBinning / minimumipvolume ** (2.0_preal / 3.0_preal)
21203 
21204  ! fill random material points with dislocation segments until the desired overall density is reached
21205  meandensity = 0.0_preal
21206  do while(meandensity < ini%rhoSglRandom)
21207  call random_number(rnd)
21208  phasemember = nint(rnd(1)*real(nipcmyphase,preal) + 0.5_preal)
21209  s = nint(rnd(2)*real(sum(ini%N_sl),preal)*4.0_preal + 0.5_preal)
21210  meandensity = meandensity + densitybinning * volume(phasemember) / totalvolume
21211  stt%rhoSglMobile(s,phasemember) = densitybinning
21212  enddo
21213  else ! homogeneous distribution with noise
21214  do e = 1, nipcmyphase
21215  do f = 1,size(ini%N_sl,1)
21216  from = 1 + sum(ini%N_sl(1:f-1))
21217  upto = sum(ini%N_sl(1:f))
21218  do s = from,upto
21219  noise = [math_samplegaussvar(0.0_preal, ini%rhoSglScatter), &
21220  math_samplegaussvar(0.0_preal, ini%rhoSglScatter)]
21221  stt%rho_sgl_mob_edg_pos(s,e) = ini%rhoSglEdgePos0(f) + noise(1)
21222  stt%rho_sgl_mob_edg_neg(s,e) = ini%rhoSglEdgeNeg0(f) + noise(1)
21223  stt%rho_sgl_mob_scr_pos(s,e) = ini%rhoSglScrewPos0(f) + noise(2)
21224  stt%rho_sgl_mob_scr_neg(s,e) = ini%rhoSglScrewNeg0(f) + noise(2)
21225  enddo
21226  stt%rho_dip_edg(from:upto,e) = ini%rhoDipEdge0(f)
21227  stt%rho_dip_scr(from:upto,e) = ini%rhoDipScrew0(f)
21228  enddo
21229  enddo
21230  endif
21231 
21232  end associate
21233 
21234 end subroutine stateinit
21235 
21236 
21237 !--------------------------------------------------------------------------------------------------
21239 !--------------------------------------------------------------------------------------------------
21240 subroutine kinetics(v, dv_dtau, dv_dtauNS, tau, tauNS, tauThreshold, c, Temperature, instance)
21242  integer, intent(in) :: &
21243  c, & !< dislocation character (1:edge, 2:screw)
21244  instance
21245  real(pReal), intent(in) :: &
21246  Temperature
21247  real(pReal), dimension(param(instance)%sum_N_sl), intent(in) :: &
21248  tau, & !< resolved external shear stress (without non Schmid effects)
21249  tauNS, & !< resolved external shear stress (including non Schmid effects)
21250  tauThreshold
21251  real(pReal), dimension(param(instance)%sum_N_sl), intent(out) :: &
21252  v, & !< velocity
21253  dv_dtau, & !< velocity derivative with respect to resolved shear stress (without non Schmid contributions)
21254  dv_dtauNS
21255 
21256  integer :: &
21257  ns, & !< short notation for the total number of active slip systems
21258  s
21259  real(pReal) :: &
21260  tauRel_P, &
21261  tauRel_S, &
21262  tauEff, & !< effective shear stress
21263  tPeierls, & !< waiting time in front of a peierls barriers
21264  tSolidSolution, & !< waiting time in front of a solid solution obstacle
21265  vViscous, & !< viscous glide velocity
21266  dtPeierls_dtau, & !< derivative with respect to resolved shear stress
21267  dtSolidSolution_dtau, & !< derivative with respect to resolved shear stress
21268  meanfreepath_S, & !< mean free travel distance for dislocations between two solid solution obstacles
21269  meanfreepath_P, & !< mean free travel distance for dislocations between two Peierls barriers
21270  jumpWidth_P, & !< depth of activated area
21271  jumpWidth_S, & !< depth of activated area
21272  activationLength_P, & !< length of activated dislocation line
21273  activationLength_S, & !< length of activated dislocation line
21274  activationVolume_P, & !< volume that needs to be activated to overcome barrier
21275  activationVolume_S, & !< volume that needs to be activated to overcome barrier
21276  activationEnergy_P, & !< energy that is needed to overcome barrier
21277  activationEnergy_S, & !< energy that is needed to overcome barrier
21278  criticalStress_P, & !< maximum obstacle strength
21279  criticalStress_S, & !< maximum obstacle strength
21280  mobility
21281 
21282  associate(prm => param(instance))
21283  ns = prm%sum_N_sl
21284  v = 0.0_preal
21285  dv_dtau = 0.0_preal
21286  dv_dtauns = 0.0_preal
21287 
21288  do s = 1,ns
21289  if (abs(tau(s)) > tauthreshold(s)) then
21290 
21291  !* Peierls contribution
21292  !* Effective stress includes non Schmid constributions
21293  !* The derivative only gives absolute values; the correct sign is taken care of in the formula for the derivative of the velocity
21294  taueff = max(0.0_preal, abs(tauns(s)) - tauthreshold(s)) ! ensure that the effective stress is positive
21295  meanfreepath_p = prm%burgers(s)
21296  jumpwidth_p = prm%burgers(s)
21297  activationlength_p = prm%doublekinkwidth *prm%burgers(s)
21298  activationvolume_p = activationlength_p * jumpwidth_p * prm%burgers(s)
21299  criticalstress_p = prm%peierlsStress(s,c)
21300  activationenergy_p = criticalstress_p * activationvolume_p
21301  taurel_p = min(1.0_preal, taueff / criticalstress_p) ! ensure that the activation probability cannot become greater than one
21302  tpeierls = 1.0_preal / prm%fattack &
21303  * exp(activationenergy_p / (kb * temperature) &
21304  * (1.0_preal - taurel_p**prm%p)**prm%q)
21305  if (taueff < criticalstress_p) then
21306  dtpeierls_dtau = tpeierls * prm%p * prm%q * activationvolume_p / (kb * temperature) &
21307  * (1.0_preal - taurel_p**prm%p)**(prm%q-1.0_preal) * taurel_p**(prm%p-1.0_preal)
21308  else
21309  dtpeierls_dtau = 0.0_preal
21310  endif
21311 
21312  !* Contribution from solid solution strengthening
21313  !* The derivative only gives absolute values; the correct sign is taken care of in the formula for the derivative of the velocity
21314  taueff = abs(tau(s)) - tauthreshold(s)
21315  meanfreepath_s = prm%burgers(s) / sqrt(prm%solidSolutionConcentration)
21316  jumpwidth_s = prm%solidSolutionSize * prm%burgers(s)
21317  activationlength_s = prm%burgers(s) / sqrt(prm%solidSolutionConcentration)
21318  activationvolume_s = activationlength_s * jumpwidth_s * prm%burgers(s)
21319  activationenergy_s = prm%solidSolutionEnergy
21320  criticalstress_s = activationenergy_s / activationvolume_s
21321  taurel_s = min(1.0_preal, taueff / criticalstress_s) ! ensure that the activation probability cannot become greater than one
21322  tsolidsolution = 1.0_preal / prm%fattack &
21323  * exp(activationenergy_s / (kb * temperature)* (1.0_preal - taurel_s**prm%p)**prm%q)
21324  if (taueff < criticalstress_s) then
21325  dtsolidsolution_dtau = tsolidsolution * prm%p * prm%q * activationvolume_s / (kb * temperature) &
21326  * (1.0_preal - taurel_s**prm%p)**(prm%q-1.0_preal)* taurel_s**(prm%p-1.0_preal)
21327  else
21328  dtsolidsolution_dtau = 0.0_preal
21329  endif
21330 
21331  !* viscous glide velocity
21332  taueff = abs(tau(s)) - tauthreshold(s)
21333  mobility = prm%burgers(s) / prm%viscosity
21334  vviscous = mobility * taueff
21335 
21336  !* Mean velocity results from waiting time at peierls barriers and solid solution obstacles with respective meanfreepath of
21337  !* free flight at glide velocity in between.
21338  !* adopt sign from resolved stress
21339  v(s) = sign(1.0_preal,tau(s)) &
21340  / (tpeierls / meanfreepath_p + tsolidsolution / meanfreepath_s + 1.0_preal / vviscous)
21341  dv_dtau(s) = v(s)**2.0_preal * (dtsolidsolution_dtau / meanfreepath_s + mobility /vviscous**2.0_preal)
21342  dv_dtauns(s) = v(s)**2.0_preal * dtpeierls_dtau / meanfreepath_p
21343  endif
21344  enddo
21345 
21346  end associate
21347 
21348 end subroutine kinetics
21349 
21350 
21351 !--------------------------------------------------------------------------------------------------
21354 !--------------------------------------------------------------------------------------------------
21355 function getrho(instance,of,ip,el)
21357  integer, intent(in) :: instance, of,ip,el
21358  real(preal), dimension(param(instance)%sum_N_sl,10) :: getrho
21359 
21360  associate(prm => param(instance))
21361 
21362  getrho = reshape(state(instance)%rho(:,of),[prm%sum_N_sl,10])
21363 
21364  ! ensure positive densities (not for imm, they have a sign)
21365  getrho(:,mob) = max(getrho(:,mob),0.0_preal)
21366  getrho(:,dip) = max(getrho(:,dip),0.0_preal)
21367 
21368  where(abs(getrho) < max(prm%significantN/ipvolume(ip,el)**(2.0_preal/3.0_preal),prm%significantRho)) &
21369  getrho = 0.0_preal
21370 
21371  end associate
21372 
21373 end function getrho
21374 
21375 
21376 !--------------------------------------------------------------------------------------------------
21379 !--------------------------------------------------------------------------------------------------
21380 function getrho0(instance,of,ip,el)
21382  integer, intent(in) :: instance, of,ip,el
21383  real(preal), dimension(param(instance)%sum_N_sl,10) :: getrho0
21384 
21385  associate(prm => param(instance))
21386 
21387  getrho0 = reshape(state0(instance)%rho(:,of),[prm%sum_N_sl,10])
21388 
21389  ! ensure positive densities (not for imm, they have a sign)
21390  getrho0(:,mob) = max(getrho0(:,mob),0.0_preal)
21391  getrho0(:,dip) = max(getrho0(:,dip),0.0_preal)
21392 
21393  where(abs(getrho0) < max(prm%significantN/ipvolume(ip,el)**(2.0_preal/3.0_preal),prm%significantRho)) &
21394  getrho0 = 0.0_preal
21395 
21396  end associate
21397 
21398 end function getrho0
21399 
21400 end submodule plastic_nonlocal
21401 # 44 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
21402 
21403 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/crystallite.f90" 1
21404 !--------------------------------------------------------------------------------------------------
21412 !--------------------------------------------------------------------------------------------------
21413 
21414 module crystallite
21415  use prec
21416  use io
21417  use hdf5_utilities
21418  use damask_interface
21419  use config
21420  use debug
21421  use numerics
21422  use rotations
21423  use math
21424  use fesolving
21425  use material
21426  use constitutive
21427  use discretization
21428  use lattice
21429  use results
21430 
21431  implicit none
21432  private
21433 
21434  real(preal), dimension(:,:,:), allocatable, public :: &
21435  crystallite_dt
21436  real(preal), dimension(:,:,:), allocatable :: &
21437  crystallite_subdt, & !< substepped time increment of each grain
21438  crystallite_subfrac, & !< already calculated fraction of increment
21439  crystallite_substep
21440  type(rotation), dimension(:,:,:), allocatable :: &
21441  crystallite_orientation
21442  real(preal), dimension(:,:,:,:,:), allocatable, public, protected :: &
21443  crystallite_fe, & !< current "elastic" def grad (end of converged time step)
21444  crystallite_p, & !< 1st Piola-Kirchhoff stress per grain
21445  crystallite_s0, & !< 2nd Piola-Kirchhoff stress vector at start of FE inc
21446  crystallite_fp0, & !< plastic def grad at start of FE inc
21447  crystallite_fi0, & !< intermediate def grad at start of FE inc
21448  crystallite_f0, & !< def grad at start of FE inc
21449  crystallite_lp0, & !< plastic velocitiy grad at start of FE inc
21450  crystallite_li0
21451  real(preal), dimension(:,:,:,:,:), allocatable, public :: &
21452  crystallite_s, & !< current 2nd Piola-Kirchhoff stress vector (end of converged time step)
21453  crystallite_partioneds0, & !< 2nd Piola-Kirchhoff stress vector at start of homog inc
21454  crystallite_fp, & !< current plastic def grad (end of converged time step)
21455  crystallite_partionedfp0,& !< plastic def grad at start of homog inc
21456  crystallite_fi, & !< current intermediate def grad (end of converged time step)
21457  crystallite_partionedfi0,& !< intermediate def grad at start of homog inc
21458  crystallite_partionedf, & !< def grad to be reached at end of homog inc
21459  crystallite_partionedf0, & !< def grad at start of homog inc
21460  crystallite_lp, & !< current plastic velocitiy grad (end of converged time step)
21461  crystallite_partionedlp0, & !< plastic velocity grad at start of homog inc
21462  crystallite_li, & !< current intermediate velocitiy grad (end of converged time step)
21463  crystallite_partionedli0
21464  real(preal), dimension(:,:,:,:,:), allocatable :: &
21465  crystallite_subfp0,& !< plastic def grad at start of crystallite inc
21466  crystallite_subfi0,& !< intermediate def grad at start of crystallite inc
21467  crystallite_subf, & !< def grad to be reached at end of crystallite inc
21468  crystallite_subf0, & !< def grad at start of crystallite inc
21469  crystallite_sublp0,& !< plastic velocity grad at start of crystallite inc
21470  crystallite_subli0
21471  real(preal), dimension(:,:,:,:,:,:,:), allocatable, public, protected :: &
21472  crystallite_dpdf
21473  logical, dimension(:,:,:), allocatable, public :: &
21474  crystallite_requested
21475  logical, dimension(:,:,:), allocatable :: &
21476  crystallite_converged, & !< convergence flag
21477  crystallite_todo, & !< flag to indicate need for further computation
21478  crystallite_localplasticity
21479 
21480  type :: toutput
21481  character(len=pStringLen), allocatable, dimension(:) :: &
21482  label
21483  end type toutput
21484  type(toutput), allocatable, dimension(:) :: output_constituent
21485 
21486  type :: tnumerics
21487  integer :: &
21488  ijacolpresiduum, & !< frequency of Jacobian update of residuum in Lp
21489  nstate, & !< state loop limit
21490  nstress
21491  real(preal) :: &
21492  substepmincryst, & !< minimum (relative) size of sub-step allowed during cutback
21493  substepsizecryst, & !< size of first substep when cutback
21494  substepsizelp, & !< size of first substep when cutback in Lp calculation
21495  substepsizeli, & !< size of first substep when cutback in Li calculation
21496  stepincreasecryst, & !< increase of next substep size when previous substep converged
21497  rtol_crystallitestate, & !< relative tolerance in state loop
21498  rtol_crystallitestress, & !< relative tolerance in stress loop
21499  atol_crystallitestress
21500  end type tnumerics
21501 
21502  type(tnumerics) :: num ! numerics parameters. Better name?
21503 
21504  procedure(), pointer :: integratestate
21505 
21506  public :: &
21507  crystallite_init, &
21516 
21517 contains
21518 
21519 
21520 !--------------------------------------------------------------------------------------------------
21522 !--------------------------------------------------------------------------------------------------
21523 subroutine crystallite_init
21525  logical, dimension(discretization_nIP,discretization_nElem) :: devNull
21526  integer :: &
21527  c, & !< counter in integration point component loop
21528  i, & !< counter in integration point loop
21529  e, & !< counter in element loop
21530  cMax, & !< maximum number of integration point components
21531  iMax, & !< maximum number of integration points
21532  eMax, & !< maximum number of elements
21533  myNcomponents
21534 
21535  write(6,'(/,a)') ' <<<+- crystallite init -+>>>'
21536 
21538  imax = discretization_nip
21539  emax = discretization_nelem
21540 
21541  allocate(crystallite_partionedf(3,3,cmax,imax,emax),source=0.0_preal)
21542 
21543  allocate(crystallite_s0, &
21544  crystallite_f0, crystallite_fi0,crystallite_fp0, &
21545  crystallite_li0,crystallite_lp0, &
21546  crystallite_partioneds0, &
21547  crystallite_partionedf0,crystallite_partionedfp0,crystallite_partionedfi0, &
21548  crystallite_partionedlp0,crystallite_partionedli0, &
21549  crystallite_s,crystallite_p, &
21550  crystallite_fe,crystallite_fi,crystallite_fp, &
21551  crystallite_li,crystallite_lp, &
21552  crystallite_subf,crystallite_subf0, &
21553  crystallite_subfp0,crystallite_subfi0, &
21554  crystallite_subli0,crystallite_sublp0, &
21555  source = crystallite_partionedf)
21556 
21557  allocate(crystallite_dpdf(3,3,3,3,cmax,imax,emax),source=0.0_preal)
21558 
21559  allocate(crystallite_dt(cmax,imax,emax),source=0.0_preal)
21560  allocate(crystallite_subdt,crystallite_subfrac,crystallite_substep, &
21561  source = crystallite_dt)
21562 
21563  allocate(crystallite_orientation(cmax,imax,emax))
21564 
21565  allocate(crystallite_localplasticity(cmax,imax,emax), source=.true.)
21566  allocate(crystallite_requested(cmax,imax,emax), source=.false.)
21567  allocate(crystallite_todo(cmax,imax,emax), source=.false.)
21568  allocate(crystallite_converged(cmax,imax,emax), source=.true.)
21569 
21570  num%subStepMinCryst = config_numerics%getFloat('substepmincryst', defaultval=1.0e-3_preal)
21571  num%subStepSizeCryst = config_numerics%getFloat('substepsizecryst', defaultval=0.25_preal)
21572  num%stepIncreaseCryst = config_numerics%getFloat('stepincreasecryst', defaultval=1.5_preal)
21573 
21574  num%subStepSizeLp = config_numerics%getFloat('substepsizelp', defaultval=0.5_preal)
21575  num%subStepSizeLi = config_numerics%getFloat('substepsizeli', defaultval=0.5_preal)
21576 
21577  num%rtol_crystalliteState = config_numerics%getFloat('rtol_crystallitestate', defaultval=1.0e-6_preal)
21578  num%rtol_crystalliteStress = config_numerics%getFloat('rtol_crystallitestress',defaultval=1.0e-6_preal)
21579  num%atol_crystalliteStress = config_numerics%getFloat('atol_crystallitestress',defaultval=1.0e-8_preal)
21580 
21581  num%iJacoLpresiduum = config_numerics%getInt ('ijacolpresiduum', defaultval=1)
21582 
21583  num%nState = config_numerics%getInt ('nstate', defaultval=20)
21584  num%nStress = config_numerics%getInt ('nstress', defaultval=40)
21585 
21586  if(num%subStepMinCryst <= 0.0_preal) call io_error(301,ext_msg='subStepMinCryst')
21587  if(num%subStepSizeCryst <= 0.0_preal) call io_error(301,ext_msg='subStepSizeCryst')
21588  if(num%stepIncreaseCryst <= 0.0_preal) call io_error(301,ext_msg='stepIncreaseCryst')
21589 
21590  if(num%subStepSizeLp <= 0.0_preal) call io_error(301,ext_msg='subStepSizeLp')
21591  if(num%subStepSizeLi <= 0.0_preal) call io_error(301,ext_msg='subStepSizeLi')
21592 
21593  if(num%rtol_crystalliteState <= 0.0_preal) call io_error(301,ext_msg='rtol_crystalliteState')
21594  if(num%rtol_crystalliteStress <= 0.0_preal) call io_error(301,ext_msg='rtol_crystalliteStress')
21595  if(num%atol_crystalliteStress <= 0.0_preal) call io_error(301,ext_msg='atol_crystalliteStress')
21596 
21597  if(num%iJacoLpresiduum < 1) call io_error(301,ext_msg='iJacoLpresiduum')
21598 
21599  if(num%nState < 1) call io_error(301,ext_msg='nState')
21600  if(num%nStress< 1) call io_error(301,ext_msg='nStress')
21601 
21602  select case(numerics_integrator)
21603  case(1)
21604  integratestate => integratestatefpi
21605  case(2)
21606  integratestate => integratestateeuler
21607  case(3)
21608  integratestate => integratestateadaptiveeuler
21609  case(4)
21610  integratestate => integratestaterk4
21611  case(5)
21612  integratestate => integratestaterkck45
21613  end select
21614 
21615  allocate(output_constituent(size(config_phase)))
21616  do c = 1, size(config_phase)
21617 
21618  allocate(output_constituent(c)%label(1))
21619  output_constituent(c)%label(1)= 'GfortranBug86277'
21620  output_constituent(c)%label = config_phase(c)%getStrings('(output)',defaultval=output_constituent(c)%label )
21621  if (output_constituent(c)%label (1) == 'GfortranBug86277') output_constituent(c)%label = [character(len=pStringLen)::]
21622 
21623 
21624 
21625  enddo
21626 
21627  call config_deallocate('material.config/phase')
21628 
21629 !--------------------------------------------------------------------------------------------------
21630 ! initialize
21631  !$OMP PARALLEL DO PRIVATE(myNcomponents,i,c)
21634  do i = fesolving_execip(1), fesolving_execip(2); do c = 1, myncomponents
21635  crystallite_fp0(1:3,1:3,c,i,e) = material_orientation0(c,i,e)%asMatrix() ! plastic def gradient reflects init orientation
21636  crystallite_fp0(1:3,1:3,c,i,e) = crystallite_fp0(1:3,1:3,c,i,e) &
21637  / math_det33(crystallite_fp0(1:3,1:3,c,i,e))**(1.0_preal/3.0_preal)
21638  crystallite_fi0(1:3,1:3,c,i,e) = constitutive_initialfi(c,i,e)
21639  crystallite_f0(1:3,1:3,c,i,e) = math_i3
21640  crystallite_localplasticity(c,i,e) = phase_localplasticity(material_phaseat(c,e))
21641  crystallite_fe(1:3,1:3,c,i,e) = math_inv33(matmul(crystallite_fi0(1:3,1:3,c,i,e), &
21642  crystallite_fp0(1:3,1:3,c,i,e))) ! assuming that euler angles are given in internal strain free configuration
21643  crystallite_fp(1:3,1:3,c,i,e) = crystallite_fp0(1:3,1:3,c,i,e)
21644  crystallite_fi(1:3,1:3,c,i,e) = crystallite_fi0(1:3,1:3,c,i,e)
21645  crystallite_requested(c,i,e) = .true.
21646  enddo; enddo
21647  enddo
21648  !$OMP END PARALLEL DO
21649 
21650  if(any(.not. crystallite_localplasticity) .and. .not. usepingpong) call io_error(601) ! exit if nonlocal but no ping-pong ToDo: Why not check earlier? or in nonlocal?
21651 
21652  crystallite_partionedfp0 = crystallite_fp0
21653  crystallite_partionedfi0 = crystallite_fi0
21654  crystallite_partionedf0 = crystallite_f0
21655  crystallite_partionedf = crystallite_f0
21656 
21658 
21659  !$OMP PARALLEL DO
21661  do i = fesolving_execip(1),fesolving_execip(2)
21663  call constitutive_dependentstate(crystallite_partionedf0(1:3,1:3,c,i,e), &
21664  crystallite_partionedfp0(1:3,1:3,c,i,e), &
21665  c,i,e) ! update dependent state variables to be consistent with basic states
21666  enddo
21667  enddo
21668  enddo
21669  !$OMP END PARALLEL DO
21670 
21671  devnull = crystallite_stress()
21673 
21674 # 283 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/crystallite.f90"
21675 
21676 end subroutine crystallite_init
21677 
21678 
21679 !--------------------------------------------------------------------------------------------------
21681 !--------------------------------------------------------------------------------------------------
21682 function crystallite_stress(dummyArgumentToPreventInternalCompilerErrorWithGCC)
21684  logical, dimension(discretization_nIP,discretization_nElem) :: crystallite_stress
21685  real(preal), intent(in), optional :: &
21686  dummyargumenttopreventinternalcompilererrorwithgcc
21687  real(preal) :: &
21688  formersubstep
21689  integer :: &
21690  niterationcrystallite, & ! number of iterations in crystallite loop
21691  c, & !< counter in integration point component loop
21692  i, & !< counter in integration point loop
21693  e, & !< counter in element loop
21694  startip, endip, &
21695  s
21696 
21697 # 325 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/crystallite.f90"
21698 
21699 !--------------------------------------------------------------------------------------------------
21700 ! initialize to starting condition
21701  crystallite_substep = 0.0_preal
21702  !$OMP PARALLEL DO
21703  elementlooping1: do e = fesolving_execelem(1),fesolving_execelem(2)
21705  homogenizationrequestscalculation: if (crystallite_requested(c,i,e)) then
21706  plasticstate(material_phaseat(c,e))%subState0( :,material_phasememberat(c,i,e)) = &
21707  plasticstate(material_phaseat(c,e))%partionedState0(:,material_phasememberat(c,i,e))
21708 
21709  do s = 1, phase_nsources(material_phaseat(c,e))
21710  sourcestate(material_phaseat(c,e))%p(s)%subState0( :,material_phasememberat(c,i,e)) = &
21711  sourcestate(material_phaseat(c,e))%p(s)%partionedState0(:,material_phasememberat(c,i,e))
21712  enddo
21713  crystallite_subfp0(1:3,1:3,c,i,e) = crystallite_partionedfp0(1:3,1:3,c,i,e)
21714  crystallite_sublp0(1:3,1:3,c,i,e) = crystallite_partionedlp0(1:3,1:3,c,i,e)
21715  crystallite_subfi0(1:3,1:3,c,i,e) = crystallite_partionedfi0(1:3,1:3,c,i,e)
21716  crystallite_subli0(1:3,1:3,c,i,e) = crystallite_partionedli0(1:3,1:3,c,i,e)
21717  crystallite_subf0(1:3,1:3,c,i,e) = crystallite_partionedf0(1:3,1:3,c,i,e)
21718  crystallite_subfrac(c,i,e) = 0.0_preal
21719  crystallite_substep(c,i,e) = 1.0_preal/num%subStepSizeCryst
21720  crystallite_todo(c,i,e) = .true.
21721  crystallite_converged(c,i,e) = .false. ! pretend failed step of 1/subStepSizeCryst
21722  endif homogenizationrequestscalculation
21723  enddo; enddo
21724  enddo elementlooping1
21725  !$OMP END PARALLEL DO
21726 
21727  singlerun: if (fesolving_execelem(1) == fesolving_execelem(2) .and. &
21728  fesolving_execip(1) == fesolving_execip(2)) then
21729  startip = fesolving_execip(1)
21730  endip = startip
21731  else singlerun
21732  startip = 1
21733  endip = discretization_nip
21734  endif singlerun
21735 
21736  niterationcrystallite = 0
21737  cutbacklooping: do while (any(crystallite_todo(:,startip:endip,fesolving_execelem(1):fesolving_execelem(2))))
21738  niterationcrystallite = niterationcrystallite + 1
21739 
21740 
21741 
21742 
21743 
21744  !$OMP PARALLEL DO PRIVATE(formerSubStep)
21745  elementlooping3: do e = fesolving_execelem(1),fesolving_execelem(2)
21746  do i = fesolving_execip(1),fesolving_execip(2)
21748 !--------------------------------------------------------------------------------------------------
21749 ! wind forward
21750  if (crystallite_converged(c,i,e)) then
21751  formersubstep = crystallite_substep(c,i,e)
21752  crystallite_subfrac(c,i,e) = crystallite_subfrac(c,i,e) + crystallite_substep(c,i,e)
21753  crystallite_substep(c,i,e) = min(1.0_preal - crystallite_subfrac(c,i,e), &
21754  num%stepIncreaseCryst * crystallite_substep(c,i,e))
21755 
21756  crystallite_todo(c,i,e) = crystallite_substep(c,i,e) > 0.0_preal ! still time left to integrate on?
21757  if (crystallite_todo(c,i,e)) then
21758  crystallite_subf0(1:3,1:3,c,i,e) = crystallite_subf(1:3,1:3,c,i,e)
21759  crystallite_sublp0(1:3,1:3,c,i,e) = crystallite_lp(1:3,1:3,c,i,e)
21760  crystallite_subli0(1:3,1:3,c,i,e) = crystallite_li(1:3,1:3,c,i,e)
21761  crystallite_subfp0(1:3,1:3,c,i,e) = crystallite_fp(1:3,1:3,c,i,e)
21762  crystallite_subfi0(1:3,1:3,c,i,e) = crystallite_fi(1:3,1:3,c,i,e)
21763  !if abbrevation, make c and p private in omp
21764  plasticstate( material_phaseat(c,e))%subState0(:,material_phasememberat(c,i,e)) &
21765  = plasticstate(material_phaseat(c,e))%state( :,material_phasememberat(c,i,e))
21766  do s = 1, phase_nsources(material_phaseat(c,e))
21767  sourcestate( material_phaseat(c,e))%p(s)%subState0(:,material_phasememberat(c,i,e)) &
21768  = sourcestate(material_phaseat(c,e))%p(s)%state( :,material_phasememberat(c,i,e))
21769  enddo
21770  endif
21771 
21772 !--------------------------------------------------------------------------------------------------
21773 ! cut back (reduced time and restore)
21774  else
21775  crystallite_substep(c,i,e) = num%subStepSizeCryst * crystallite_substep(c,i,e)
21776  crystallite_fp(1:3,1:3,c,i,e) = crystallite_subfp0(1:3,1:3,c,i,e)
21777  crystallite_fi(1:3,1:3,c,i,e) = crystallite_subfi0(1:3,1:3,c,i,e)
21778  crystallite_s(1:3,1:3,c,i,e) = crystallite_s0(1:3,1:3,c,i,e)
21779  if (crystallite_substep(c,i,e) < 1.0_preal) then ! actual (not initial) cutback
21780  crystallite_lp(1:3,1:3,c,i,e) = crystallite_sublp0(1:3,1:3,c,i,e)
21781  crystallite_li(1:3,1:3,c,i,e) = crystallite_subli0(1:3,1:3,c,i,e)
21782  endif
21783  plasticstate(material_phaseat(c,e))%state( :,material_phasememberat(c,i,e)) &
21784  = plasticstate(material_phaseat(c,e))%subState0(:,material_phasememberat(c,i,e))
21785  do s = 1, phase_nsources(material_phaseat(c,e))
21786  sourcestate( material_phaseat(c,e))%p(s)%state( :,material_phasememberat(c,i,e)) &
21787  = sourcestate(material_phaseat(c,e))%p(s)%subState0(:,material_phasememberat(c,i,e))
21788  enddo
21789 
21790  ! cant restore dotState here, since not yet calculated in first cutback after initialization
21791  crystallite_todo(c,i,e) = crystallite_substep(c,i,e) > num%subStepMinCryst ! still on track or already done (beyond repair)
21792  endif
21793 
21794 !--------------------------------------------------------------------------------------------------
21795 ! prepare for integration
21796  if (crystallite_todo(c,i,e)) then
21797  crystallite_subf(1:3,1:3,c,i,e) = crystallite_subf0(1:3,1:3,c,i,e) &
21798  + crystallite_substep(c,i,e) *( crystallite_partionedf(1:3,1:3,c,i,e) &
21799  -crystallite_partionedf0(1:3,1:3,c,i,e))
21800  crystallite_fe(1:3,1:3,c,i,e) = matmul(matmul(crystallite_subf(1:3,1:3,c,i,e), &
21801  math_inv33(crystallite_fp(1:3,1:3,c,i,e))), &
21802  math_inv33(crystallite_fi(1:3,1:3,c,i,e)))
21803  crystallite_subdt(c,i,e) = crystallite_substep(c,i,e) * crystallite_dt(c,i,e)
21804  crystallite_converged(c,i,e) = .false.
21805  endif
21806 
21807  enddo
21808  enddo
21809  enddo elementlooping3
21810  !$OMP END PARALLEL DO
21811 
21812 !--------------------------------------------------------------------------------------------------
21813 ! integrate --- requires fully defined state array (basic + dependent state)
21814  if (any(crystallite_todo)) call integratestate ! TODO: unroll into proper elementloop to avoid N^2 for single point evaluation
21815  where(.not. crystallite_converged .and. crystallite_substep > num%subStepMinCryst) & ! do not try non-converged but fully cutbacked any further
21816  crystallite_todo = .true. ! TODO: again unroll this into proper elementloop to avoid N^2 for single point evaluation
21817 
21818 
21819  enddo cutbacklooping
21820 
21821 ! return whether converged or not
21822  crystallite_stress = .false.
21823  elementlooping5: do e = fesolving_execelem(1),fesolving_execelem(2)
21824  do i = fesolving_execip(1),fesolving_execip(2)
21825  crystallite_stress(i,e) = all(crystallite_converged(:,i,e))
21826  enddo
21827  enddo elementlooping5
21828 
21829 end function crystallite_stress
21830 
21831 
21832 !--------------------------------------------------------------------------------------------------
21834 !--------------------------------------------------------------------------------------------------
21835 subroutine crystallite_stresstangent
21837  integer :: &
21838  c, & !< counter in integration point component loop
21839  i, & !< counter in integration point loop
21840  e, & !< counter in element loop
21841  o, &
21842  p
21843 
21844  real(pReal), dimension(3,3) :: devNull, &
21845  invSubFp0,invSubFi0,invFp,invFi, &
21846  temp_33_1, temp_33_2, temp_33_3, temp_33_4
21847  real(pReal), dimension(3,3,3,3) :: dSdFe, &
21848  dSdF, &
21849  dSdFi, &
21850  dLidS, & ! tangent in lattice configuration
21851  dLidFi, &
21852  dLpdS, &
21853  dLpdFi, &
21854  dFidS, &
21855  dFpinvdF, &
21856  rhs_3333, &
21857  lhs_3333, &
21858  temp_3333
21859  real(pReal), dimension(9,9):: temp_99
21860  logical :: error
21861 
21862  !$OMP PARALLEL DO PRIVATE(dSdF,dSdFe,dSdFi,dLpdS,dLpdFi,dFpinvdF,dLidS,dLidFi,dFidS,o,p, &
21863  !$OMP invSubFp0,invSubFi0,invFp,invFi, &
21864  !$OMP rhs_3333,lhs_3333,temp_99,temp_33_1,temp_33_2,temp_33_3,temp_33_4,temp_3333,error)
21865  elementlooping: do e = fesolving_execelem(1),fesolving_execelem(2)
21866  do i = fesolving_execip(1),fesolving_execip(2)
21868 
21869  call constitutive_sanditstangents(devnull,dsdfe,dsdfi, &
21870  crystallite_fe(1:3,1:3,c,i,e), &
21871  crystallite_fi(1:3,1:3,c,i,e),c,i,e)
21872  call constitutive_lianditstangents(devnull,dlids,dlidfi, &
21873  crystallite_s(1:3,1:3,c,i,e), &
21874  crystallite_fi(1:3,1:3,c,i,e), &
21875  c,i,e)
21876 
21877  invfp = math_inv33(crystallite_fp(1:3,1:3,c,i,e))
21878  invfi = math_inv33(crystallite_fi(1:3,1:3,c,i,e))
21879  invsubfp0 = math_inv33(crystallite_subfp0(1:3,1:3,c,i,e))
21880  invsubfi0 = math_inv33(crystallite_subfi0(1:3,1:3,c,i,e))
21881 
21882  if (sum(abs(dlids)) < tol_math_check) then
21883  dfids = 0.0_preal
21884  else
21885  lhs_3333 = 0.0_preal; rhs_3333 = 0.0_preal
21886  do o=1,3; do p=1,3
21887  lhs_3333(1:3,1:3,o,p) = lhs_3333(1:3,1:3,o,p) &
21888  + crystallite_subdt(c,i,e)*matmul(invsubfi0,dlidfi(1:3,1:3,o,p))
21889  lhs_3333(1:3,o,1:3,p) = lhs_3333(1:3,o,1:3,p) &
21890  + invfi*invfi(p,o)
21891  rhs_3333(1:3,1:3,o,p) = rhs_3333(1:3,1:3,o,p) &
21892  - crystallite_subdt(c,i,e)*matmul(invsubfi0,dlids(1:3,1:3,o,p))
21893  enddo; enddo
21894  call math_invert(temp_99,error,math_3333to99(lhs_3333))
21895  if (error) then
21896  call io_warning(warning_id=600,el=e,ip=i,g=c, &
21897  ext_msg='inversion error in analytic tangent calculation')
21898  dfids = 0.0_preal
21899  else
21900  dfids = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333)
21901  endif
21902  dlids = math_mul3333xx3333(dlidfi,dfids) + dlids
21903  endif
21904 
21905  call constitutive_lpanditstangents(devnull,dlpds,dlpdfi, &
21906  crystallite_s(1:3,1:3,c,i,e), &
21907  crystallite_fi(1:3,1:3,c,i,e),c,i,e) ! call constitutive law to calculate Lp tangent in lattice configuration
21908  dlpds = math_mul3333xx3333(dlpdfi,dfids) + dlpds
21909 
21910 !--------------------------------------------------------------------------------------------------
21911 ! calculate dSdF
21912  temp_33_1 = transpose(matmul(invfp,invfi))
21913  temp_33_2 = matmul(crystallite_subf(1:3,1:3,c,i,e),invsubfp0)
21914  temp_33_3 = matmul(matmul(crystallite_subf(1:3,1:3,c,i,e),invfp), invsubfi0)
21915 
21916  do o=1,3; do p=1,3
21917  rhs_3333(p,o,1:3,1:3) = matmul(dsdfe(p,o,1:3,1:3),temp_33_1)
21918  temp_3333(1:3,1:3,p,o) = matmul(matmul(temp_33_2,dlpds(1:3,1:3,p,o)), invfi) &
21919  + matmul(temp_33_3,dlids(1:3,1:3,p,o))
21920  enddo; enddo
21921  lhs_3333 = crystallite_subdt(c,i,e)*math_mul3333xx3333(dsdfe,temp_3333) &
21922  + math_mul3333xx3333(dsdfi,dfids)
21923 
21924  call math_invert(temp_99,error,math_identity2nd(9)+math_3333to99(lhs_3333))
21925  if (error) then
21926  call io_warning(warning_id=600,el=e,ip=i,g=c, &
21927  ext_msg='inversion error in analytic tangent calculation')
21928  dsdf = rhs_3333
21929  else
21930  dsdf = math_mul3333xx3333(math_99to3333(temp_99),rhs_3333)
21931  endif
21932 
21933 !--------------------------------------------------------------------------------------------------
21934 ! calculate dFpinvdF
21935  temp_3333 = math_mul3333xx3333(dlpds,dsdf)
21936  do o=1,3; do p=1,3
21937  dfpinvdf(1:3,1:3,p,o) = -crystallite_subdt(c,i,e) &
21938  * matmul(invsubfp0, matmul(temp_3333(1:3,1:3,p,o),invfi))
21939  enddo; enddo
21940 
21941 !--------------------------------------------------------------------------------------------------
21942 ! assemble dPdF
21943  temp_33_1 = matmul(crystallite_s(1:3,1:3,c,i,e),transpose(invfp))
21944  temp_33_2 = matmul(invfp,temp_33_1)
21945  temp_33_3 = matmul(crystallite_subf(1:3,1:3,c,i,e),invfp)
21946  temp_33_4 = matmul(temp_33_3,crystallite_s(1:3,1:3,c,i,e))
21947 
21948  crystallite_dpdf(1:3,1:3,1:3,1:3,c,i,e) = 0.0_preal
21949  do p=1,3
21950  crystallite_dpdf(p,1:3,p,1:3,c,i,e) = transpose(temp_33_2)
21951  enddo
21952  do o=1,3; do p=1,3
21953  crystallite_dpdf(1:3,1:3,p,o,c,i,e) = crystallite_dpdf(1:3,1:3,p,o,c,i,e) &
21954  + matmul(matmul(crystallite_subf(1:3,1:3,c,i,e), &
21955  dfpinvdf(1:3,1:3,p,o)),temp_33_1) &
21956  + matmul(matmul(temp_33_3,dsdf(1:3,1:3,p,o)), &
21957  transpose(invfp)) &
21958  + matmul(temp_33_4,transpose(dfpinvdf(1:3,1:3,p,o)))
21959  enddo; enddo
21960 
21961  enddo; enddo
21962  enddo elementlooping
21963  !$OMP END PARALLEL DO
21964 
21965 end subroutine crystallite_stresstangent
21966 
21967 
21968 !--------------------------------------------------------------------------------------------------
21970 !--------------------------------------------------------------------------------------------------
21971 subroutine crystallite_orientations
21973  integer &
21974  c, & !< counter in integration point component loop
21975  i, & !< counter in integration point loop
21976  e
21977 
21978  !$OMP PARALLEL DO
21980  do i = fesolving_execip(1),fesolving_execip(2)
21982  call crystallite_orientation(c,i,e)%fromMatrix(transpose(math_rotationalpart(crystallite_fe(1:3,1:3,c,i,e))))
21983  enddo; enddo; enddo
21984  !$OMP END PARALLEL DO
21985 
21986  nonlocalpresent: if (any(plasticstate%nonLocal)) then
21987  !$OMP PARALLEL DO
21989  do i = fesolving_execip(1),fesolving_execip(2)
21990  if (plasticstate(material_phaseat(1,e))%nonLocal) &
21991  call plastic_nonlocal_updatecompatibility(crystallite_orientation, &
21993  enddo; enddo
21994  !$OMP END PARALLEL DO
21995  endif nonlocalpresent
21996 
21997 end subroutine crystallite_orientations
21998 
21999 
22000 !--------------------------------------------------------------------------------------------------
22002 !--------------------------------------------------------------------------------------------------
22003 function crystallite_push33toref(ipc,ip,el, tensor33)
22005  real(preal), dimension(3,3) :: crystallite_push33toref
22006  real(preal), dimension(3,3), intent(in) :: tensor33
22007  real(preal), dimension(3,3) :: t
22008  integer, intent(in):: &
22009  el, &
22010  ip, &
22011  ipc
22012 
22013  t = matmul(material_orientation0(ipc,ip,el)%asMatrix(), & ! ToDo: initial orientation correct?
22014  transpose(math_inv33(crystallite_subf(1:3,1:3,ipc,ip,el))))
22015  crystallite_push33toref = matmul(transpose(t),matmul(tensor33,t))
22016 
22017 end function crystallite_push33toref
22018 
22019 
22020 !--------------------------------------------------------------------------------------------------
22022 !--------------------------------------------------------------------------------------------------
22023 subroutine crystallite_results
22025  integer :: p,o
22026  real(pReal), allocatable, dimension(:,:,:) :: selected_tensors
22027  type(rotation), allocatable, dimension(:) :: selected_rotations
22028  character(len=pStringLen) :: group,structureLabel
22029 
22030  do p=1,size(config_name_phase)
22031  group = trim('current/constituent')//'/'//trim(config_name_phase(p))//'/generic'
22032 
22034 
22035  do o = 1, size(output_constituent(p)%label)
22036  select case (output_constituent(p)%label(o))
22037  case('f')
22038  selected_tensors = select_tensors(crystallite_partionedf,p)
22039  call results_writedataset(group,selected_tensors,'F',&
22040  'deformation gradient','1')
22041  case('fe')
22042  selected_tensors = select_tensors(crystallite_fe,p)
22043  call results_writedataset(group,selected_tensors,'Fe',&
22044  'elastic deformation gradient','1')
22045  case('fp')
22046  selected_tensors = select_tensors(crystallite_fp,p)
22047  call results_writedataset(group,selected_tensors,'Fp',&
22048  'plastic deformation gradient','1')
22049  case('fi')
22050  selected_tensors = select_tensors(crystallite_fi,p)
22051  call results_writedataset(group,selected_tensors,'Fi',&
22052  'inelastic deformation gradient','1')
22053  case('lp')
22054  selected_tensors = select_tensors(crystallite_lp,p)
22055  call results_writedataset(group,selected_tensors,'Lp',&
22056  'plastic velocity gradient','1/s')
22057  case('li')
22058  selected_tensors = select_tensors(crystallite_li,p)
22059  call results_writedataset(group,selected_tensors,'Li',&
22060  'inelastic velocity gradient','1/s')
22061  case('p')
22062  selected_tensors = select_tensors(crystallite_p,p)
22063  call results_writedataset(group,selected_tensors,'P',&
22064  'First Piola-Kirchoff stress','Pa')
22065  case('s')
22066  selected_tensors = select_tensors(crystallite_s,p)
22067  call results_writedataset(group,selected_tensors,'S',&
22068  'Second Piola-Kirchoff stress','Pa')
22069  case('orientation')
22070  select case(lattice_structure(p))
22071  case(lattice_iso_id)
22072  structurelabel = 'iso'
22073  case(lattice_fcc_id)
22074  structurelabel = 'fcc'
22075  case(lattice_bcc_id)
22076  structurelabel = 'bcc'
22077  case(lattice_bct_id)
22078  structurelabel = 'bct'
22079  case(lattice_hex_id)
22080  structurelabel = 'hex'
22081  case(lattice_ort_id)
22082  structurelabel = 'ort'
22083  end select
22084  selected_rotations = select_rotations(crystallite_orientation,p)
22085  call results_writedataset(group,selected_rotations,'orientation',&
22086  'crystal orientation as quaternion',structurelabel)
22087  end select
22088  enddo
22089  enddo
22090 
22091  contains
22092 
22093  !------------------------------------------------------------------------------------------------
22095  !------------------------------------------------------------------------------------------------
22096  function select_tensors(dataset,instance)
22098  integer, intent(in) :: instance
22099  real(preal), dimension(:,:,:,:,:), intent(in) :: dataset
22100  real(preal), allocatable, dimension(:,:,:) :: select_tensors
22101  integer :: e,i,c,j
22102 
22103  allocate(select_tensors(3,3,count(material_phaseat==instance)*discretization_nip))
22104 
22105  j=0
22106  do e = 1, size(material_phaseat,2)
22107  do i = 1, discretization_nip
22108  do c = 1, size(material_phaseat,1) !ToDo: this needs to be changed for varying Ngrains
22109  if (material_phaseat(c,e) == instance) then
22110  j = j + 1
22111  select_tensors(1:3,1:3,j) = dataset(1:3,1:3,c,i,e)
22112  endif
22113  enddo
22114  enddo
22115  enddo
22116 
22117  end function select_tensors
22118 
22119 
22120 !--------------------------------------------------------------------------------------------------
22122 !--------------------------------------------------------------------------------------------------
22123  function select_rotations(dataset,instance)
22125  integer, intent(in) :: instance
22126  type(rotation), dimension(:,:,:), intent(in) :: dataset
22127  type(rotation), allocatable, dimension(:) :: select_rotations
22128  integer :: e,i,c,j
22129 
22131 
22132  j=0
22133  do e = 1, size(material_phaseat,2)
22134  do i = 1, discretization_nip
22135  do c = 1, size(material_phaseat,1) !ToDo: this needs to be changed for varying Ngrains
22136  if (material_phaseat(c,e) == instance) then
22137  j = j + 1
22138  select_rotations(j) = dataset(c,i,e)
22139  endif
22140  enddo
22141  enddo
22142  enddo
22143 
22144  end function select_rotations
22145 
22146 end subroutine crystallite_results
22147 
22148 
22149 !--------------------------------------------------------------------------------------------------
22152 !--------------------------------------------------------------------------------------------------
22153 logical function integratestress(ipc,ip,el,timeFraction)
22155  integer, intent(in):: el, & ! element index
22156  ip, & ! integration point index
22157  ipc ! grain index
22158  real(preal), optional, intent(in) :: timefraction ! fraction of timestep
22159 
22160  real(preal), dimension(3,3):: f, & ! deformation gradient at end of timestep
22161  fp_new, & ! plastic deformation gradient at end of timestep
22162  invfp_new, & ! inverse of Fp_new
22163  invfp_current, & ! inverse of Fp_current
22164  lpguess, & ! current guess for plastic velocity gradient
22165  lpguess_old, & ! known last good guess for plastic velocity gradient
22166  lp_constitutive, & ! plastic velocity gradient resulting from constitutive law
22167  residuumlp, & ! current residuum of plastic velocity gradient
22168  residuumlp_old, & ! last residuum of plastic velocity gradient
22169  deltalp, & ! direction of next guess
22170  fi_new, & ! gradient of intermediate deformation stages
22171  invfi_new, &
22172  invfi_current, & ! inverse of Fi_current
22173  liguess, & ! current guess for intermediate velocity gradient
22174  liguess_old, & ! known last good guess for intermediate velocity gradient
22175  li_constitutive, & ! intermediate velocity gradient resulting from constitutive law
22176  residuumli, & ! current residuum of intermediate velocity gradient
22177  residuumli_old, & ! last residuum of intermediate velocity gradient
22178  deltali, & ! direction of next guess
22179  fe, & ! elastic deformation gradient
22180  fe_new, &
22181  s, & ! 2nd Piola-Kirchhoff Stress in plastic (lattice) configuration
22182  a, &
22183  b, &
22184  temp_33
22185  real(preal), dimension(9) :: temp_9 ! needed for matrix inversion by LAPACK
22186  integer, dimension(9) :: devnull_9 ! needed for matrix inversion by LAPACK
22187  real(preal), dimension(9,9) :: drlp_dlp, & ! partial derivative of residuum (Jacobian for Newton-Raphson scheme)
22188  drli_dli ! partial derivative of residuumI (Jacobian for Newton-Raphson scheme)
22189  real(preal), dimension(3,3,3,3):: ds_dfe, & ! partial derivative of 2nd Piola-Kirchhoff stress
22190  ds_dfi, &
22191  dfe_dlp, & ! partial derivative of elastic deformation gradient
22192  dfe_dli, &
22193  dfi_dli, &
22194  dlp_dfi, &
22195  dli_dfi, &
22196  dlp_ds, &
22197  dli_ds
22198  real(preal) steplengthlp, &
22199  steplengthli, &
22200  dt, & ! time increment
22201  atol_lp, &
22202  atol_li, &
22203  devnull
22204  integer niterationstresslp, & ! number of stress integrations
22205  niterationstressli, & ! number of inner stress integrations
22206  ierr, & ! error indicator for LAPACK
22207  o, &
22208  p, &
22209  jacocounterlp, &
22210  jacocounterli ! counters to check for Jacobian update
22211  logical :: error
22212  external :: &
22213  dgesv
22214 
22215  integratestress = .false.
22216 
22217  if (present(timefraction)) then
22218  dt = crystallite_subdt(ipc,ip,el) * timefraction
22219  f = crystallite_subf0(1:3,1:3,ipc,ip,el) &
22220  + (crystallite_subf(1:3,1:3,ipc,ip,el) - crystallite_subf0(1:3,1:3,ipc,ip,el)) * timefraction
22221  else
22222  dt = crystallite_subdt(ipc,ip,el)
22223  f = crystallite_subf(1:3,1:3,ipc,ip,el)
22224  endif
22225 
22226  lpguess = crystallite_lp(1:3,1:3,ipc,ip,el) ! take as first guess
22227  liguess = crystallite_li(1:3,1:3,ipc,ip,el) ! take as first guess
22228 
22229  call math_invert33(invfp_current,devnull,error,crystallite_subfp0(1:3,1:3,ipc,ip,el))
22230  if (error) return ! error
22231  call math_invert33(invfi_current,devnull,error,crystallite_subfi0(1:3,1:3,ipc,ip,el))
22232  if (error) return ! error
22233 
22234  a = matmul(f,invfp_current) ! intermediate tensor needed later to calculate dFe_dLp
22235 
22236  jacocounterli = 0
22237  steplengthli = 1.0_preal
22238  residuumli_old = 0.0_preal
22239  liguess_old = liguess
22240 
22241  niterationstressli = 0
22242  liloop: do
22243  niterationstressli = niterationstressli + 1
22244  if (niterationstressli>num%nStress) return ! error
22245 
22246  invfi_new = matmul(invfi_current,math_i3 - dt*liguess)
22247  fi_new = math_inv33(invfi_new)
22248 
22249  jacocounterlp = 0
22250  steplengthlp = 1.0_preal
22251  residuumlp_old = 0.0_preal
22252  lpguess_old = lpguess
22253 
22254  niterationstresslp = 0
22255  lploop: do
22256  niterationstresslp = niterationstresslp + 1
22257  if (niterationstresslp>num%nStress) return ! error
22258 
22259  b = math_i3 - dt*lpguess
22260  fe = matmul(matmul(a,b), invfi_new)
22261  call constitutive_sanditstangents(s, ds_dfe, ds_dfi, &
22262  fe, fi_new, ipc, ip, el)
22263 
22264  call constitutive_lpanditstangents(lp_constitutive, dlp_ds, dlp_dfi, &
22265  s, fi_new, ipc, ip, el)
22266 
22267  !* update current residuum and check for convergence of loop
22268  atol_lp = max(num%rtol_crystalliteStress * max(norm2(lpguess),norm2(lp_constitutive)), & ! absolute tolerance from largest acceptable relative error
22269  num%atol_crystalliteStress) ! minimum lower cutoff
22270  residuumlp = lpguess - lp_constitutive
22271 
22272  if (any(ieee_is_nan(residuumlp))) then
22273  return ! error
22274  elseif (norm2(residuumlp) < atol_lp) then ! converged if below absolute tolerance
22275  exit lploop
22276  elseif (niterationstresslp == 1 .or. norm2(residuumlp) < norm2(residuumlp_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)...
22277  residuumlp_old = residuumlp ! ...remember old values and...
22278  lpguess_old = lpguess
22279  steplengthlp = 1.0_preal ! ...proceed with normal step length (calculate new search direction)
22280  else ! not converged and residuum not improved...
22281  steplengthlp = num%subStepSizeLp * steplengthlp ! ...try with smaller step length in same direction
22282  lpguess = lpguess_old &
22283  + deltalp * steplengthlp
22284  cycle lploop
22285  endif
22286 
22287  !* calculate Jacobian for correction term
22288  if (mod(jacocounterlp, num%iJacoLpresiduum) == 0) then
22289  jacocounterlp = jacocounterlp + 1
22290 
22291  do o=1,3; do p=1,3
22292  dfe_dlp(o,1:3,p,1:3) = a(o,p)*transpose(invfi_new) ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j)
22293  enddo; enddo
22294  dfe_dlp = - dt * dfe_dlp
22295  drlp_dlp = math_identity2nd(9) &
22296  - math_3333to99(math_mul3333xx3333(math_mul3333xx3333(dlp_ds,ds_dfe),dfe_dlp))
22297  temp_9 = math_33to9(residuumlp)
22298  call dgesv(9,1,drlp_dlp,9,devnull_9,temp_9,9,ierr) ! solve dRLp/dLp * delta Lp = -res for delta Lp
22299  if (ierr /= 0) return ! error
22300  deltalp = - math_9to33(temp_9)
22301  endif
22302 
22303  lpguess = lpguess &
22304  + deltalp * steplengthlp
22305  enddo lploop
22306 
22307  call constitutive_lianditstangents(li_constitutive, dli_ds, dli_dfi, &
22308  s, fi_new, ipc, ip, el)
22309 
22310  !* update current residuum and check for convergence of loop
22311  atol_li = max(num%rtol_crystalliteStress * max(norm2(liguess),norm2(li_constitutive)), & ! absolute tolerance from largest acceptable relative error
22312  num%atol_crystalliteStress) ! minimum lower cutoff
22313  residuumli = liguess - li_constitutive
22314  if (any(ieee_is_nan(residuumli))) then
22315  return ! error
22316  elseif (norm2(residuumli) < atol_li) then ! converged if below absolute tolerance
22317  exit liloop
22318  elseif (niterationstressli == 1 .or. norm2(residuumli) < norm2(residuumli_old)) then ! not converged, but improved norm of residuum (always proceed in first iteration)...
22319  residuumli_old = residuumli ! ...remember old values and...
22320  liguess_old = liguess
22321  steplengthli = 1.0_preal ! ...proceed with normal step length (calculate new search direction)
22322  else ! not converged and residuum not improved...
22323  steplengthli = num%subStepSizeLi * steplengthli ! ...try with smaller step length in same direction
22324  liguess = liguess_old &
22325  + deltali * steplengthli
22326  cycle liloop
22327  endif
22328 
22329  !* calculate Jacobian for correction term
22330  if (mod(jacocounterli, num%iJacoLpresiduum) == 0) then
22331  jacocounterli = jacocounterli + 1
22332 
22333  temp_33 = matmul(matmul(a,b),invfi_current)
22334  do o=1,3; do p=1,3
22335  dfe_dli(1:3,o,1:3,p) = -dt*math_i3(o,p)*temp_33 ! dFe_dLp(i,j,k,l) = -dt * A(i,k) invFi(l,j)
22336  dfi_dli(1:3,o,1:3,p) = -dt*math_i3(o,p)*invfi_current
22337  enddo; enddo
22338  do o=1,3; do p=1,3
22339  dfi_dli(1:3,1:3,o,p) = matmul(matmul(fi_new,dfi_dli(1:3,1:3,o,p)),fi_new)
22340  enddo; enddo
22341  drli_dli = math_identity2nd(9) &
22342  - math_3333to99(math_mul3333xx3333(dli_ds, math_mul3333xx3333(ds_dfe, dfe_dli) &
22343  + math_mul3333xx3333(ds_dfi, dfi_dli))) &
22344  - math_3333to99(math_mul3333xx3333(dli_dfi, dfi_dli))
22345  temp_9 = math_33to9(residuumli)
22346  call dgesv(9,1,drli_dli,9,devnull_9,temp_9,9,ierr) ! solve dRLi/dLp * delta Li = -res for delta Li
22347  if (ierr /= 0) return ! error
22348  deltali = - math_9to33(temp_9)
22349  endif
22350 
22351  liguess = liguess &
22352  + deltali * steplengthli
22353  enddo liloop
22354 
22355  invfp_new = matmul(invfp_current,b)
22356  call math_invert33(fp_new,devnull,error,invfp_new)
22357  if (error) return ! error
22358  fp_new = fp_new / math_det33(fp_new)**(1.0_preal/3.0_preal) ! regularize
22359  fe_new = matmul(matmul(f,invfp_new),invfi_new)
22360 
22361  integratestress = .true.
22362  crystallite_p(1:3,1:3,ipc,ip,el) = matmul(matmul(f,invfp_new),matmul(s,transpose(invfp_new)))
22363  crystallite_s(1:3,1:3,ipc,ip,el) = s
22364  crystallite_lp(1:3,1:3,ipc,ip,el) = lpguess
22365  crystallite_li(1:3,1:3,ipc,ip,el) = liguess
22366  crystallite_fp(1:3,1:3,ipc,ip,el) = fp_new
22367  crystallite_fi(1:3,1:3,ipc,ip,el) = fi_new
22368  crystallite_fe(1:3,1:3,ipc,ip,el) = fe_new
22369 
22370 end function integratestress
22371 
22372 
22373 !--------------------------------------------------------------------------------------------------
22376 !--------------------------------------------------------------------------------------------------
22377 subroutine integratestatefpi
22379  integer :: &
22380  NiterationState, & !< number of iterations in state loop
22381  e, & !< element index in element loop
22382  i, & !< integration point index in ip loop
22383  g, & !< grain index in grain loop
22384  p, &
22385  c, &
22386  s, &
22387  sizeDotState
22388  real(pReal) :: &
22389  zeta
22390  real(pReal), dimension(constitutive_plasticity_maxSizeDotState) :: &
22391  residuum_plastic ! residuum for plastic state
22392  real(pReal), dimension(constitutive_source_maxSizeDotState) :: &
22393  residuum_source ! residuum for source state
22394  logical :: &
22395  nonlocalBroken
22396 
22397  nonlocalbroken = .false.
22398  !$OMP PARALLEL DO PRIVATE(sizeDotState,residuum_plastic,residuum_source,zeta,p,c)
22400  do i = fesolving_execip(1),fesolving_execip(2)
22402  if(crystallite_todo(g,i,e) .and. (.not. nonlocalbroken .or. crystallite_localplasticity(g,i,e)) ) then
22403 
22404  p = material_phaseat(g,e); c = material_phasememberat(g,i,e)
22405 
22406  call constitutive_collectdotstate(crystallite_s(1:3,1:3,g,i,e), &
22407  crystallite_partionedf0, &
22408  crystallite_fi(1:3,1:3,g,i,e), &
22409  crystallite_partionedfp0, &
22410  crystallite_subdt(g,i,e), g,i,e)
22411  crystallite_todo(g,i,e) = all(.not. ieee_is_nan(plasticstate(p)%dotState(:,c)))
22412  do s = 1, phase_nsources(p)
22413  crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. all(.not. ieee_is_nan(sourcestate(p)%p(s)%dotState(:,c)))
22414  enddo
22415  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22416  nonlocalbroken = .true.
22417  if(.not. crystallite_todo(g,i,e)) cycle
22418 
22419  sizedotstate = plasticstate(p)%sizeDotState
22420  plasticstate(p)%state(1:sizedotstate,c) = plasticstate(p)%subState0(1:sizedotstate,c) &
22421  + plasticstate(p)%dotState (1:sizedotstate,c) &
22422  * crystallite_subdt(g,i,e)
22423  do s = 1, phase_nsources(p)
22424  sizedotstate = sourcestate(p)%p(s)%sizeDotState
22425  sourcestate(p)%p(s)%state(1:sizedotstate,c) = sourcestate(p)%p(s)%subState0(1:sizedotstate,c) &
22426  + sourcestate(p)%p(s)%dotState (1:sizedotstate,c) &
22427  * crystallite_subdt(g,i,e)
22428  enddo
22429 
22430  iteration: do niterationstate = 1, num%nState
22431 
22432  plasticstate(p)%previousDotState2(:,c) = merge(plasticstate(p)%previousDotState(:,c),&
22433  0.0_preal,&
22434  niterationstate > 1)
22435  plasticstate(p)%previousDotState (:,c) = plasticstate(p)%dotState(:,c)
22436  do s = 1, phase_nsources(p)
22437  sourcestate(p)%p(s)%previousDotState2(:,c) = merge(sourcestate(p)%p(s)%previousDotState(:,c),&
22438  0.0_preal, &
22439  niterationstate > 1)
22440  sourcestate(p)%p(s)%previousDotState (:,c) = sourcestate(p)%p(s)%dotState(:,c)
22441  enddo
22442 
22443  call constitutive_dependentstate(crystallite_partionedf(1:3,1:3,g,i,e), &
22444  crystallite_fp(1:3,1:3,g,i,e), &
22445  g, i, e)
22446 
22447  crystallite_todo(g,i,e) = integratestress(g,i,e)
22448  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22449  nonlocalbroken = .true.
22450  if(.not. crystallite_todo(g,i,e)) exit iteration
22451 
22452  call constitutive_collectdotstate(crystallite_s(1:3,1:3,g,i,e), &
22453  crystallite_partionedf0, &
22454  crystallite_fi(1:3,1:3,g,i,e), &
22455  crystallite_partionedfp0, &
22456  crystallite_subdt(g,i,e), g,i,e)
22457  crystallite_todo(g,i,e) = all(.not. ieee_is_nan(plasticstate(p)%dotState(:,c)))
22458  do s = 1, phase_nsources(p)
22459  crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. all(.not. ieee_is_nan(sourcestate(p)%p(s)%dotState(:,c)))
22460  enddo
22461  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22462  nonlocalbroken = .true.
22463  if(.not. crystallite_todo(g,i,e)) exit iteration
22464 
22465  sizedotstate = plasticstate(p)%sizeDotState
22466  zeta = damper(plasticstate(p)%dotState (:,c), &
22467  plasticstate(p)%previousDotState (:,c), &
22468  plasticstate(p)%previousDotState2(:,c))
22469  plasticstate(p)%dotState(:,c) = plasticstate(p)%dotState(:,c) * zeta &
22470  + plasticstate(p)%previousDotState(:,c) * (1.0_preal - zeta)
22471  residuum_plastic(1:sizedotstate) = plasticstate(p)%state (1:sizedotstate,c) &
22472  - plasticstate(p)%subState0(1:sizedotstate,c) &
22473  - plasticstate(p)%dotState (1:sizedotstate,c) &
22474  * crystallite_subdt(g,i,e)
22475  plasticstate(p)%state(1:sizedotstate,c) = plasticstate(p)%state(1:sizedotstate,c) &
22476  - residuum_plastic(1:sizedotstate)
22477  crystallite_converged(g,i,e) = converged(residuum_plastic(1:sizedotstate), &
22478  plasticstate(p)%state(1:sizedotstate,c), &
22479  plasticstate(p)%atol(1:sizedotstate))
22480  do s = 1, phase_nsources(p)
22481  sizedotstate = sourcestate(p)%p(s)%sizeDotState
22482  zeta = damper(sourcestate(p)%p(s)%dotState (:,c), &
22483  sourcestate(p)%p(s)%previousDotState (:,c), &
22484  sourcestate(p)%p(s)%previousDotState2(:,c))
22485  sourcestate(p)%p(s)%dotState(:,c) = sourcestate(p)%p(s)%dotState(:,c) * zeta &
22486  + sourcestate(p)%p(s)%previousDotState(:,c)* (1.0_preal - zeta)
22487  residuum_source(1:sizedotstate) = sourcestate(p)%p(s)%state (1:sizedotstate,c) &
22488  - sourcestate(p)%p(s)%subState0(1:sizedotstate,c) &
22489  - sourcestate(p)%p(s)%dotState (1:sizedotstate,c) &
22490  * crystallite_subdt(g,i,e)
22491  sourcestate(p)%p(s)%state(1:sizedotstate,c) = sourcestate(p)%p(s)%state(1:sizedotstate,c) &
22492  - residuum_source(1:sizedotstate)
22493  crystallite_converged(g,i,e) = &
22494  crystallite_converged(g,i,e) .and. converged(residuum_source(1:sizedotstate), &
22495  sourcestate(p)%p(s)%state(1:sizedotstate,c), &
22496  sourcestate(p)%p(s)%atol(1:sizedotstate))
22497  enddo
22498 
22499  if(crystallite_converged(g,i,e)) then
22500  crystallite_todo(g,i,e) = statejump(g,i,e)
22501  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22502  nonlocalbroken = .true.
22503  exit iteration
22504  endif
22505 
22506  enddo iteration
22507 
22508  endif
22509  enddo; enddo; enddo
22510  !$OMP END PARALLEL DO
22511 
22512  if(nonlocalbroken) where(.not. crystallite_localplasticity) crystallite_todo = .false.
22513  if (any(plasticstate(:)%nonlocal)) call nonlocalconvergencecheck
22514 
22515  contains
22516 
22517  !--------------------------------------------------------------------------------------------------
22519  !--------------------------------------------------------------------------------------------------
22520  real(pReal) pure function damper(current,previous,previous2)
22522  real(preal), dimension(:), intent(in) ::&
22523  current, previous, previous2
22524 
22525  real(preal) :: dot_prod12, dot_prod22
22526 
22527  dot_prod12 = dot_product(current - previous, previous - previous2)
22528  dot_prod22 = dot_product(previous - previous2, previous - previous2)
22529  if ((dot_product(current,previous) < 0.0_preal .or. dot_prod12 < 0.0_preal) .and. dot_prod22 > 0.0_preal) then
22530  damper = 0.75_preal + 0.25_preal * tanh(2.0_preal + 4.0_preal * dot_prod12 / dot_prod22)
22531  else
22532  damper = 1.0_preal
22533  endif
22534 
22535  end function damper
22536 
22537 end subroutine integratestatefpi
22538 
22539 
22540 !--------------------------------------------------------------------------------------------------
22542 !--------------------------------------------------------------------------------------------------
22543 subroutine integratestateeuler
22545  integer :: &
22546  e, & !< element index in element loop
22547  i, & !< integration point index in ip loop
22548  g, & !< grain index in grain loop
22549  p, &
22550  c, &
22551  s, &
22552  sizeDotState
22553  logical :: &
22554  nonlocalBroken
22555 
22556  nonlocalbroken = .false.
22557  !$OMP PARALLEL DO PRIVATE (sizeDotState,p,c)
22558  do e = fesolving_execelem(1),fesolving_execelem(2)
22559  do i = fesolving_execip(1),fesolving_execip(2)
22560  do g = 1,homogenization_ngrains(material_homogenizationat(e))
22561  if(crystallite_todo(g,i,e) .and. (.not. nonlocalbroken .or. crystallite_localplasticity(g,i,e)) ) then
22562 
22563  p = material_phaseat(g,e); c = material_phasememberat(g,i,e)
22564 
22565  call constitutive_collectdotstate(crystallite_s(1:3,1:3,g,i,e), &
22566  crystallite_partionedf0, &
22567  crystallite_fi(1:3,1:3,g,i,e), &
22568  crystallite_partionedfp0, &
22569  crystallite_subdt(g,i,e), g,i,e)
22570  crystallite_todo(g,i,e) = all(.not. ieee_is_nan(plasticstate(p)%dotState(:,c)))
22571  do s = 1, phase_nsources(p)
22572  crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. all(.not. ieee_is_nan(sourcestate(p)%p(s)%dotState(:,c)))
22573  enddo
22574  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22575  nonlocalbroken = .true.
22576  if(.not. crystallite_todo(g,i,e)) cycle
22577 
22578  sizedotstate = plasticstate(p)%sizeDotState
22579  plasticstate(p)%state(1:sizedotstate,c) = plasticstate(p)%subState0(1:sizedotstate,c) &
22580  + plasticstate(p)%dotState (1:sizedotstate,c) &
22581  * crystallite_subdt(g,i,e)
22582  do s = 1, phase_nsources(p)
22583  sizedotstate = sourcestate(p)%p(s)%sizeDotState
22584  sourcestate(p)%p(s)%state(1:sizedotstate,c) = sourcestate(p)%p(s)%subState0(1:sizedotstate,c) &
22585  + sourcestate(p)%p(s)%dotState (1:sizedotstate,c) &
22586  * crystallite_subdt(g,i,e)
22587  enddo
22588 
22589  crystallite_todo(g,i,e) = statejump(g,i,e)
22590  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22591  nonlocalbroken = .true.
22592  if(.not. crystallite_todo(g,i,e)) cycle
22593 
22594  call constitutive_dependentstate(crystallite_partionedf(1:3,1:3,g,i,e), &
22595  crystallite_fp(1:3,1:3,g,i,e), &
22596  g, i, e)
22597 
22598  crystallite_todo(g,i,e) = integratestress(g,i,e)
22599  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22600  nonlocalbroken = .true.
22601 
22602  crystallite_converged(g,i,e) = crystallite_todo(g,i,e)
22603 
22604  endif
22605  enddo; enddo; enddo
22606  !$OMP END PARALLEL DO
22607 
22608  if(nonlocalbroken) where(.not. crystallite_localplasticity) crystallite_todo = .false.
22609  if (any(plasticstate(:)%nonlocal)) call nonlocalconvergencecheck
22610 
22611 end subroutine integratestateeuler
22612 
22613 
22614 !--------------------------------------------------------------------------------------------------
22616 !--------------------------------------------------------------------------------------------------
22617 subroutine integratestateadaptiveeuler
22619  integer :: &
22620  e, & ! element index in element loop
22621  i, & ! integration point index in ip loop
22622  g, & ! grain index in grain loop
22623  p, &
22624  c, &
22625  s, &
22626  sizeDotState
22627  logical :: &
22628  nonlocalBroken
22629 
22630  real(pReal), dimension(constitutive_plasticity_maxSizeDotState, & homogenization_maxNgrains,discretization_nIP,discretization_nElem) :: &
22631  residuum_plastic
22632  real(pReal), dimension(constitutive_source_maxSizeDotState,& maxval(phase_Nsources), & homogenization_maxNgrains,discretization_nIP,discretization_nElem) :: &
22633  residuum_source
22634 
22635 
22636  nonlocalbroken = .false.
22637  !$OMP PARALLEL DO PRIVATE(sizeDotState,p,c)
22638  do e = fesolving_execelem(1),fesolving_execelem(2)
22639  do i = fesolving_execip(1),fesolving_execip(2)
22640  do g = 1,homogenization_ngrains(material_homogenizationat(e))
22641  if(crystallite_todo(g,i,e) .and. (.not. nonlocalbroken .or. crystallite_localplasticity(g,i,e)) ) then
22642 
22643  p = material_phaseat(g,e); c = material_phasememberat(g,i,e)
22644 
22645  call constitutive_collectdotstate(crystallite_s(1:3,1:3,g,i,e), &
22646  crystallite_partionedf0, &
22647  crystallite_fi(1:3,1:3,g,i,e), &
22648  crystallite_partionedfp0, &
22649  crystallite_subdt(g,i,e), g,i,e)
22650  crystallite_todo(g,i,e) = all(.not. ieee_is_nan(plasticstate(p)%dotState(:,c)))
22651  do s = 1, phase_nsources(p)
22652  crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. all(.not. ieee_is_nan(sourcestate(p)%p(s)%dotState(:,c)))
22653  enddo
22654  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22655  nonlocalbroken = .true.
22656  if(.not. crystallite_todo(g,i,e)) cycle
22657 
22658  sizedotstate = plasticstate(p)%sizeDotState
22659 
22660  residuum_plastic(1:sizedotstate,g,i,e) = plasticstate(p)%dotstate(1:sizedotstate,c) &
22661  * (- 0.5_preal * crystallite_subdt(g,i,e))
22662  plasticstate(p)%state(1:sizedotstate,c) = plasticstate(p)%subState0(1:sizedotstate,c) &
22663  + plasticstate(p)%dotstate(1:sizedotstate,c) * crystallite_subdt(g,i,e)
22664  do s = 1, phase_nsources(p)
22665  sizedotstate = sourcestate(p)%p(s)%sizeDotState
22666 
22667  residuum_source(1:sizedotstate,s,g,i,e) = sourcestate(p)%p(s)%dotstate(1:sizedotstate,c) &
22668  * (- 0.5_preal * crystallite_subdt(g,i,e))
22669  sourcestate(p)%p(s)%state(1:sizedotstate,c) = sourcestate(p)%p(s)%subState0(1:sizedotstate,c) &
22670  + sourcestate(p)%p(s)%dotstate(1:sizedotstate,c) * crystallite_subdt(g,i,e)
22671  enddo
22672 
22673  crystallite_todo(g,i,e) = statejump(g,i,e)
22674  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22675  nonlocalbroken = .true.
22676  if(.not. crystallite_todo(g,i,e)) cycle
22677 
22678  call constitutive_dependentstate(crystallite_partionedf(1:3,1:3,g,i,e), &
22679  crystallite_fp(1:3,1:3,g,i,e), &
22680  g, i, e)
22681 
22682  crystallite_todo(g,i,e) = integratestress(g,i,e)
22683  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22684  nonlocalbroken = .true.
22685  if(.not. crystallite_todo(g,i,e)) cycle
22686 
22687  call constitutive_collectdotstate(crystallite_s(1:3,1:3,g,i,e), &
22688  crystallite_partionedf0, &
22689  crystallite_fi(1:3,1:3,g,i,e), &
22690  crystallite_partionedfp0, &
22691  crystallite_subdt(g,i,e), g,i,e)
22692  crystallite_todo(g,i,e) = all(.not. ieee_is_nan(plasticstate(p)%dotState(:,c)))
22693  do s = 1, phase_nsources(p)
22694  crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. all(.not. ieee_is_nan(sourcestate(p)%p(s)%dotState(:,c)))
22695  enddo
22696  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22697  nonlocalbroken = .true.
22698  if(.not. crystallite_todo(g,i,e)) cycle
22699 
22700 
22701  sizedotstate = plasticstate(p)%sizeDotState
22702 
22703  residuum_plastic(1:sizedotstate,g,i,e) = residuum_plastic(1:sizedotstate,g,i,e) &
22704  + 0.5_preal * plasticstate(p)%dotState(:,c) * crystallite_subdt(g,i,e)
22705 
22706  crystallite_converged(g,i,e) = converged(residuum_plastic(1:sizedotstate,g,i,e), &
22707  plasticstate(p)%state(1:sizedotstate,c), &
22708  plasticstate(p)%atol(1:sizedotstate))
22709 
22710  do s = 1, phase_nsources(p)
22711  sizedotstate = sourcestate(p)%p(s)%sizeDotState
22712 
22713  residuum_source(1:sizedotstate,s,g,i,e) = &
22714  residuum_source(1:sizedotstate,s,g,i,e) + 0.5_preal * sourcestate(p)%p(s)%dotState(:,c) * crystallite_subdt(g,i,e)
22715 
22716  crystallite_converged(g,i,e) = &
22717  crystallite_converged(g,i,e) .and. converged(residuum_source(1:sizedotstate,s,g,i,e), &
22718  sourcestate(p)%p(s)%state(1:sizedotstate,c), &
22719  sourcestate(p)%p(s)%atol(1:sizedotstate))
22720  enddo
22721 
22722  endif
22723  enddo; enddo; enddo
22724  !$OMP END PARALLEL DO
22725 
22726  if (any(plasticstate(:)%nonlocal)) call nonlocalconvergencecheck
22727 
22728 end subroutine integratestateadaptiveeuler
22729 
22730 
22731 !--------------------------------------------------------------------------------------------------
22733 !--------------------------------------------------------------------------------------------------
22734 subroutine integratestaterk4
22735 
22736  real(pReal), dimension(3,3), parameter :: &
22737  A = reshape([&
22738  0.5_preal, 0.0_preal, 0.0_preal, &
22739  0.0_preal, 0.5_preal, 0.0_preal, &
22740  0.0_preal, 0.0_preal, 1.0_preal], &
22741  [3,3])
22742  real(pReal), dimension(3), parameter :: &
22743  CC = [0.5_preal, 0.5_preal, 1.0_preal] ! factor giving the fraction of the original timestep used for Runge Kutta Integration
22744  real(pReal), dimension(4), parameter :: &
22745  B = [1.0_preal/6.0_preal, 1.0_preal/3.0_preal, 1.0_preal/3.0_preal, 1.0_preal/6.0_preal] ! weight of slope used for Runge Kutta integration (final weight divided by 6)
22746 
22747  integer :: &
22748  e, & ! element index in element loop
22749  i, & ! integration point index in ip loop
22750  g, & ! grain index in grain loop
22751  stage, & ! stage index in integration stage loop
22752  n, &
22753  p, &
22754  c, &
22755  s, &
22756  sizeDotState
22757  logical :: &
22758  nonlocalBroken
22759 
22760  nonlocalbroken = .false.
22761  !$OMP PARALLEL DO PRIVATE(sizeDotState,p,c)
22762  do e = fesolving_execelem(1),fesolving_execelem(2)
22763  do i = fesolving_execip(1),fesolving_execip(2)
22764  do g = 1,homogenization_ngrains(material_homogenizationat(e))
22765  if(crystallite_todo(g,i,e) .and. (.not. nonlocalbroken .or. crystallite_localplasticity(g,i,e)) ) then
22766 
22767  p = material_phaseat(g,e); c = material_phasememberat(g,i,e)
22768 
22769  call constitutive_collectdotstate(crystallite_s(1:3,1:3,g,i,e), &
22770  crystallite_partionedf0, &
22771  crystallite_fi(1:3,1:3,g,i,e), &
22772  crystallite_partionedfp0, &
22773  crystallite_subdt(g,i,e), g,i,e)
22774  crystallite_todo(g,i,e) = all(.not. ieee_is_nan(plasticstate(p)%dotState(:,c)))
22775  do s = 1, phase_nsources(p)
22776  crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. all(.not. ieee_is_nan(sourcestate(p)%p(s)%dotState(:,c)))
22777  enddo
22778  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22779  nonlocalbroken = .true.
22780  if(.not. crystallite_todo(g,i,e)) cycle
22781 
22782  do stage = 1,3
22783 
22784  plasticstate(p)%RK4dotState(stage,:,c) = plasticstate(p)%dotState(:,c)
22785  plasticstate(p)%dotState(:,c) = a(1,stage) * plasticstate(p)%RK4dotState(1,:,c)
22786  do s = 1, phase_nsources(p)
22787  sourcestate(p)%p(s)%RK4dotState(stage,:,c) = sourcestate(p)%p(s)%dotState(:,c)
22788  sourcestate(p)%p(s)%dotState(:,c) = a(1,stage) * sourcestate(p)%p(s)%RK4dotState(1,:,c)
22789  enddo
22790 
22791  do n = 2, stage
22792  plasticstate(p)%dotState(:,c) = plasticstate(p)%dotState(:,c) &
22793  + a(n,stage) * plasticstate(p)%RK4dotState(n,:,c)
22794  do s = 1, phase_nsources(p)
22795  sourcestate(p)%p(s)%dotState(:,c) = sourcestate(p)%p(s)%dotState(:,c) &
22796  + a(n,stage) * sourcestate(p)%p(s)%RK4dotState(n,:,c)
22797  enddo
22798  enddo
22799 
22800  sizedotstate = plasticstate(p)%sizeDotState
22801  plasticstate(p)%state(1:sizedotstate,c) = plasticstate(p)%subState0(1:sizedotstate,c) &
22802  + plasticstate(p)%dotState (1:sizedotstate,c) &
22803  * crystallite_subdt(g,i,e)
22804  do s = 1, phase_nsources(p)
22805  sizedotstate = sourcestate(p)%p(s)%sizeDotState
22806  sourcestate(p)%p(s)%state(1:sizedotstate,c) = sourcestate(p)%p(s)%subState0(1:sizedotstate,c) &
22807  + sourcestate(p)%p(s)%dotState (1:sizedotstate,c) &
22808  * crystallite_subdt(g,i,e)
22809  enddo
22810 
22811  call constitutive_dependentstate(crystallite_partionedf(1:3,1:3,g,i,e), &
22812  crystallite_fp(1:3,1:3,g,i,e), &
22813  g, i, e)
22814 
22815  crystallite_todo(g,i,e) = integratestress(g,i,e,cc(stage))
22816  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22817  nonlocalbroken = .true.
22818  if(.not. crystallite_todo(g,i,e)) exit
22819 
22820  call constitutive_collectdotstate(crystallite_s(1:3,1:3,g,i,e), &
22821  crystallite_partionedf0, &
22822  crystallite_fi(1:3,1:3,g,i,e), &
22823  crystallite_partionedfp0, &
22824  crystallite_subdt(g,i,e)*cc(stage), g,i,e)
22825  crystallite_todo(g,i,e) = all(.not. ieee_is_nan(plasticstate(p)%dotState(:,c)))
22826  do s = 1, phase_nsources(p)
22827  crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. all(.not. ieee_is_nan(sourcestate(p)%p(s)%dotState(:,c)))
22828  enddo
22829  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22830  nonlocalbroken = .true.
22831  if(.not. crystallite_todo(g,i,e)) exit
22832 
22833  enddo
22834 
22835  if(.not. crystallite_todo(g,i,e)) cycle
22836 
22837  sizedotstate = plasticstate(p)%sizeDotState
22838 
22839  plasticstate(p)%RK4dotState(4,:,c) = plasticstate(p)%dotState(:,c)
22840 
22841  plasticstate(p)%dotState(:,c) = matmul(b,plasticstate(p)%RK4dotState(1:4,1:sizedotstate,c))
22842  plasticstate(p)%state(1:sizedotstate,c) = plasticstate(p)%subState0(1:sizedotstate,c) &
22843  + plasticstate(p)%dotState (1:sizedotstate,c) &
22844  * crystallite_subdt(g,i,e)
22845 
22846  do s = 1, phase_nsources(p)
22847  sizedotstate = sourcestate(p)%p(s)%sizeDotState
22848 
22849  sourcestate(p)%p(s)%RK4dotState(4,:,c) = sourcestate(p)%p(s)%dotState(:,c)
22850 
22851  sourcestate(p)%p(s)%dotState(:,c) = matmul(b,sourcestate(p)%p(s)%RK4dotState(1:4,1:sizedotstate,c))
22852  sourcestate(p)%p(s)%state(1:sizedotstate,c) = sourcestate(p)%p(s)%subState0(1:sizedotstate,c) &
22853  + sourcestate(p)%p(s)%dotState (1:sizedotstate,c) &
22854  * crystallite_subdt(g,i,e)
22855  enddo
22856 
22857  crystallite_todo(g,i,e) = statejump(g,i,e)
22858  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22859  nonlocalbroken = .true.
22860  if(.not. crystallite_todo(g,i,e)) cycle
22861 
22862  call constitutive_dependentstate(crystallite_partionedf(1:3,1:3,g,i,e), &
22863  crystallite_fp(1:3,1:3,g,i,e), &
22864  g, i, e)
22865 
22866  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22867  nonlocalbroken = .true.
22868  if(.not. crystallite_todo(g,i,e)) cycle
22869 
22870  crystallite_todo(g,i,e) = integratestress(g,i,e)
22871  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22872  nonlocalbroken = .true.
22873  crystallite_converged(g,i,e) = crystallite_todo(g,i,e) ! consider converged if not broken
22874 
22875  endif
22876  enddo; enddo; enddo
22877  !$OMP END PARALLEL DO
22878 
22879  if(nonlocalbroken) where(.not. crystallite_localplasticity) crystallite_todo = .false.
22880  if (any(plasticstate(:)%nonlocal)) call nonlocalconvergencecheck
22881 
22882 end subroutine integratestaterk4
22883 
22884 
22885 !--------------------------------------------------------------------------------------------------
22888 !--------------------------------------------------------------------------------------------------
22889 subroutine integratestaterkck45
22890 
22891  real(pReal), dimension(5,5), parameter :: &
22892  A = reshape([&
22893  .2_preal, .075_preal, .3_preal, -11.0_preal/54.0_preal, 1631.0_preal/55296.0_preal, &
22894  .0_preal, .225_preal, -.9_preal, 2.5_preal, 175.0_preal/512.0_preal, &
22895  .0_preal, .0_preal, 1.2_preal, -70.0_preal/27.0_preal, 575.0_preal/13824.0_preal, &
22896  .0_preal, .0_preal, .0_preal, 35.0_preal/27.0_preal, 44275.0_preal/110592.0_preal, &
22897  .0_preal, .0_preal, .0_preal, .0_preal, 253.0_preal/4096.0_preal], &
22898  [5,5], order=[2,1])
22899 
22900  real(pReal), dimension(6), parameter :: &
22901  B = &
22902  [37.0_preal/378.0_preal, .0_preal, 250.0_preal/621.0_preal, &
22903  125.0_preal/594.0_preal, .0_preal, 512.0_preal/1771.0_preal], &
22904  db = b - &
22905  [2825.0_preal/27648.0_preal, .0_preal, 18575.0_preal/48384.0_preal,&
22906  13525.0_preal/55296.0_preal, 277.0_preal/14336.0_preal, 0.25_preal]
22907 
22908  real(pReal), dimension(5), parameter :: &
22909  CC = [0.2_preal, 0.3_preal, 0.6_preal, 1.0_preal, 0.875_preal]
22910 
22911  integer :: &
22912  e, & ! element index in element loop
22913  i, & ! integration point index in ip loop
22914  g, & ! grain index in grain loop
22915  stage, & ! stage index in integration stage loop
22916  n, &
22917  p, &
22918  c, &
22919  s, &
22920  sizeDotState
22921  logical :: &
22922  nonlocalBroken
22923 
22924  real(pReal), dimension(constitutive_plasticity_maxSizeDotState, & homogenization_maxNgrains,discretization_nIP,discretization_nElem) :: &
22925  residuum_plastic
22926  real(pReal), dimension(constitutive_source_maxSizeDotState, & maxval(phase_Nsources), & homogenization_maxNgrains,discretization_nIP,discretization_nElem) :: &
22927  residuum_source
22928 
22929 
22930  nonlocalbroken = .false.
22931  !$OMP PARALLEL DO PRIVATE(sizeDotState,p,c)
22932  do e = fesolving_execelem(1),fesolving_execelem(2)
22933  do i = fesolving_execip(1),fesolving_execip(2)
22934  do g = 1,homogenization_ngrains(material_homogenizationat(e))
22935  if(crystallite_todo(g,i,e) .and. (.not. nonlocalbroken .or. crystallite_localplasticity(g,i,e)) ) then
22936 
22937  p = material_phaseat(g,e); c = material_phasememberat(g,i,e)
22938 
22939  call constitutive_collectdotstate(crystallite_s(1:3,1:3,g,i,e), &
22940  crystallite_partionedf0, &
22941  crystallite_fi(1:3,1:3,g,i,e), &
22942  crystallite_partionedfp0, &
22943  crystallite_subdt(g,i,e), g,i,e)
22944  crystallite_todo(g,i,e) = all(.not. ieee_is_nan(plasticstate(p)%dotState(:,c)))
22945  do s = 1, phase_nsources(p)
22946  crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. all(.not. ieee_is_nan(sourcestate(p)%p(s)%dotState(:,c)))
22947  enddo
22948  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22949  nonlocalbroken = .true.
22950  if(.not. crystallite_todo(g,i,e)) cycle
22951 
22952  do stage = 1,5
22953 
22954  plasticstate(p)%RKCK45dotState(stage,:,c) = plasticstate(p)%dotState(:,c)
22955  plasticstate(p)%dotState(:,c) = a(1,stage) * plasticstate(p)%RKCK45dotState(1,:,c)
22956  do s = 1, phase_nsources(p)
22957  sourcestate(p)%p(s)%RKCK45dotState(stage,:,c) = sourcestate(p)%p(s)%dotState(:,c)
22958  sourcestate(p)%p(s)%dotState(:,c) = a(1,stage) * sourcestate(p)%p(s)%RKCK45dotState(1,:,c)
22959  enddo
22960 
22961  do n = 2, stage
22962  plasticstate(p)%dotState(:,c) = plasticstate(p)%dotState(:,c) &
22963  + a(n,stage) * plasticstate(p)%RKCK45dotState(n,:,c)
22964  do s = 1, phase_nsources(p)
22965  sourcestate(p)%p(s)%dotState(:,c) = sourcestate(p)%p(s)%dotState(:,c) &
22966  + a(n,stage) * sourcestate(p)%p(s)%RKCK45dotState(n,:,c)
22967  enddo
22968  enddo
22969 
22970  sizedotstate = plasticstate(p)%sizeDotState
22971  plasticstate(p)%state(1:sizedotstate,c) = plasticstate(p)%subState0(1:sizedotstate,c) &
22972  + plasticstate(p)%dotState (1:sizedotstate,c) &
22973  * crystallite_subdt(g,i,e)
22974  do s = 1, phase_nsources(p)
22975  sizedotstate = sourcestate(p)%p(s)%sizeDotState
22976  sourcestate(p)%p(s)%state(1:sizedotstate,c) = sourcestate(p)%p(s)%subState0(1:sizedotstate,c) &
22977  + sourcestate(p)%p(s)%dotState (1:sizedotstate,c) &
22978  * crystallite_subdt(g,i,e)
22979  enddo
22980 
22981  call constitutive_dependentstate(crystallite_partionedf(1:3,1:3,g,i,e), &
22982  crystallite_fp(1:3,1:3,g,i,e), &
22983  g, i, e)
22984 
22985  crystallite_todo(g,i,e) = integratestress(g,i,e,cc(stage))
22986  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
22987  nonlocalbroken = .true.
22988  if(.not. crystallite_todo(g,i,e)) exit
22989 
22990  call constitutive_collectdotstate(crystallite_s(1:3,1:3,g,i,e), &
22991  crystallite_partionedf0, &
22992  crystallite_fi(1:3,1:3,g,i,e), &
22993  crystallite_partionedfp0, &
22994  crystallite_subdt(g,i,e)*cc(stage), g,i,e)
22995  crystallite_todo(g,i,e) = all(.not. ieee_is_nan(plasticstate(p)%dotState(:,c)))
22996  do s = 1, phase_nsources(p)
22997  crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. all(.not. ieee_is_nan(sourcestate(p)%p(s)%dotState(:,c)))
22998  enddo
22999  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
23000  nonlocalbroken = .true.
23001  if(.not. crystallite_todo(g,i,e)) exit
23002 
23003  enddo
23004 
23005  if(.not. crystallite_todo(g,i,e)) cycle
23006 
23007  sizedotstate = plasticstate(p)%sizeDotState
23008 
23009  plasticstate(p)%RKCK45dotState(6,:,c) = plasticstate(p)%dotState(:,c)
23010  residuum_plastic(1:sizedotstate,g,i,e) = matmul(db,plasticstate(p)%RKCK45dotState(1:6,1:sizedotstate,c)) &
23011  * crystallite_subdt(g,i,e)
23012  plasticstate(p)%dotState(:,c) = matmul(b,plasticstate(p)%RKCK45dotState(1:6,1:sizedotstate,c))
23013  plasticstate(p)%state(1:sizedotstate,c) = plasticstate(p)%subState0(1:sizedotstate,c) &
23014  + plasticstate(p)%dotState (1:sizedotstate,c) &
23015  * crystallite_subdt(g,i,e)
23016  crystallite_todo(g,i,e) = converged(residuum_plastic(1:sizedotstate,g,i,e), &
23017  plasticstate(p)%state(1:sizedotstate,c), &
23018  plasticstate(p)%atol(1:sizedotstate))
23019 
23020  do s = 1, phase_nsources(p)
23021  sizedotstate = sourcestate(p)%p(s)%sizeDotState
23022 
23023  sourcestate(p)%p(s)%RKCK45dotState(6,:,c) = sourcestate(p)%p(s)%dotState(:,c)
23024  residuum_source(1:sizedotstate,s,g,i,e) = matmul(db,sourcestate(p)%p(s)%RKCK45dotState(1:6,1:sizedotstate,c)) &
23025  * crystallite_subdt(g,i,e)
23026  sourcestate(p)%p(s)%dotState(:,c) = matmul(b,sourcestate(p)%p(s)%RKCK45dotState(1:6,1:sizedotstate,c))
23027  sourcestate(p)%p(s)%state(1:sizedotstate,c) = sourcestate(p)%p(s)%subState0(1:sizedotstate,c) &
23028  + sourcestate(p)%p(s)%dotState (1:sizedotstate,c) &
23029  * crystallite_subdt(g,i,e)
23030  crystallite_todo(g,i,e) = crystallite_todo(g,i,e) .and. &
23031  converged(residuum_source(1:sizedotstate,s,g,i,e), &
23032  sourcestate(p)%p(s)%state(1:sizedotstate,c), &
23033  sourcestate(p)%p(s)%atol(1:sizedotstate))
23034  enddo
23035  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
23036  nonlocalbroken = .true.
23037  if(.not. crystallite_todo(g,i,e)) cycle
23038 
23039  crystallite_todo(g,i,e) = statejump(g,i,e)
23040  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
23041  nonlocalbroken = .true.
23042  if(.not. crystallite_todo(g,i,e)) cycle
23043 
23044  call constitutive_dependentstate(crystallite_partionedf(1:3,1:3,g,i,e), &
23045  crystallite_fp(1:3,1:3,g,i,e), &
23046  g, i, e)
23047 
23048  crystallite_todo(g,i,e) = integratestress(g,i,e)
23049  if(.not. (crystallite_todo(g,i,e) .or. crystallite_localplasticity(g,i,e))) &
23050  nonlocalbroken = .true.
23051  crystallite_converged(g,i,e) = crystallite_todo(g,i,e) ! consider converged if not broken
23052 
23053  endif
23054  enddo; enddo; enddo
23055  !$OMP END PARALLEL DO
23056 
23057  if(nonlocalbroken) where(.not. crystallite_localplasticity) crystallite_todo = .false.
23058  if (any(plasticstate(:)%nonlocal)) call nonlocalconvergencecheck
23059 
23060 end subroutine integratestaterkck45
23061 
23062 
23063 !--------------------------------------------------------------------------------------------------
23066 !--------------------------------------------------------------------------------------------------
23067 subroutine nonlocalconvergencecheck
23068 
23069  if (any(.not. crystallite_converged .and. .not. crystallite_localplasticity)) & ! any non-local not yet converged (or broken)...
23070  where( .not. crystallite_localplasticity) crystallite_converged = .false.
23071 
23072 end subroutine nonlocalconvergencecheck
23073 
23075 !--------------------------------------------------------------------------------------------------
23077 !--------------------------------------------------------------------------------------------------
23078 logical pure function converged(residuum,state,atol)
23079 
23080  real(pReal), intent(in), dimension(:) ::&
23081  residuum, state, atol
23082  real(pReal) :: &
23083  rTol
23084 
23085  rtol = num%rTol_crystalliteState
23086 
23087  converged = all(abs(residuum) <= max(atol, rtol*abs(state)))
23088 
23089 end function converged
23090 
23091 
23092 !--------------------------------------------------------------------------------------------------
23095 !--------------------------------------------------------------------------------------------------
23096 logical function statejump(ipc,ip,el)
23097 
23098  integer, intent(in):: &
23099  el, & ! element index
23100  ip, & ! integration point index
23101  ipc ! grain index
23102 
23103  integer :: &
23104  c, &
23105  p, &
23106  mysource, &
23107  myoffset, &
23108  mysize
23109 
23110  c = material_phasememberat(ipc,ip,el)
23111  p = material_phaseat(ipc,el)
23112 
23113  call constitutive_collectdeltastate(crystallite_s(1:3,1:3,ipc,ip,el), &
23114  crystallite_fe(1:3,1:3,ipc,ip,el), &
23115  crystallite_fi(1:3,1:3,ipc,ip,el), &
23116  ipc,ip,el)
23117 
23118  myoffset = plasticstate(p)%offsetDeltaState
23119  mysize = plasticstate(p)%sizeDeltaState
23120 
23121  if( any(ieee_is_nan(plasticstate(p)%deltaState(1:mysize,c)))) then
23122  statejump = .false.
23123  return
23124  endif
23125 
23126  plasticstate(p)%state(myoffset + 1:myoffset + mysize,c) = &
23127  plasticstate(p)%state(myoffset + 1:myoffset + mysize,c) + plasticstate(p)%deltaState(1:mysize,c)
23128 
23129  do mysource = 1, phase_nsources(p)
23130  myoffset = sourcestate(p)%p(mysource)%offsetDeltaState
23131  mysize = sourcestate(p)%p(mysource)%sizeDeltaState
23132  if (any(ieee_is_nan(sourcestate(p)%p(mysource)%deltaState(1:mysize,c)))) then
23133  statejump = .false.
23134  return
23135  endif
23136  sourcestate(p)%p(mysource)%state(myoffset + 1: myoffset + mysize,c) = &
23137  sourcestate(p)%p(mysource)%state(myoffset + 1: myoffset + mysize,c) + sourcestate(p)%p(mysource)%deltaState(1:mysize,c)
23138  enddo
23139 
23140  statejump = .true.
23141 
23142 end function statejump
23143 
23144 
23145 !--------------------------------------------------------------------------------------------------
23147 ! ToDo: Merge data into one file for MPI, move state to constitutive and homogenization, respectively
23148 !--------------------------------------------------------------------------------------------------
23149 subroutine crystallite_restartwrite
23150 
23151  integer :: i
23152  integer(HID_T) :: filehandle, grouphandle
23153  character(len=pStringLen) :: filename, datasetname
23154 
23155  write(6,'(a)') ' writing field and constitutive data required for restart to file';flush(6)
23157  write(filename,'(a,i0,a)') trim(getsolverjobname())//'_',worldrank,'.hdf5'
23158  filehandle = hdf5_openfile(filename,'a')
23159 
23160  call hdf5_write(filehandle,crystallite_partionedf,'F')
23161  call hdf5_write(filehandle,crystallite_fp, 'Fp')
23162  call hdf5_write(filehandle,crystallite_fi, 'Fi')
23163  call hdf5_write(filehandle,crystallite_lp, 'Lp')
23164  call hdf5_write(filehandle,crystallite_li, 'Li')
23165  call hdf5_write(filehandle,crystallite_s, 'S')
23166 
23167  grouphandle = hdf5_addgroup(filehandle,'constituent')
23168  do i = 1,size(phase_plasticity)
23169  write(datasetname,'(i0,a)') i,'_omega_plastic'
23170  call hdf5_write(grouphandle,plasticstate(i)%state,datasetname)
23171  enddo
23172  call hdf5_closegroup(grouphandle)
23173 
23174  grouphandle = hdf5_addgroup(filehandle,'materialpoint')
23175  do i = 1, material_nhomogenization
23176  write(datasetname,'(i0,a)') i,'_omega_homogenization'
23177  call hdf5_write(grouphandle,homogstate(i)%state,datasetname)
23178  enddo
23179  call hdf5_closegroup(grouphandle)
23180 
23181  call hdf5_closefile(filehandle)
23182 
23183 end subroutine crystallite_restartwrite
23184 
23185 
23186 !--------------------------------------------------------------------------------------------------
23188 ! ToDo: Merge data into one file for MPI, move state to constitutive and homogenization, respectively
23189 !--------------------------------------------------------------------------------------------------
23190 subroutine crystallite_restartread
23191 
23192  integer :: i
23193  integer(HID_T) :: fileHandle, groupHandle
23194  character(len=pStringLen) :: fileName, datasetName
23195 
23196  write(6,'(/,a,i0,a)') ' reading restart information of increment from file'
23198  write(filename,'(a,i0,a)') trim(getsolverjobname())//'_',worldrank,'.hdf5'
23199  filehandle = hdf5_openfile(filename)
23200 
23201  call hdf5_read(filehandle,crystallite_f0, 'F')
23202  call hdf5_read(filehandle,crystallite_fp0,'Fp')
23203  call hdf5_read(filehandle,crystallite_fi0,'Fi')
23204  call hdf5_read(filehandle,crystallite_lp0,'Lp')
23205  call hdf5_read(filehandle,crystallite_li0,'Li')
23206  call hdf5_read(filehandle,crystallite_s0, 'S')
23207 
23208  grouphandle = hdf5_opengroup(filehandle,'constituent')
23209  do i = 1,size(phase_plasticity)
23210  write(datasetname,'(i0,a)') i,'_omega_plastic'
23211  call hdf5_read(grouphandle,plasticstate(i)%state0,datasetname)
23212  enddo
23213  call hdf5_closegroup(grouphandle)
23214 
23215  grouphandle = hdf5_opengroup(filehandle,'materialpoint')
23216  do i = 1, material_nhomogenization
23217  write(datasetname,'(i0,a)') i,'_omega_homogenization'
23218  call hdf5_read(grouphandle,homogstate(i)%state0,datasetname)
23219  enddo
23220  call hdf5_closegroup(grouphandle)
23221 
23222  call hdf5_closefile(filehandle)
23223 
23224 end subroutine crystallite_restartread
23225 
23226 
23227 !--------------------------------------------------------------------------------------------------
23229 ! ToDo: Any guessing for the current states possible?
23230 !--------------------------------------------------------------------------------------------------
23231 subroutine crystallite_forward
23232 
23233  integer :: i, j
23234 
23235  crystallite_f0 = crystallite_partionedf
23236  crystallite_fp0 = crystallite_fp
23237  crystallite_lp0 = crystallite_lp
23238  crystallite_fi0 = crystallite_fi
23239  crystallite_li0 = crystallite_li
23240  crystallite_s0 = crystallite_s
23241 
23242  do i = 1, size(plasticstate)
23243  plasticstate(i)%state0 = plasticstate(i)%state
23244  enddo
23245  do i = 1, size(sourcestate)
23246  do j = 1,phase_nsources(i)
23247  sourcestate(i)%p(j)%state0 = sourcestate(i)%p(j)%state
23248  enddo; enddo
23249  do i = 1, material_nhomogenization
23250  homogstate(i)%state0 = homogstate(i)%state
23251  thermalstate(i)%state0 = thermalstate(i)%state
23252  damagestate(i)%state0 = damagestate(i)%state
23253  enddo
23254 
23255 end subroutine crystallite_forward
23256 
23257 end module crystallite
23258 # 45 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
23259 
23260 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/thermal_isothermal.f90" 1
23261 !--------------------------------------------------------------------------------------------------
23264 !--------------------------------------------------------------------------------------------------
23265 module thermal_isothermal
23266  use config
23267  use material
23268 
23269  implicit none
23270  public
23272 contains
23273 
23274 !--------------------------------------------------------------------------------------------------
23276 !--------------------------------------------------------------------------------------------------
23277 subroutine thermal_isothermal_init
23278 
23279  integer :: h,NofMyHomog
23280 
23281  write(6,'(/,a)') ' <<<+- thermal_'//thermal_isothermal_label//' init -+>>>'; flush(6)
23282 
23283  do h = 1, size(config_homogenization)
23285 
23286  nofmyhomog = count(material_homogenizationat == h)
23287  thermalstate(h)%sizeState = 0
23288  allocate(thermalstate(h)%state0 (0,nofmyhomog))
23289  allocate(thermalstate(h)%subState0(0,nofmyhomog))
23290  allocate(thermalstate(h)%state (0,nofmyhomog))
23291 
23292  deallocate(temperature(h)%p)
23293  allocate (temperature(h)%p(1), source=thermal_initialt(h))
23294  deallocate(temperaturerate(h)%p)
23295  allocate (temperaturerate(h)%p(1))
23296 
23297  enddo
23298 
23299 end subroutine thermal_isothermal_init
23300 
23301 end module thermal_isothermal
23302 # 46 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
23303 
23304 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/thermal_adiabatic.f90" 1
23305 !--------------------------------------------------------------------------------------------------
23308 !--------------------------------------------------------------------------------------------------
23309 module thermal_adiabatic
23310  use prec
23311  use config
23312  use numerics
23313  use material
23314  use results
23317  use crystallite
23318  use lattice
23319 
23320  implicit none
23321  private
23322 
23323  type :: tparameters
23324  character(len=pStringLen), allocatable, dimension(:) :: &
23325  output
23326  end type tparameters
23327 
23328  type(tparameters), dimension(:), allocatable :: &
23329  param
23331  public :: &
23338 
23339 contains
23340 
23341 
23342 !--------------------------------------------------------------------------------------------------
23345 !--------------------------------------------------------------------------------------------------
23346 subroutine thermal_adiabatic_init
23347 
23348  integer :: maxninstance,h,nofmyhomog
23349 
23350  write(6,'(/,a)') ' <<<+- thermal_'//thermal_adiabatic_label//' init -+>>>'; flush(6)
23351 
23352  maxninstance = count(thermal_type == thermal_adiabatic_id)
23353  if (maxninstance == 0) return
23354 
23355  allocate(param(maxninstance))
23356 
23357  do h = 1, size(thermal_type)
23358  if (thermal_type(h) /= thermal_adiabatic_id) cycle
23359  associate(prm => param(thermal_typeinstance(h)),config => config_homogenization(h))
23360 
23361  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
23362 
23363  nofmyhomog=count(material_homogenizationat==h)
23364  thermalstate(h)%sizeState = 1
23365  allocate(thermalstate(h)%state0 (1,nofmyhomog), source=thermal_initialt(h))
23366  allocate(thermalstate(h)%subState0(1,nofmyhomog), source=thermal_initialt(h))
23367  allocate(thermalstate(h)%state (1,nofmyhomog), source=thermal_initialt(h))
23368 
23370  deallocate(temperature(h)%p)
23371  temperature(h)%p => thermalstate(h)%state(1,:)
23372  deallocate(temperaturerate(h)%p)
23373  allocate (temperaturerate(h)%p(nofmyhomog), source=0.0_preal)
23374 
23375  end associate
23376  enddo
23377 
23378 end subroutine thermal_adiabatic_init
23379 
23380 
23381 !--------------------------------------------------------------------------------------------------
23383 !--------------------------------------------------------------------------------------------------
23384 function thermal_adiabatic_updatestate(subdt, ip, el)
23385 
23386  integer, intent(in) :: &
23387  ip, & !< integration point number
23388  el
23389  real(preal), intent(in) :: &
23390  subdt
23392  logical, dimension(2) :: &
23394  integer :: &
23395  homog, &
23396  offset
23397  real(preal) :: &
23398  t, tdot, dtdot_dt
23399 
23400  homog = material_homogenizationat(el)
23401  offset = material_homogenizationmemberat(ip,el)
23402 
23403  t = thermalstate(homog)%subState0(1,offset)
23404  call thermal_adiabatic_getsourceanditstangent(tdot, dtdot_dt, t, ip, el)
23405  t = t + subdt*tdot/(thermal_adiabatic_getspecificheat(ip,el)*thermal_adiabatic_getmassdensity(ip,el))
23406 
23407  thermal_adiabatic_updatestate = [ abs(t - thermalstate(homog)%state(1,offset)) &
23408  <= err_thermal_tolabs &
23409  .or. abs(t - thermalstate(homog)%state(1,offset)) &
23410  <= err_thermal_tolrel*abs(thermalstate(homog)%state(1,offset)), &
23411  .true.]
23412 
23413  temperature(homog)%p(thermalmapping(homog)%p(ip,el)) = t
23414  temperaturerate(homog)%p(thermalmapping(homog)%p(ip,el)) = &
23415  (thermalstate(homog)%state(1,offset) - thermalstate(homog)%subState0(1,offset))/(subdt+tiny(0.0_preal))
23416 
23417 end function thermal_adiabatic_updatestate
23418 
23419 
23420 !--------------------------------------------------------------------------------------------------
23422 !--------------------------------------------------------------------------------------------------
23423 subroutine thermal_adiabatic_getsourceanditstangent(Tdot, dTdot_dT, T, ip, el)
23424 
23425  integer, intent(in) :: &
23426  ip, & !< integration point number
23427  el
23428  real(preal), intent(in) :: &
23429  t
23430  real(preal), intent(out) :: &
23431  tdot, dtdot_dt
23432 
23433  real(preal) :: &
23434  my_tdot, my_dtdot_dt
23435  integer :: &
23436  phase, &
23437  homog, &
23438  instance, &
23439  grain, &
23440  source, &
23441  constituent
23442 
23443  homog = material_homogenizationat(el)
23444  instance = thermal_typeinstance(homog)
23445 
23446  tdot = 0.0_preal
23447  dtdot_dt = 0.0_preal
23448  do grain = 1, homogenization_ngrains(homog)
23449  phase = material_phaseat(grain,el)
23450  constituent = material_phasememberat(grain,ip,el)
23451  do source = 1, phase_nsources(phase)
23452  select case(phase_source(source,phase))
23453  case (source_thermal_dissipation_id)
23454  call source_thermal_dissipation_getrateanditstangent(my_tdot, my_dtdot_dt, &
23455  crystallite_s(1:3,1:3,grain,ip,el), &
23456  crystallite_lp(1:3,1:3,grain,ip,el), &
23457  phase)
23458 
23459  case (source_thermal_externalheat_id)
23460  call source_thermal_externalheat_getrateanditstangent(my_tdot, my_dtdot_dt, &
23461  phase, constituent)
23462 
23463  case default
23464  my_tdot = 0.0_preal
23465  my_dtdot_dt = 0.0_preal
23466  end select
23467  tdot = tdot + my_tdot
23468  dtdot_dt = dtdot_dt + my_dtdot_dt
23469  enddo
23470  enddo
23471 
23472  tdot = tdot/real(homogenization_ngrains(homog),preal)
23473  dtdot_dt = dtdot_dt/real(homogenization_ngrains(homog),preal)
23474 
23476 
23477 
23478 !--------------------------------------------------------------------------------------------------
23480 !--------------------------------------------------------------------------------------------------
23481 function thermal_adiabatic_getspecificheat(ip,el)
23482 
23483  integer, intent(in) :: &
23484  ip, & !< integration point number
23485  el
23486 
23487  real(preal) :: &
23489  integer :: &
23490  grain
23491 
23493 
23494  do grain = 1, homogenization_ngrains(material_homogenizationat(el))
23496  + lattice_specificheat(material_phaseat(grain,el))
23497  enddo
23498 
23500  / real(homogenization_ngrains(material_homogenizationat(el)),preal)
23501 
23503 
23504 
23505 !--------------------------------------------------------------------------------------------------
23507 !--------------------------------------------------------------------------------------------------
23508 function thermal_adiabatic_getmassdensity(ip,el)
23509 
23510  integer, intent(in) :: &
23511  ip, & !< integration point number
23512  el
23513  real(preal) :: &
23515  integer :: &
23516  grain
23517 
23519 
23520  do grain = 1, homogenization_ngrains(material_homogenizationat(el))
23522  + lattice_massdensity(material_phaseat(grain,el))
23523  enddo
23524 
23526  / real(homogenization_ngrains(material_homogenizationat(el)),preal)
23527 
23529 
23530 
23531 !--------------------------------------------------------------------------------------------------
23533 !--------------------------------------------------------------------------------------------------
23534 subroutine thermal_adiabatic_results(homog,group)
23535 
23536  integer, intent(in) :: homog
23537  character(len=*), intent(in) :: group
23538 
23539  integer :: o
23540 
23541  associate(prm => param(damage_typeinstance(homog)))
23542  outputsloop: do o = 1,size(prm%output)
23543  select case(trim(prm%output(o)))
23544  case('temperature') ! ToDo: should be 'T'
23545  call results_writedataset(group,temperature(homog)%p,'T',&
23546  'temperature','K')
23547  end select
23548  enddo outputsloop
23549  end associate
23550 
23551 end subroutine thermal_adiabatic_results
23552 
23553 end module thermal_adiabatic
23554 # 47 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
23555 
23556 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/thermal_conduction.f90" 1
23557 !--------------------------------------------------------------------------------------------------
23560 !--------------------------------------------------------------------------------------------------
23561 module thermal_conduction
23562  use prec
23563  use material
23564  use config
23565  use lattice
23566  use results
23567  use crystallite
23570 
23571  implicit none
23572  private
23573 
23574  type :: tparameters
23575  character(len=pStringLen), allocatable, dimension(:) :: &
23576  output
23577  end type tparameters
23578 
23579  type(tparameters), dimension(:), allocatable :: &
23580  param
23582  public :: &
23590 
23591 contains
23592 
23593 
23594 !--------------------------------------------------------------------------------------------------
23597 !--------------------------------------------------------------------------------------------------
23598 subroutine thermal_conduction_init
23599 
23600  integer :: ninstance,nofmyhomog,h
23601 
23602  write(6,'(/,a)') ' <<<+- thermal_'//thermal_conduction_label//' init -+>>>'; flush(6)
23603 
23604  ninstance = count(thermal_type == thermal_conduction_id)
23605  allocate(param(ninstance))
23606 
23607  do h = 1, size(config_homogenization)
23608  if (thermal_type(h) /= thermal_conduction_id) cycle
23609  associate(prm => param(thermal_typeinstance(h)),config => config_homogenization(h))
23610 
23611  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
23612 
23613  nofmyhomog=count(material_homogenizationat==h)
23614  thermalstate(h)%sizeState = 0
23615  allocate(thermalstate(h)%state0 (0,nofmyhomog))
23616  allocate(thermalstate(h)%subState0(0,nofmyhomog))
23617  allocate(thermalstate(h)%state (0,nofmyhomog))
23618 
23620  deallocate(temperature(h)%p)
23621  allocate (temperature(h)%p(nofmyhomog), source=thermal_initialt(h))
23622  deallocate(temperaturerate(h)%p)
23623  allocate (temperaturerate(h)%p(nofmyhomog), source=0.0_preal)
23624 
23625  end associate
23626  enddo
23627 
23628 end subroutine thermal_conduction_init
23629 
23630 
23631 !--------------------------------------------------------------------------------------------------
23633 !--------------------------------------------------------------------------------------------------
23634 subroutine thermal_conduction_getsourceanditstangent(Tdot, dTdot_dT, T, ip, el)
23635 
23636  integer, intent(in) :: &
23637  ip, & !< integration point number
23638  el
23639  real(preal), intent(in) :: &
23640  t
23641  real(preal), intent(out) :: &
23642  tdot, dtdot_dt
23643  real(preal) :: &
23644  my_tdot, my_dtdot_dt
23645  integer :: &
23646  phase, &
23647  homog, &
23648  offset, &
23649  instance, &
23650  grain, &
23651  source, &
23652  constituent
23653 
23654  homog = material_homogenizationat(el)
23655  offset = material_homogenizationmemberat(ip,el)
23656  instance = thermal_typeinstance(homog)
23657 
23658  tdot = 0.0_preal
23659  dtdot_dt = 0.0_preal
23660  do grain = 1, homogenization_ngrains(homog)
23661  phase = material_phaseat(grain,el)
23662  constituent = material_phasememberat(grain,ip,el)
23663  do source = 1, phase_nsources(phase)
23664  select case(phase_source(source,phase))
23665  case (source_thermal_dissipation_id)
23666  call source_thermal_dissipation_getrateanditstangent(my_tdot, my_dtdot_dt, &
23667  crystallite_s(1:3,1:3,grain,ip,el), &
23668  crystallite_lp(1:3,1:3,grain,ip,el), &
23669  phase)
23670 
23671  case (source_thermal_externalheat_id)
23672  call source_thermal_externalheat_getrateanditstangent(my_tdot, my_dtdot_dt, &
23673  phase, constituent)
23674  case default
23675  my_tdot = 0.0_preal
23676  my_dtdot_dt = 0.0_preal
23677 
23678  end select
23679  tdot = tdot + my_tdot
23680  dtdot_dt = dtdot_dt + my_dtdot_dt
23681  enddo
23682  enddo
23683 
23684  tdot = tdot/real(homogenization_ngrains(homog),preal)
23685  dtdot_dt = dtdot_dt/real(homogenization_ngrains(homog),preal)
23686 
23688 
23689 
23690 !--------------------------------------------------------------------------------------------------
23692 !--------------------------------------------------------------------------------------------------
23693 function thermal_conduction_getconductivity(ip,el)
23694 
23695  integer, intent(in) :: &
23696  ip, & !< integration point number
23697  el
23698  real(preal), dimension(3,3) :: &
23700  integer :: &
23701  grain
23702 
23703 
23705  do grain = 1, homogenization_ngrains(material_homogenizationat(el))
23707  crystallite_push33toref(grain,ip,el,lattice_thermalconductivity(:,:,material_phaseat(grain,el)))
23708  enddo
23709 
23711  / real(homogenization_ngrains(material_homogenizationat(el)),preal)
23712 
23714 
23715 
23716 !--------------------------------------------------------------------------------------------------
23718 !--------------------------------------------------------------------------------------------------
23719 function thermal_conduction_getspecificheat(ip,el)
23720 
23721  integer, intent(in) :: &
23722  ip, & !< integration point number
23723  el
23724  real(preal) :: &
23726  integer :: &
23727  grain
23728 
23730 
23731  do grain = 1, homogenization_ngrains(material_homogenizationat(el))
23733  + lattice_specificheat(material_phaseat(grain,el))
23734  enddo
23735 
23737  / real(homogenization_ngrains(material_homogenizationat(el)),preal)
23738 
23740 
23741 
23742 !--------------------------------------------------------------------------------------------------
23744 !--------------------------------------------------------------------------------------------------
23745 function thermal_conduction_getmassdensity(ip,el)
23746 
23747  integer, intent(in) :: &
23748  ip, & !< integration point number
23749  el
23750  real(preal) :: &
23752  integer :: &
23753  grain
23754 
23756 
23757 
23758  do grain = 1, homogenization_ngrains(material_homogenizationat(el))
23760  + lattice_massdensity(material_phaseat(grain,el))
23761  enddo
23762 
23764  / real(homogenization_ngrains(material_homogenizationat(el)),preal)
23765 
23767 
23768 
23769 !--------------------------------------------------------------------------------------------------
23771 !--------------------------------------------------------------------------------------------------
23772 subroutine thermal_conduction_puttemperatureanditsrate(T,Tdot,ip,el)
23773 
23774  integer, intent(in) :: &
23775  ip, & !< integration point number
23776  el
23777  real(preal), intent(in) :: &
23778  t, &
23779  tdot
23780  integer :: &
23781  homog, &
23782  offset
23783 
23784  homog = material_homogenizationat(el)
23785  offset = thermalmapping(homog)%p(ip,el)
23786  temperature(homog)%p(offset) = t
23787  temperaturerate(homog)%p(offset) = tdot
23788 
23790 
23791 
23792 !--------------------------------------------------------------------------------------------------
23794 !--------------------------------------------------------------------------------------------------
23795 subroutine thermal_conduction_results(homog,group)
23796 
23797  integer, intent(in) :: homog
23798  character(len=*), intent(in) :: group
23799 
23800  integer :: o
23801 
23802  associate(prm => param(damage_typeinstance(homog)))
23803  outputsloop: do o = 1,size(prm%output)
23804  select case(trim(prm%output(o)))
23805  case('temperature') ! ToDo: should be 'T'
23806  call results_writedataset(group,temperature(homog)%p,'T',&
23807  'temperature','K')
23808  end select
23809  enddo outputsloop
23810  end associate
23811 
23812 end subroutine thermal_conduction_results
23813 
23814 end module thermal_conduction
23815 # 48 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
23816 
23817 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/damage_none.f90" 1
23818 !--------------------------------------------------------------------------------------------------
23821 !--------------------------------------------------------------------------------------------------
23822 module damage_none
23823  use config
23824  use material
23825 
23826  implicit none
23827  public
23829 contains
23830 
23831 !--------------------------------------------------------------------------------------------------
23833 !--------------------------------------------------------------------------------------------------
23834 subroutine damage_none_init
23835 
23836  integer :: h,NofMyHomog
23837 
23838  write(6,'(/,a)') ' <<<+- damage_'//damage_none_label//' init -+>>>'; flush(6)
23839 
23840  do h = 1, size(config_homogenization)
23841  if (damage_type(h) /= damage_none_id) cycle
23842 
23843  nofmyhomog = count(material_homogenizationat == h)
23844  damagestate(h)%sizeState = 0
23845  allocate(damagestate(h)%state0 (0,nofmyhomog))
23846  allocate(damagestate(h)%subState0(0,nofmyhomog))
23847  allocate(damagestate(h)%state (0,nofmyhomog))
23848 
23849  deallocate(damage(h)%p)
23850  allocate (damage(h)%p(1), source=damage_initialphi(h))
23851 
23852  enddo
23853 
23854 end subroutine damage_none_init
23855 
23856 end module damage_none
23857 # 49 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
23858 
23859 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/damage_local.f90" 1
23860 !--------------------------------------------------------------------------------------------------
23863 !--------------------------------------------------------------------------------------------------
23864 module damage_local
23865  use prec
23866  use material
23867  use config
23868  use numerics
23873  use results
23874 
23875  implicit none
23876  private
23877 
23878  type :: tparameters
23879  character(len=pStringLen), allocatable, dimension(:) :: &
23880  output
23881  end type tparameters
23882 
23883  type(tparameters), dimension(:), allocatable :: &
23884  param
23886  public :: &
23890 
23891 contains
23892 
23893 !--------------------------------------------------------------------------------------------------
23896 !--------------------------------------------------------------------------------------------------
23897 subroutine damage_local_init
23898 
23899  integer :: ninstance,nofmyhomog,h
23900 
23901  write(6,'(/,a)') ' <<<+- damage_'//damage_local_label//' init -+>>>'; flush(6)
23902 
23903  ninstance = count(damage_type == damage_local_id)
23904  allocate(param(ninstance))
23905 
23906  do h = 1, size(config_homogenization)
23907  if (damage_type(h) /= damage_local_id) cycle
23908  associate(prm => param(damage_typeinstance(h)),config => config_homogenization(h))
23909 
23910  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
23911 
23912  nofmyhomog = count(material_homogenizationat == h)
23913  damagestate(h)%sizeState = 1
23914  allocate(damagestate(h)%state0 (1,nofmyhomog), source=damage_initialphi(h))
23915  allocate(damagestate(h)%subState0(1,nofmyhomog), source=damage_initialphi(h))
23916  allocate(damagestate(h)%state (1,nofmyhomog), source=damage_initialphi(h))
23917 
23918  nullify(damagemapping(h)%p)
23920  deallocate(damage(h)%p)
23921  damage(h)%p => damagestate(h)%state(1,:)
23922 
23923  end associate
23924  enddo
23925 
23926 end subroutine damage_local_init
23927 
23928 
23929 !--------------------------------------------------------------------------------------------------
23931 !--------------------------------------------------------------------------------------------------
23932 function damage_local_updatestate(subdt, ip, el)
23933 
23934  integer, intent(in) :: &
23935  ip, & !< integration point number
23936  el
23937  real(preal), intent(in) :: &
23938  subdt
23939  logical, dimension(2) :: &
23941  integer :: &
23942  homog, &
23943  offset
23944  real(preal) :: &
23945  phi, phidot, dphidot_dphi
23946 
23947  homog = material_homogenizationat(el)
23948  offset = material_homogenizationmemberat(ip,el)
23949  phi = damagestate(homog)%subState0(1,offset)
23950  call damage_local_getsourceanditstangent(phidot, dphidot_dphi, phi, ip, el)
23951  phi = max(residualstiffness,min(1.0_preal,phi + subdt*phidot))
23952 
23953  damage_local_updatestate = [ abs(phi - damagestate(homog)%state(1,offset)) &
23954  <= err_damage_tolabs &
23955  .or. abs(phi - damagestate(homog)%state(1,offset)) &
23956  <= err_damage_tolrel*abs(damagestate(homog)%state(1,offset)), &
23957  .true.]
23958 
23959  damagestate(homog)%state(1,offset) = phi
23960 
23961 end function damage_local_updatestate
23962 
23963 
23964 !--------------------------------------------------------------------------------------------------
23966 !--------------------------------------------------------------------------------------------------
23967 subroutine damage_local_getsourceanditstangent(phiDot, dPhiDot_dPhi, phi, ip, el)
23968 
23969  integer, intent(in) :: &
23970  ip, & !< integration point number
23971  el
23972  real(preal), intent(in) :: &
23973  phi
23974  integer :: &
23975  phase, &
23976  grain, &
23977  source, &
23978  constituent
23979  real(pReal) :: &
23980  phiDot, dPhiDot_dPhi, localphiDot, dLocalphiDot_dPhi
23981 
23982  phidot = 0.0_preal
23983  dphidot_dphi = 0.0_preal
23984  do grain = 1, homogenization_ngrains(material_homogenizationat(el))
23985  phase = material_phaseat(grain,el)
23986  constituent = material_phasememberat(grain,ip,el)
23987  do source = 1, phase_nsources(phase)
23988  select case(phase_source(source,phase))
23989  case (source_damage_isobrittle_id)
23990  call source_damage_isobrittle_getrateanditstangent (localphidot, dlocalphidot_dphi, phi, phase, constituent)
23991 
23992  case (source_damage_isoductile_id)
23993  call source_damage_isoductile_getrateanditstangent (localphidot, dlocalphidot_dphi, phi, phase, constituent)
23994 
23995  case (source_damage_anisobrittle_id)
23996  call source_damage_anisobrittle_getrateanditstangent(localphidot, dlocalphidot_dphi, phi, phase, constituent)
23997 
23998  case (source_damage_anisoductile_id)
23999  call source_damage_anisoductile_getrateanditstangent(localphidot, dlocalphidot_dphi, phi, phase, constituent)
24000 
24001  case default
24002  localphidot = 0.0_preal
24003  dlocalphidot_dphi = 0.0_preal
24004 
24005  end select
24006  phidot = phidot + localphidot
24007  dphidot_dphi = dphidot_dphi + dlocalphidot_dphi
24008  enddo
24009  enddo
24010 
24011  phidot = phidot/real(homogenization_ngrains(material_homogenizationat(el)),preal)
24012  dphidot_dphi = dphidot_dphi/real(homogenization_ngrains(material_homogenizationat(el)),preal)
24013 
24015 
24016 
24017 !--------------------------------------------------------------------------------------------------
24019 !--------------------------------------------------------------------------------------------------
24020 subroutine damage_local_results(homog,group)
24021 
24022  integer, intent(in) :: homog
24023  character(len=*), intent(in) :: group
24024 
24025  integer :: o
24026 
24027  associate(prm => param(damage_typeinstance(homog)))
24028  outputsloop: do o = 1,size(prm%output)
24029  select case(prm%output(o))
24030  case ('damage')
24031  call results_writedataset(group,damage(homog)%p,'phi',&
24032  'damage indicator','-')
24033  end select
24034  enddo outputsloop
24035  end associate
24036 
24037 end subroutine damage_local_results
24038 
24039 
24040 end module damage_local
24041 # 50 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
24042 
24043 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/damage_nonlocal.f90" 1
24044 !--------------------------------------------------------------------------------------------------
24047 !--------------------------------------------------------------------------------------------------
24048 module damage_nonlocal
24049  use prec
24050  use material
24051  use config
24052  use numerics
24053  use crystallite
24059  use results
24060 
24061  implicit none
24062  private
24063 
24064  type :: tparameters
24065  character(len=pStringLen), allocatable, dimension(:) :: &
24066  output
24067  end type tparameters
24068 
24069  type(tparameters), dimension(:), allocatable :: &
24070  param
24072  public :: &
24079 
24080 contains
24081 
24082 !--------------------------------------------------------------------------------------------------
24085 !--------------------------------------------------------------------------------------------------
24086 subroutine damage_nonlocal_init
24087 
24088  integer :: ninstance,nofmyhomog,h
24089 
24090  write(6,'(/,a)') ' <<<+- damage_'//damage_nonlocal_label//' init -+>>>'; flush(6)
24091 
24092  ninstance = count(damage_type == damage_nonlocal_id)
24093  allocate(param(ninstance))
24094 
24095  do h = 1, size(config_homogenization)
24096  if (damage_type(h) /= damage_nonlocal_id) cycle
24097  associate(prm => param(damage_typeinstance(h)),config => config_homogenization(h))
24098 
24099  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
24100 
24101  nofmyhomog = count(material_homogenizationat == h)
24102  damagestate(h)%sizeState = 1
24103  allocate(damagestate(h)%state0 (1,nofmyhomog), source=damage_initialphi(h))
24104  allocate(damagestate(h)%subState0(1,nofmyhomog), source=damage_initialphi(h))
24105  allocate(damagestate(h)%state (1,nofmyhomog), source=damage_initialphi(h))
24106 
24107  nullify(damagemapping(h)%p)
24109  deallocate(damage(h)%p)
24110  damage(h)%p => damagestate(h)%state(1,:)
24111 
24112  end associate
24113  enddo
24114 
24115 end subroutine damage_nonlocal_init
24116 
24117 
24118 !--------------------------------------------------------------------------------------------------
24120 !--------------------------------------------------------------------------------------------------
24121 subroutine damage_nonlocal_getsourceanditstangent(phiDot, dPhiDot_dPhi, phi, ip, el)
24122 
24123  integer, intent(in) :: &
24124  ip, & !< integration point number
24125  el
24126  real(preal), intent(in) :: &
24127  phi
24128  integer :: &
24129  phase, &
24130  grain, &
24131  source, &
24132  constituent
24133  real(preal) :: &
24134  phidot, dphidot_dphi, localphidot, dlocalphidot_dphi
24135 
24136  phidot = 0.0_preal
24137  dphidot_dphi = 0.0_preal
24138  do grain = 1, homogenization_ngrains(material_homogenizationat(el))
24139  phase = material_phaseat(grain,el)
24140  constituent = material_phasememberat(grain,ip,el)
24141  do source = 1, phase_nsources(phase)
24142  select case(phase_source(source,phase))
24143  case (source_damage_isobrittle_id)
24144  call source_damage_isobrittle_getrateanditstangent (localphidot, dlocalphidot_dphi, phi, phase, constituent)
24145 
24146  case (source_damage_isoductile_id)
24147  call source_damage_isoductile_getrateanditstangent (localphidot, dlocalphidot_dphi, phi, phase, constituent)
24148 
24149  case (source_damage_anisobrittle_id)
24150  call source_damage_anisobrittle_getrateanditstangent(localphidot, dlocalphidot_dphi, phi, phase, constituent)
24151 
24152  case (source_damage_anisoductile_id)
24153  call source_damage_anisoductile_getrateanditstangent(localphidot, dlocalphidot_dphi, phi, phase, constituent)
24154 
24155  case default
24156  localphidot = 0.0_preal
24157  dlocalphidot_dphi = 0.0_preal
24158 
24159  end select
24160  phidot = phidot + localphidot
24161  dphidot_dphi = dphidot_dphi + dlocalphidot_dphi
24162  enddo
24163  enddo
24164 
24165  phidot = phidot/real(homogenization_ngrains(material_homogenizationat(el)),preal)
24166  dphidot_dphi = dphidot_dphi/real(homogenization_ngrains(material_homogenizationat(el)),preal)
24167 
24169 
24170 
24171 !--------------------------------------------------------------------------------------------------
24173 !--------------------------------------------------------------------------------------------------
24174 function damage_nonlocal_getdiffusion(ip,el)
24175 
24176  integer, intent(in) :: &
24177  ip, & !< integration point number
24178  el
24179  real(preal), dimension(3,3) :: &
24181  integer :: &
24182  homog, &
24183  grain
24184 
24185  homog = material_homogenizationat(el)
24186  damage_nonlocal_getdiffusion = 0.0_preal
24187  do grain = 1, homogenization_ngrains(homog)
24189  crystallite_push33toref(grain,ip,el,lattice_damagediffusion(1:3,1:3,material_phaseat(grain,el)))
24190  enddo
24191 
24193  charlength**2*damage_nonlocal_getdiffusion/real(homogenization_ngrains(homog),preal)
24194 
24195 end function damage_nonlocal_getdiffusion
24196 
24197 
24198 !--------------------------------------------------------------------------------------------------
24200 !--------------------------------------------------------------------------------------------------
24201 real(pReal) function damage_nonlocal_getmobility(ip,el)
24202 
24203  integer, intent(in) :: &
24204  ip, & !< integration point number
24205  el
24206  integer :: &
24207  ipc
24209  damage_nonlocal_getmobility = 0.0_preal
24210 
24211  do ipc = 1, homogenization_ngrains(material_homogenizationat(el))
24212  damage_nonlocal_getmobility = damage_nonlocal_getmobility + lattice_damagemobility(material_phaseat(ipc,el))
24213  enddo
24214 
24216  real(homogenization_ngrains(material_homogenizationat(el)),preal)
24217 
24218 end function damage_nonlocal_getmobility
24219 
24220 
24221 !--------------------------------------------------------------------------------------------------
24223 !--------------------------------------------------------------------------------------------------
24224 subroutine damage_nonlocal_putnonlocaldamage(phi,ip,el)
24225 
24226  integer, intent(in) :: &
24227  ip, & !< integration point number
24228  el
24229  real(preal), intent(in) :: &
24230  phi
24231  integer :: &
24232  homog, &
24233  offset
24234 
24235  homog = material_homogenizationat(el)
24236  offset = damagemapping(homog)%p(ip,el)
24237  damage(homog)%p(offset) = phi
24238 
24239 end subroutine damage_nonlocal_putnonlocaldamage
24240 
24241 
24242 !--------------------------------------------------------------------------------------------------
24244 !--------------------------------------------------------------------------------------------------
24245 subroutine damage_nonlocal_results(homog,group)
24246 
24247  integer, intent(in) :: homog
24248  character(len=*), intent(in) :: group
24249 
24250  integer :: o
24251 
24252  associate(prm => param(damage_typeinstance(homog)))
24253  outputsloop: do o = 1,size(prm%output)
24254  select case(prm%output(o))
24255  case ('damage')
24256  call results_writedataset(group,damage(homog)%p,'phi',&
24257  'damage indicator','-')
24258  end select
24259  enddo outputsloop
24260  end associate
24261 
24262 end subroutine damage_nonlocal_results
24263 
24264 end module damage_nonlocal
24265 # 51 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
24266 
24267 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization.f90" 1
24268 !--------------------------------------------------------------------------------------------------
24273 !--------------------------------------------------------------------------------------------------
24274 module homogenization
24275  use prec
24276  use io
24277  use config
24278  use debug
24279  use math
24281  use numerics
24282  use constitutive
24283  use crystallite
24284  use fesolving
24285  use discretization
24286  use thermal_isothermal
24287  use thermal_adiabatic
24288  use thermal_conduction
24289  use damage_none
24290  use damage_local
24291  use damage_nonlocal
24292  use results
24293 
24294  implicit none
24295  private
24296 
24297 !--------------------------------------------------------------------------------------------------
24298 ! General variables for the homogenization at a material point
24299  real(pReal), dimension(:,:,:,:), allocatable, public :: &
24300  materialpoint_F0, & !< def grad of IP at start of FE increment
24301  materialpoint_F, & !< def grad of IP to be reached at end of FE increment
24302  materialpoint_P
24303  real(pReal), dimension(:,:,:,:,:,:), allocatable, public :: &
24304  materialpoint_dPdF
24306  real(preal), dimension(:,:,:,:), allocatable :: &
24307  materialpoint_subf0, & !< def grad of IP at beginning of homogenization increment
24309  real(preal), dimension(:,:), allocatable :: &
24313  logical, dimension(:,:), allocatable :: &
24316  logical, dimension(:,:,:), allocatable :: &
24318 
24319  type :: tnumerics
24320  integer :: &
24321  nmpstate
24322  real(preal) :: &
24323  substepminhomog, & !< minimum (relative) size of sub-step allowed during cutback in homogenization
24324  substepsizehomog, & !< size of first substep when cutback in homogenization
24325  stepIncreaseHomog
24326  end type tnumerics
24327 
24328  type(tnumerics) :: num
24329 
24330  interface
24331 
24332  module subroutine mech_none_init
24333  end subroutine mech_none_init
24335  module subroutine mech_isostrain_init
24336  end subroutine mech_isostrain_init
24337 
24338  module subroutine mech_rgc_init
24339  end subroutine mech_rgc_init
24340 
24341 
24342  module subroutine mech_isostrain_partitiondeformation(f,avgf)
24343  real(preal), dimension (:,:,:), intent(out) :: f
24344  real(preal), dimension (3,3), intent(in) :: avgf
24345  end subroutine mech_isostrain_partitiondeformation
24346 
24347  module subroutine mech_rgc_partitiondeformation(f,avgf,instance,of)
24348  real(preal), dimension (:,:,:), intent(out) :: f
24349  real(preal), dimension (3,3), intent(in) :: avgf
24350  integer, intent(in) :: &
24351  instance, &
24352  of
24353  end subroutine mech_rgc_partitiondeformation
24354 
24355 
24356  module subroutine mech_isostrain_averagestressanditstangent(avgp,davgpdavgf,p,dpdf,instance)
24357  real(preal), dimension (3,3), intent(out) :: avgp
24358  real(preal), dimension (3,3,3,3), intent(out) :: davgpdavgf
24359 
24360  real(preal), dimension (:,:,:), intent(in) :: p
24361  real(preal), dimension (:,:,:,:,:), intent(in) :: dpdf
24362  integer, intent(in) :: instance
24363  end subroutine mech_isostrain_averagestressanditstangent
24364 
24365  module subroutine mech_rgc_averagestressanditstangent(avgp,davgpdavgf,p,dpdf,instance)
24366  real(preal), dimension (3,3), intent(out) :: avgp
24367  real(preal), dimension (3,3,3,3), intent(out) :: davgpdavgf
24368 
24369  real(preal), dimension (:,:,:), intent(in) :: p
24370  real(preal), dimension (:,:,:,:,:), intent(in) :: dpdf
24371  integer, intent(in) :: instance
24372  end subroutine mech_rgc_averagestressanditstangent
24373 
24374 
24375  module function mech_rgc_updatestate(p,f,f0,avgf,dt,dpdf,ip,el)
24376  logical, dimension(2) :: mech_rgc_updatestate
24377  real(preal), dimension(:,:,:), intent(in) :: &
24378  p,& !< partitioned stresses
24379  f,& !< partitioned deformation gradients
24380  f0
24381  real(preal), dimension(:,:,:,:,:), intent(in) :: dpdf
24382  real(preal), dimension(3,3), intent(in) :: avgf
24383  real(preal), intent(in) :: dt
24384  integer, intent(in) :: &
24385  ip, & !< integration point number
24386  el
24387  end function mech_rgc_updatestate
24388 
24389 
24390  module subroutine mech_rgc_results(instance,group)
24391  integer, intent(in) :: instance
24392  character(len=*), intent(in) :: group
24393  end subroutine mech_rgc_results
24394 
24395  end interface
24396 
24397  public :: &
24398  homogenization_init, &
24399  materialpoint_stressanditstangent, &
24400  homogenization_results
24401 
24402 contains
24403 
24404 
24405 !--------------------------------------------------------------------------------------------------
24407 !--------------------------------------------------------------------------------------------------
24408 subroutine homogenization_init
24409 
24410  if (any(homogenization_type == homogenization_none_id)) call mech_none_init
24411  if (any(homogenization_type == homogenization_isostrain_id)) call mech_isostrain_init
24412  if (any(homogenization_type == homogenization_rgc_id)) call mech_rgc_init
24413 
24417 
24418  if (any(damage_type == damage_none_id)) call damage_none_init
24421 
24422  call config_deallocate('material.config/homogenization')
24423 
24424 !--------------------------------------------------------------------------------------------------
24425 ! allocate and initialize global variables
24426  allocate(materialpoint_dpdf(3,3,3,3,discretization_nip,discretization_nelem), source=0.0_preal)
24427  materialpoint_f0 = spread(spread(math_i3,3,discretization_nip),4,discretization_nelem) ! initialize to identity
24428  materialpoint_f = materialpoint_f0 ! initialize to identity
24429  allocate(materialpoint_subf0(3,3,discretization_nip,discretization_nelem), source=0.0_preal)
24430  allocate(materialpoint_subf(3,3,discretization_nip,discretization_nelem), source=0.0_preal)
24431  allocate(materialpoint_p(3,3,discretization_nip,discretization_nelem), source=0.0_preal)
24432  allocate(materialpoint_subfrac(discretization_nip,discretization_nelem), source=0.0_preal)
24433  allocate(materialpoint_substep(discretization_nip,discretization_nelem), source=0.0_preal)
24434  allocate(materialpoint_subdt(discretization_nip,discretization_nelem), source=0.0_preal)
24435  allocate(materialpoint_requested(discretization_nip,discretization_nelem), source=.false.)
24436  allocate(materialpoint_converged(discretization_nip,discretization_nelem), source=.true.)
24437  allocate(materialpoint_doneandhappy(2,discretization_nip,discretization_nelem), source=.true.)
24438 
24439  write(6,'(/,a)') ' <<<+- homogenization init -+>>>'; flush(6)
24440 
24441  if (iand(debug_level(debug_homogenization), debug_levelbasic) /= 0) then
24442  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_dPdF: ', shape(materialpoint_dpdf)
24443  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_F0: ', shape(materialpoint_f0)
24444  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_F: ', shape(materialpoint_f)
24445  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_subF0: ', shape(materialpoint_subf0)
24446  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_subF: ', shape(materialpoint_subf)
24447  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_P: ', shape(materialpoint_p)
24448  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_subFrac: ', shape(materialpoint_subfrac)
24449  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_subStep: ', shape(materialpoint_substep)
24450  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_subdt: ', shape(materialpoint_subdt)
24451  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_requested: ', shape(materialpoint_requested)
24452  write(6,'(a32,1x,7(i8,1x))') 'materialpoint_converged: ', shape(materialpoint_converged)
24453  write(6,'(a32,1x,7(i8,1x),/)') 'materialpoint_doneAndHappy: ', shape(materialpoint_doneandhappy)
24454  endif
24455  flush(6)
24456 
24458  call io_error(602,ext_msg='constituent', el=debug_e, g=debug_g)
24459 
24460  num%nMPstate = config_numerics%getInt( 'nmpstate', defaultval=10)
24461  num%subStepMinHomog = config_numerics%getFloat('substepminhomog', defaultval=1.0e-3_preal)
24462  num%subStepSizeHomog = config_numerics%getFloat('substepsizehomog', defaultval=0.25_preal)
24463  num%stepIncreaseHomog = config_numerics%getFloat('stepincreasehomog', defaultval=1.5_preal)
24464  if (num%nMPstate < 1) call io_error(301,ext_msg='nMPstate')
24465  if (num%subStepMinHomog <= 0.0_preal) call io_error(301,ext_msg='subStepMinHomog')
24466  if (num%subStepSizeHomog <= 0.0_preal) call io_error(301,ext_msg='subStepSizeHomog')
24467  if (num%stepIncreaseHomog <= 0.0_preal) call io_error(301,ext_msg='stepIncreaseHomog')
24468 
24469 end subroutine homogenization_init
24470 
24471 
24472 !--------------------------------------------------------------------------------------------------
24474 !--------------------------------------------------------------------------------------------------
24475 subroutine materialpoint_stressanditstangent(updateJaco,dt)
24476 
24477  real(preal), intent(in) :: dt
24478  logical, intent(in) :: updatejaco
24479  integer :: &
24480  niterationhomog, &
24481  niterationmpstate, &
24482  g, & !< grain number
24483  i, & !< integration point number
24484  e, & !< element number
24485  mysource, &
24486  myngrains
24487 
24488 # 231 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization.f90"
24489 
24490 !--------------------------------------------------------------------------------------------------
24491 ! initialize restoration points of ...
24494  do i = fesolving_execip(1),fesolving_execip(2);
24495  do g = 1,myngrains
24496 
24497  plasticstate(material_phaseat(g,e))%partionedState0(:,material_phasememberat(g,i,e)) = &
24498  plasticstate(material_phaseat(g,e))%state0( :,material_phasememberat(g,i,e))
24499  do mysource = 1, phase_nsources(material_phaseat(g,e))
24500  sourcestate(material_phaseat(g,e))%p(mysource)%partionedState0(:,material_phasememberat(g,i,e)) = &
24501  sourcestate(material_phaseat(g,e))%p(mysource)%state0( :,material_phasememberat(g,i,e))
24502  enddo
24503 
24504  crystallite_partionedfp0(1:3,1:3,g,i,e) = crystallite_fp0(1:3,1:3,g,i,e)
24505  crystallite_partionedlp0(1:3,1:3,g,i,e) = crystallite_lp0(1:3,1:3,g,i,e)
24506  crystallite_partionedfi0(1:3,1:3,g,i,e) = crystallite_fi0(1:3,1:3,g,i,e)
24507  crystallite_partionedli0(1:3,1:3,g,i,e) = crystallite_li0(1:3,1:3,g,i,e)
24508  crystallite_partionedf0(1:3,1:3,g,i,e) = crystallite_f0(1:3,1:3,g,i,e)
24509  crystallite_partioneds0(1:3,1:3,g,i,e) = crystallite_s0(1:3,1:3,g,i,e)
24510 
24511  enddo
24512 
24513 
24514  materialpoint_subf0(1:3,1:3,i,e) = materialpoint_f0(1:3,1:3,i,e)
24515  materialpoint_subfrac(i,e) = 0.0_preal
24516  materialpoint_substep(i,e) = 1.0_preal/num%subStepSizeHomog ! <<added to adopt flexibility in cutback size>>
24517  materialpoint_converged(i,e) = .false. ! pretend failed step of twice the required size
24518  materialpoint_requested(i,e) = .true. ! everybody requires calculation
24519 
24520  if (homogstate(material_homogenizationat(e))%sizeState > 0) &
24522  homogstate(material_homogenizationat(e))%State0( :,material_homogenizationmemberat(i,e)) ! ...internal homogenization state
24523 
24524  if (thermalstate(material_homogenizationat(e))%sizeState > 0) &
24526  thermalstate(material_homogenizationat(e))%State0( :,material_homogenizationmemberat(i,e)) ! ...internal thermal state
24527 
24528  if (damagestate(material_homogenizationat(e))%sizeState > 0) &
24530  damagestate(material_homogenizationat(e))%State0( :,material_homogenizationmemberat(i,e)) ! ...internal damage state
24531  enddo
24532  enddo
24533 
24534  niterationhomog = 0
24535 
24536  cutbacklooping: do while (.not. terminallyill .and. &
24537  any(materialpoint_substep(:,fesolving_execelem(1):fesolving_execelem(2)) > num%subStepMinHomog))
24538 
24539  !$OMP PARALLEL DO PRIVATE(myNgrains)
24540  elementlooping1: do e = fesolving_execelem(1),fesolving_execelem(2)
24542  iplooping1: do i = fesolving_execip(1),fesolving_execip(2)
24543 
24544  converged: if (materialpoint_converged(i,e)) then
24545 # 296 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization.f90"
24546 
24547 !---------------------------------------------------------------------------------------------------
24548 ! calculate new subStep and new subFrac
24549  materialpoint_subfrac(i,e) = materialpoint_subfrac(i,e) + materialpoint_substep(i,e)
24550  materialpoint_substep(i,e) = min(1.0_preal-materialpoint_subfrac(i,e), &
24551  num%stepIncreaseHomog*materialpoint_substep(i,e)) ! introduce flexibility for step increase/acceleration
24552 
24553  steppingneeded: if (materialpoint_substep(i,e) > num%subStepMinHomog) then
24554 
24555  ! wind forward grain starting point of...
24556  crystallite_partionedf0(1:3,1:3,1:myngrains,i,e) = &
24557  crystallite_partionedf(1:3,1:3,1:myngrains,i,e)
24558 
24559  crystallite_partionedfp0(1:3,1:3,1:myngrains,i,e) = &
24560  crystallite_fp(1:3,1:3,1:myngrains,i,e)
24561 
24562  crystallite_partionedlp0(1:3,1:3,1:myngrains,i,e) = &
24563  crystallite_lp(1:3,1:3,1:myngrains,i,e)
24564 
24565  crystallite_partionedfi0(1:3,1:3,1:myngrains,i,e) = &
24566  crystallite_fi(1:3,1:3,1:myngrains,i,e)
24567 
24568  crystallite_partionedli0(1:3,1:3,1:myngrains,i,e) = &
24569  crystallite_li(1:3,1:3,1:myngrains,i,e)
24570 
24571  crystallite_partioneds0(1:3,1:3,1:myngrains,i,e) = &
24572  crystallite_s(1:3,1:3,1:myngrains,i,e)
24573 
24574  do g = 1,myngrains
24575  plasticstate(material_phaseat(g,e))%partionedState0(:,material_phasememberat(g,i,e)) = &
24577  do mysource = 1, phase_nsources(material_phaseat(g,e))
24578  sourcestate(material_phaseat(g,e))%p(mysource)%partionedState0(:,material_phasememberat(g,i,e)) = &
24579  sourcestate(material_phaseat(g,e))%p(mysource)%state (:,material_phasememberat(g,i,e))
24580  enddo
24581  enddo
24582 
24583  if(homogstate(material_homogenizationat(e))%sizeState > 0) &
24586  if(thermalstate(material_homogenizationat(e))%sizeState > 0) &
24589  if(damagestate(material_homogenizationat(e))%sizeState > 0) &
24592 
24593  materialpoint_subf0(1:3,1:3,i,e) = materialpoint_subf(1:3,1:3,i,e)
24594 
24595  endif steppingneeded
24596 
24597  else converged
24598  if ( (myngrains == 1 .and. materialpoint_substep(i,e) <= 1.0 ) .or. & ! single grain already tried internal subStepping in crystallite
24599  num%subStepSizeHomog * materialpoint_substep(i,e) <= num%subStepMinHomog ) then ! would require too small subStep
24600  ! cutback makes no sense
24601  !$OMP FLUSH(terminallyIll)
24602  if (.not. terminallyill) then ! so first signals terminally ill...
24603  !$OMP CRITICAL (write2out)
24604  write(6,*) 'Integration point ', i,' at element ', e, ' terminally ill'
24605  !$OMP END CRITICAL (write2out)
24606  endif
24607  terminallyill = .true. ! ...and kills all others
24608  else ! cutback makes sense
24609  materialpoint_substep(i,e) = num%subStepSizeHomog * materialpoint_substep(i,e) ! crystallite had severe trouble, so do a significant cutback
24610 
24611 # 370 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization.f90"
24612 
24613 !--------------------------------------------------------------------------------------------------
24614 ! restore...
24615  if (materialpoint_substep(i,e) < 1.0_preal) then ! protect against fake cutback from \Delta t = 2 to 1. Maybe that "trick" is not necessary anymore at all? I.e. start with \Delta t = 1
24616  crystallite_lp(1:3,1:3,1:myngrains,i,e) = &
24617  crystallite_partionedlp0(1:3,1:3,1:myngrains,i,e)
24618  crystallite_li(1:3,1:3,1:myngrains,i,e) = &
24619  crystallite_partionedli0(1:3,1:3,1:myngrains,i,e)
24620  endif ! maybe protecting everything from overwriting (not only L) makes even more sense
24621  crystallite_fp(1:3,1:3,1:myngrains,i,e) = &
24622  crystallite_partionedfp0(1:3,1:3,1:myngrains,i,e)
24623  crystallite_fi(1:3,1:3,1:myngrains,i,e) = &
24624  crystallite_partionedfi0(1:3,1:3,1:myngrains,i,e)
24625  crystallite_s(1:3,1:3,1:myngrains,i,e) = &
24626  crystallite_partioneds0(1:3,1:3,1:myngrains,i,e)
24627  do g = 1, myngrains
24628  plasticstate(material_phaseat(g,e))%state( :,material_phasememberat(g,i,e)) = &
24629  plasticstate(material_phaseat(g,e))%partionedState0(:,material_phasememberat(g,i,e))
24630  do mysource = 1, phase_nsources(material_phaseat(g,e))
24631  sourcestate(material_phaseat(g,e))%p(mysource)%state( :,material_phasememberat(g,i,e)) = &
24632  sourcestate(material_phaseat(g,e))%p(mysource)%partionedState0(:,material_phasememberat(g,i,e))
24633  enddo
24634  enddo
24635  if(homogstate(material_homogenizationat(e))%sizeState > 0) &
24638  if(thermalstate(material_homogenizationat(e))%sizeState > 0) &
24641  if(damagestate(material_homogenizationat(e))%sizeState > 0) &
24644  endif
24645  endif converged
24646 
24647  if (materialpoint_substep(i,e) > num%subStepMinHomog) then
24648  materialpoint_requested(i,e) = .true.
24649  materialpoint_subf(1:3,1:3,i,e) = materialpoint_subf0(1:3,1:3,i,e) &
24650  + materialpoint_substep(i,e) * (materialpoint_f(1:3,1:3,i,e) &
24651  - materialpoint_f0(1:3,1:3,i,e))
24652  materialpoint_subdt(i,e) = materialpoint_substep(i,e) * dt
24653  materialpoint_doneandhappy(1:2,i,e) = [.false.,.true.]
24654  endif
24655  enddo iplooping1
24656  enddo elementlooping1
24657  !$OMP END PARALLEL DO
24658 
24659  niterationmpstate = 0
24660 
24661  convergencelooping: do while (.not. terminallyill .and. &
24662  any( materialpoint_requested(:,fesolving_execelem(1):fesolving_execelem(2)) &
24663  .and. .not. materialpoint_doneandhappy(1,:,fesolving_execelem(1):fesolving_execelem(2)) &
24664  ) .and. &
24665  niterationmpstate < num%nMPstate)
24666  niterationmpstate = niterationmpstate + 1
24667 
24668 !--------------------------------------------------------------------------------------------------
24669 ! deformation partitioning
24670 ! based on materialpoint_subF0,.._subF,crystallite_partionedF0, and homogenization_state,
24671 ! results in crystallite_partionedF
24672  !$OMP PARALLEL DO PRIVATE(myNgrains)
24673  elementlooping2: do e = fesolving_execelem(1),fesolving_execelem(2)
24675  iplooping2: do i = fesolving_execip(1),fesolving_execip(2)
24676  if ( materialpoint_requested(i,e) .and. & ! process requested but...
24677  .not. materialpoint_doneandhappy(1,i,e)) then ! ...not yet done material points
24678  call partitiondeformation(i,e) ! partition deformation onto constituents
24679  crystallite_dt(1:myngrains,i,e) = materialpoint_subdt(i,e) ! propagate materialpoint dt to grains
24680  crystallite_requested(1:myngrains,i,e) = .true. ! request calculation for constituents
24681  else
24682  crystallite_requested(1:myngrains,i,e) = .false. ! calculation for constituents not required anymore
24683  endif
24684  enddo iplooping2
24685  enddo elementlooping2
24686  !$OMP END PARALLEL DO
24687 
24688 !--------------------------------------------------------------------------------------------------
24689 ! crystallite integration
24690 ! based on crystallite_partionedF0,.._partionedF
24691 ! incrementing by crystallite_dt
24692 
24693  materialpoint_converged = crystallite_stress() !ToDo: MD not sure if that is the best logic
24694 
24695 !--------------------------------------------------------------------------------------------------
24696 ! state update
24697  !$OMP PARALLEL DO
24698  elementlooping3: do e = fesolving_execelem(1),fesolving_execelem(2)
24699  iplooping3: do i = fesolving_execip(1),fesolving_execip(2)
24700  if ( materialpoint_requested(i,e) .and. &
24701  .not. materialpoint_doneandhappy(1,i,e)) then
24702  if (.not. materialpoint_converged(i,e)) then
24703  materialpoint_doneandhappy(1:2,i,e) = [.true.,.false.]
24704  else
24705  materialpoint_doneandhappy(1:2,i,e) = updatestate(i,e)
24706  materialpoint_converged(i,e) = all(materialpoint_doneandhappy(1:2,i,e)) ! converged if done and happy
24707  endif
24708  endif
24709  enddo iplooping3
24710  enddo elementlooping3
24711  !$OMP END PARALLEL DO
24712 
24713  enddo convergencelooping
24714 
24715  niterationhomog = niterationhomog + 1
24716 
24717  enddo cutbacklooping
24718 
24719  if(updatejaco) call crystallite_stresstangent
24720 
24721  if (.not. terminallyill ) then
24722  call crystallite_orientations() ! calculate crystal orientations
24723  !$OMP PARALLEL DO
24724  elementlooping4: do e = fesolving_execelem(1),fesolving_execelem(2)
24725  iplooping4: do i = fesolving_execip(1),fesolving_execip(2)
24726  call averagestressanditstangent(i,e)
24727  enddo iplooping4
24728  enddo elementlooping4
24729  !$OMP END PARALLEL DO
24730  else
24731  write(6,'(/,a,/)') '<< HOMOG >> Material Point terminally ill'
24732  endif
24733 
24734 end subroutine materialpoint_stressanditstangent
24735 
24736 
24737 !--------------------------------------------------------------------------------------------------
24739 !--------------------------------------------------------------------------------------------------
24740 subroutine partitiondeformation(ip,el)
24741 
24742  integer, intent(in) :: &
24743  ip, & !< integration point
24744  el
24745 
24746  chosenhomogenization: select case(homogenization_type(material_homogenizationat(el)))
24748  case (homogenization_none_id) chosenhomogenization
24749  crystallite_partionedf(1:3,1:3,1,ip,el) = materialpoint_subf(1:3,1:3,ip,el)
24750 
24751  case (homogenization_isostrain_id) chosenhomogenization
24752  call mech_isostrain_partitiondeformation(&
24753  crystallite_partionedf(1:3,1:3,1:homogenization_ngrains(material_homogenizationat(el)),ip,el), &
24754  materialpoint_subf(1:3,1:3,ip,el))
24755 
24756  case (homogenization_rgc_id) chosenhomogenization
24757  call mech_rgc_partitiondeformation(&
24758  crystallite_partionedf(1:3,1:3,1:homogenization_ngrains(material_homogenizationat(el)),ip,el), &
24759  materialpoint_subf(1:3,1:3,ip,el),&
24760  ip, &
24761  el)
24762  end select chosenhomogenization
24763 
24764 end subroutine partitiondeformation
24765 
24766 
24767 !--------------------------------------------------------------------------------------------------
24770 !--------------------------------------------------------------------------------------------------
24771 function updatestate(ip,el)
24772 
24773  integer, intent(in) :: &
24774  ip, & !< integration point
24775  el
24776  logical, dimension(2) :: updateState
24777 
24778  updatestate = .true.
24779  chosenhomogenization: select case(homogenization_type(material_homogenizationat(el)))
24780  case (homogenization_rgc_id) chosenhomogenization
24781  updatestate = &
24782  updatestate .and. &
24783  mech_rgc_updatestate(crystallite_p(1:3,1:3,1:homogenization_ngrains(material_homogenizationat(el)),ip,el), &
24784  crystallite_partionedf(1:3,1:3,1:homogenization_ngrains(material_homogenizationat(el)),ip,el), &
24785  crystallite_partionedf0(1:3,1:3,1:homogenization_ngrains(material_homogenizationat(el)),ip,el),&
24786  materialpoint_subf(1:3,1:3,ip,el),&
24787  materialpoint_subdt(ip,el), &
24788  crystallite_dpdf(1:3,1:3,1:3,1:3,1:homogenization_ngrains(material_homogenizationat(el)),ip,el), &
24789  ip, &
24790  el)
24791  end select chosenhomogenization
24792 
24793  chosenthermal: select case (thermal_type(material_homogenizationat(el)))
24794  case (thermal_adiabatic_id) chosenthermal
24795  updatestate = &
24796  updatestate .and. &
24797  thermal_adiabatic_updatestate(materialpoint_subdt(ip,el), &
24798  ip, &
24799  el)
24800  end select chosenthermal
24801 
24802  chosendamage: select case (damage_type(material_homogenizationat(el)))
24803  case (damage_local_id) chosendamage
24804  updatestate = &
24805  updatestate .and. &
24806  damage_local_updatestate(materialpoint_subdt(ip,el), &
24807  ip, &
24808  el)
24809  end select chosendamage
24810 
24811 end function updatestate
24812 
24813 
24814 !--------------------------------------------------------------------------------------------------
24816 !--------------------------------------------------------------------------------------------------
24817 subroutine averagestressanditstangent(ip,el)
24818 
24819  integer, intent(in) :: &
24820  ip, & !< integration point
24821  el
24822 
24823  chosenhomogenization: select case(homogenization_type(material_homogenizationat(el)))
24824  case (homogenization_none_id) chosenhomogenization
24825  materialpoint_p(1:3,1:3,ip,el) = crystallite_p(1:3,1:3,1,ip,el)
24826  materialpoint_dpdf(1:3,1:3,1:3,1:3,ip,el) = crystallite_dpdf(1:3,1:3,1:3,1:3,1,ip,el)
24827 
24828  case (homogenization_isostrain_id) chosenhomogenization
24829  call mech_isostrain_averagestressanditstangent(&
24830  materialpoint_p(1:3,1:3,ip,el), &
24831  materialpoint_dpdf(1:3,1:3,1:3,1:3,ip,el),&
24832  crystallite_p(1:3,1:3,1:homogenization_ngrains(material_homogenizationat(el)),ip,el), &
24833  crystallite_dpdf(1:3,1:3,1:3,1:3,1:homogenization_ngrains(material_homogenizationat(el)),ip,el), &
24835 
24836  case (homogenization_rgc_id) chosenhomogenization
24837  call mech_rgc_averagestressanditstangent(&
24838  materialpoint_p(1:3,1:3,ip,el), &
24839  materialpoint_dpdf(1:3,1:3,1:3,1:3,ip,el),&
24840  crystallite_p(1:3,1:3,1:homogenization_ngrains(material_homogenizationat(el)),ip,el), &
24841  crystallite_dpdf(1:3,1:3,1:3,1:3,1:homogenization_ngrains(material_homogenizationat(el)),ip,el), &
24843  end select chosenhomogenization
24844 
24845 end subroutine averagestressanditstangent
24846 
24847 
24848 !--------------------------------------------------------------------------------------------------
24850 !--------------------------------------------------------------------------------------------------
24851 subroutine homogenization_results
24852  use material, only: &
24853  material_homogenization_type => homogenization_type
24854 
24855  integer :: p
24856  character(len=pStringLen) :: group_base,group
24857 
24858  !real(pReal), dimension(:,:,:), allocatable :: temp
24859 
24860  do p=1,size(config_name_homogenization)
24861  group_base = 'current/materialpoint/'//trim(config_name_homogenization(p))
24862  call results_closegroup(results_addgroup(group_base))
24863 
24864  group = trim(group_base)//'/generic'
24866  !temp = reshape(materialpoint_F,[3,3,discretization_nIP*discretization_nElem])
24867  !call results_writeDataset(group,temp,'F',&
24868  ! 'deformation gradient','1')
24869  !temp = reshape(materialpoint_P,[3,3,discretization_nIP*discretization_nElem])
24870  !call results_writeDataset(group,temp,'P',&
24871  ! '1st Piola-Kirchoff stress','Pa')
24872 
24873  group = trim(group_base)//'/mech'
24875  select case(material_homogenization_type(p))
24876  case(homogenization_rgc_id)
24877  call mech_rgc_results(homogenization_typeinstance(p),group)
24878  end select
24879 
24880  group = trim(group_base)//'/damage'
24882  select case(damage_type(p))
24883  case(damage_local_id)
24884  call damage_local_results(p,group)
24885  case(damage_nonlocal_id)
24886  call damage_nonlocal_results(p,group)
24887  end select
24888 
24889  group = trim(group_base)//'/thermal'
24891  select case(thermal_type(p))
24892  case(thermal_adiabatic_id)
24893  call thermal_adiabatic_results(p,group)
24894  case(thermal_conduction_id)
24895  call thermal_conduction_results(p,group)
24896  end select
24897 
24898  enddo
24899 
24900 end subroutine homogenization_results
24901 
24902 end module homogenization
24903 # 52 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
24904 
24905 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_none.f90" 1
24906 !--------------------------------------------------------------------------------------------------
24911 !--------------------------------------------------------------------------------------------------
24912 submodule(homogenization) homogenization_mech_none
24913 
24914 contains
24915 
24916 !--------------------------------------------------------------------------------------------------
24918 !--------------------------------------------------------------------------------------------------
24919 module subroutine mech_none_init
24920 
24921  integer :: &
24922  ninstance, &
24923  h, &
24924  nofmyhomog
24925 
24926  write(6,'(/,a)') ' <<<+- homogenization_'//homogenization_none_label//' init -+>>>'; flush(6)
24927 
24928  ninstance = count(homogenization_type == homogenization_none_id)
24929  if (iand(debug_level(debug_homogenization),debug_levelbasic) /= 0) &
24930  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
24931 
24932  do h = 1, size(homogenization_type)
24933  if (homogenization_type(h) /= homogenization_none_id) cycle
24934 
24935  nofmyhomog = count(material_homogenizationat == h)
24936  homogstate(h)%sizeState = 0
24937  allocate(homogstate(h)%state0 (0,nofmyhomog))
24938  allocate(homogstate(h)%subState0(0,nofmyhomog))
24939  allocate(homogstate(h)%state (0,nofmyhomog))
24940 
24941  enddo
24942 
24943 end subroutine mech_none_init
24944 
24945 end submodule homogenization_mech_none
24946 # 53 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
24947 
24948 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_isostrain.f90" 1
24949 !--------------------------------------------------------------------------------------------------
24954 !--------------------------------------------------------------------------------------------------
24955 submodule(homogenization) homogenization_mech_isostrain
24956 
24957  enum, bind(c); enumerator :: &
24958  parallel_id, &
24959  average_id
24960  end enum
24961 
24962  type :: tparameters
24963  integer :: &
24964  nconstituents
24965  integer(kind(average_ID)) :: &
24966  mapping
24967  end type
24968 
24969  type(tparameters), dimension(:), allocatable :: param
24970 
24971 
24972 contains
24973 
24974 !--------------------------------------------------------------------------------------------------
24976 !--------------------------------------------------------------------------------------------------
24977 module subroutine mech_isostrain_init
24978 
24979  integer :: &
24980  ninstance, &
24981  h, &
24982  nofmyhomog
24983  character(len=pStringLen) :: &
24984  tag = ''
24985 
24986  write(6,'(/,a)') ' <<<+- homogenization_'//homogenization_isostrain_label//' init -+>>>'
24987 
24988  ninstance = count(homogenization_type == homogenization_isostrain_id)
24989  if (iand(debug_level(debug_homogenization),debug_levelbasic) /= 0) &
24990  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
24991 
24992  allocate(param(ninstance)) ! one container of parameters per instance
24993 
24994  do h = 1, size(homogenization_type)
24995  if (homogenization_type(h) /= homogenization_isostrain_id) cycle
24996 
24997  associate(prm => param(homogenization_typeinstance(h)),&
24998  config => config_homogenization(h))
24999 
25000  prm%Nconstituents = config_homogenization(h)%getInt('nconstituents')
25001  tag = 'sum'
25002  select case(trim(config%getString('mapping',defaultval = tag)))
25003  case ('sum')
25004  prm%mapping = parallel_id
25005  case ('avg')
25006  prm%mapping = average_id
25007  case default
25008  call io_error(211,ext_msg=trim(tag)//' ('//homogenization_isostrain_label//')')
25009  end select
25010 
25011  nofmyhomog = count(material_homogenizationat == h)
25012  homogstate(h)%sizeState = 0
25013  allocate(homogstate(h)%state0 (0,nofmyhomog))
25014  allocate(homogstate(h)%subState0(0,nofmyhomog))
25015  allocate(homogstate(h)%state (0,nofmyhomog))
25016 
25017  end associate
25018 
25019  enddo
25020 
25021 end subroutine mech_isostrain_init
25022 
25023 
25024 !--------------------------------------------------------------------------------------------------
25026 !--------------------------------------------------------------------------------------------------
25027 module subroutine mech_isostrain_partitiondeformation(f,avgf)
25028 
25029  real(preal), dimension (:,:,:), intent(out) :: f
25030 
25031  real(preal), dimension (3,3), intent(in) :: avgf
25032 
25033  f = spread(avgf,3,size(f,3))
25034 
25035 end subroutine mech_isostrain_partitiondeformation
25036 
25037 
25038 !--------------------------------------------------------------------------------------------------
25040 !--------------------------------------------------------------------------------------------------
25041 module subroutine mech_isostrain_averagestressanditstangent(avgp,davgpdavgf,p,dpdf,instance)
25042 
25043  real(preal), dimension (3,3), intent(out) :: avgp
25044  real(preal), dimension (3,3,3,3), intent(out) :: davgpdavgf
25045 
25046  real(preal), dimension (:,:,:), intent(in) :: p
25047  real(preal), dimension (:,:,:,:,:), intent(in) :: dpdf
25048  integer, intent(in) :: instance
25049 
25050  associate(prm => param(instance))
25051 
25052  select case (prm%mapping)
25053  case (parallel_id)
25054  avgp = sum(p,3)
25055  davgpdavgf = sum(dpdf,5)
25056  case (average_id)
25057  avgp = sum(p,3) /real(prm%Nconstituents,preal)
25058  davgpdavgf = sum(dpdf,5)/real(prm%Nconstituents,preal)
25059  end select
25060 
25061  end associate
25062 
25063 end subroutine mech_isostrain_averagestressanditstangent
25064 
25065 end submodule homogenization_mech_isostrain
25066 # 54 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
25067 
25068 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90" 1
25069 !--------------------------------------------------------------------------------------------------
25076 !--------------------------------------------------------------------------------------------------
25077 submodule(homogenization) homogenization_mech_rgc
25078  use rotations
25079 
25080  type :: tparameters
25081  integer, dimension(:), allocatable :: &
25082  nconstituents
25083  real(preal) :: &
25084  xialpha, &
25085  cialpha
25086  real(preal), dimension(:), allocatable :: &
25087  dalpha, &
25088  angles
25089  integer :: &
25090  of_debug = 0
25091  character(len=pStringLen), allocatable, dimension(:) :: &
25092  output
25093  end type tparameters
25094 
25095  type :: trgcstate
25096  real(preal), pointer, dimension(:) :: &
25097  work, &
25098  penaltyenergy
25099  real(preal), pointer, dimension(:,:) :: &
25101  end type trgcstate
25102 
25103  type :: trgcdependentstate
25104  real(preal), allocatable, dimension(:) :: &
25105  volumediscrepancy, &
25106  relaxationrate_avg, &
25107  relaxationrate_max
25108  real(preal), allocatable, dimension(:,:) :: &
25109  mismatch
25110  real(preal), allocatable, dimension(:,:,:) :: &
25111  orientation
25112  end type trgcdependentstate
25113 
25114  type :: tnumerics_rgc
25115  real(preal) :: &
25116  atol, & !< absolute tolerance of RGC residuum
25117  rtol, & !< relative tolerance of RGC residuum
25118  absmax, & !< absolute maximum of RGC residuum
25119  relmax, & !< relative maximum of RGC residuum
25120  ppert, & !< perturbation for computing RGC penalty tangent
25121  xsmoo, & !< RGC penalty smoothing parameter (hyperbolic tangent)
25122  viscpower, & !< power (sensitivity rate) of numerical viscosity in RGC scheme, Default 1.0e0: Newton viscosity (linear model)
25123  viscmodus, & !< stress modulus of RGC numerical viscosity, Default 0.0e0: No viscosity is applied
25124  refrelaxrate, & !< reference relaxation rate in RGC viscosity
25125  maxdrelax, & !< threshold of maximum relaxation vector increment (if exceed this then cutback)
25126  maxvoldiscr, & !< threshold of maximum volume discrepancy allowed
25127  voldiscrmod, & !< stiffness of RGC volume discrepancy (zero = without volume discrepancy constraint)
25128  voldiscrpow
25129  end type tnumerics_rgc
25130 
25131  type(tparameters), dimension(:), allocatable :: &
25132  param
25133  type(trgcstate), dimension(:), allocatable :: &
25134  state, &
25135  state0
25136  type(trgcdependentstate), dimension(:), allocatable :: &
25137  dependentstate
25138  type(tnumerics_rgc) :: &
25139  num ! numerics parameters. Better name?
25140 
25141 contains
25142 
25143 !--------------------------------------------------------------------------------------------------
25145 !--------------------------------------------------------------------------------------------------
25146 module subroutine mech_rgc_init
25147 
25148  integer :: &
25149  ninstance, &
25150  h, &
25151  nofmyhomog, &
25152  sizestate, nintfacetot
25153 
25154  write(6,'(/,a)') ' <<<+- homogenization_'//homogenization_rgc_label//' init -+>>>'; flush(6)
25155 
25156  write(6,'(/,a)') ' Tjahjanto et al., International Journal of Material Forming 2(1):939–942, 2009'
25157  write(6,'(a)') ' https://doi.org/10.1007/s12289-009-0619-1'
25158 
25159  write(6,'(/,a)') ' Tjahjanto et al., Modelling and Simulation in Materials Science and Engineering 18:015006, 2010'
25160  write(6,'(a)') ' https://doi.org/10.1088/0965-0393/18/1/015006'
25161 
25162  ninstance = count(homogenization_type == homogenization_rgc_id)
25163  if (iand(debug_level(debug_homogenization),debug_levelbasic) /= 0) &
25164  write(6,'(a16,1x,i5,/)') '# instances:',ninstance
25165 
25166  allocate(param(ninstance))
25167  allocate(state(ninstance))
25168  allocate(state0(ninstance))
25169  allocate(dependentstate(ninstance))
25170 
25171  num%atol = config_numerics%getFloat('atol_rgc', defaultval=1.0e+4_preal)
25172  num%rtol = config_numerics%getFloat('rtol_rgc', defaultval=1.0e-3_preal)
25173  num%absMax = config_numerics%getFloat('amax_rgc', defaultval=1.0e+10_preal)
25174  num%relMax = config_numerics%getFloat('rmax_rgc', defaultval=1.0e+2_preal)
25175  num%pPert = config_numerics%getFloat('perturbpenalty_rgc', defaultval=1.0e-7_preal)
25176  num%xSmoo = config_numerics%getFloat('relvantmismatch_rgc', defaultval=1.0e-5_preal)
25177  num%viscPower = config_numerics%getFloat('viscositypower_rgc', defaultval=1.0e+0_preal)
25178  num%viscModus = config_numerics%getFloat('viscositymodulus_rgc', defaultval=0.0e+0_preal)
25179  num%refRelaxRate = config_numerics%getFloat('refrelaxationrate_rgc',defaultval=1.0e-3_preal)
25180  num%maxdRelax = config_numerics%getFloat('maxrelaxationrate_rgc',defaultval=1.0e+0_preal)
25181  num%maxVolDiscr = config_numerics%getFloat('maxvoldiscrepancy_rgc',defaultval=1.0e-5_preal)
25182  num%volDiscrMod = config_numerics%getFloat('voldiscrepancymod_rgc',defaultval=1.0e+12_preal)
25183  num%volDiscrPow = config_numerics%getFloat('dicrepancypower_rgc', defaultval=5.0_preal)
25184 
25185  if (num%atol <= 0.0_preal) call io_error(301,ext_msg='absTol_RGC')
25186  if (num%rtol <= 0.0_preal) call io_error(301,ext_msg='relTol_RGC')
25187  if (num%absMax <= 0.0_preal) call io_error(301,ext_msg='absMax_RGC')
25188  if (num%relMax <= 0.0_preal) call io_error(301,ext_msg='relMax_RGC')
25189  if (num%pPert <= 0.0_preal) call io_error(301,ext_msg='pPert_RGC')
25190  if (num%xSmoo <= 0.0_preal) call io_error(301,ext_msg='xSmoo_RGC')
25191  if (num%viscPower < 0.0_preal) call io_error(301,ext_msg='viscPower_RGC')
25192  if (num%viscModus < 0.0_preal) call io_error(301,ext_msg='viscModus_RGC')
25193  if (num%refRelaxRate <= 0.0_preal) call io_error(301,ext_msg='refRelaxRate_RGC')
25194  if (num%maxdRelax <= 0.0_preal) call io_error(301,ext_msg='maxdRelax_RGC')
25195  if (num%maxVolDiscr <= 0.0_preal) call io_error(301,ext_msg='maxVolDiscr_RGC')
25196  if (num%volDiscrMod < 0.0_preal) call io_error(301,ext_msg='volDiscrMod_RGC')
25197  if (num%volDiscrPow <= 0.0_preal) call io_error(301,ext_msg='volDiscrPw_RGC')
25198 
25199  do h = 1, size(homogenization_type)
25200  if (homogenization_type(h) /= homogenization_rgc_id) cycle
25201  associate(prm => param(homogenization_typeinstance(h)), &
25202  stt => state(homogenization_typeinstance(h)), &
25203  st0 => state0(homogenization_typeinstance(h)), &
25204  dst => dependentstate(homogenization_typeinstance(h)), &
25205  config => config_homogenization(h))
25206 
25207 
25208 
25209 
25210 
25211 
25212 
25213  prm%output = config%getStrings('(output)',defaultval=emptystringarray)
25214 
25215  prm%Nconstituents = config%getInts('clustersize',requiredsize=3)
25216  if (homogenization_ngrains(h) /= product(prm%Nconstituents)) &
25217  call io_error(211,ext_msg='clustersize ('//homogenization_rgc_label//')')
25218 
25219  prm%xiAlpha = config%getFloat('scalingparameter')
25220  prm%ciAlpha = config%getFloat('overproportionality')
25221 
25222  prm%dAlpha = config%getFloats('grainsize', requiredsize=3)
25223  prm%angles = config%getFloats('clusterorientation',requiredsize=3)
25224 
25225  nofmyhomog = count(material_homogenizationat == h)
25226  nintfacetot = 3*( (prm%Nconstituents(1)-1)*prm%Nconstituents(2)*prm%Nconstituents(3) &
25227  + prm%Nconstituents(1)*(prm%Nconstituents(2)-1)*prm%Nconstituents(3) &
25228  + prm%Nconstituents(1)*prm%Nconstituents(2)*(prm%Nconstituents(3)-1))
25229  sizestate = nintfacetot &
25230  + size(['avg constitutive work ','average penalty energy'])
25231 
25232  homogstate(h)%sizeState = sizestate
25233  allocate(homogstate(h)%state0 (sizestate,nofmyhomog), source=0.0_preal)
25234  allocate(homogstate(h)%subState0(sizestate,nofmyhomog), source=0.0_preal)
25235  allocate(homogstate(h)%state (sizestate,nofmyhomog), source=0.0_preal)
25236 
25237  stt%relaxationVector => homogstate(h)%state(1:nintfacetot,:)
25238  st0%relaxationVector => homogstate(h)%state0(1:nintfacetot,:)
25239  stt%work => homogstate(h)%state(nintfacetot+1,:)
25240  stt%penaltyEnergy => homogstate(h)%state(nintfacetot+2,:)
25241 
25242  allocate(dst%volumeDiscrepancy( nofmyhomog))
25243  allocate(dst%relaxationRate_avg( nofmyhomog))
25244  allocate(dst%relaxationRate_max( nofmyhomog))
25245  allocate(dst%mismatch( 3,nofmyhomog))
25246 
25247 !--------------------------------------------------------------------------------------------------
25248 ! assigning cluster orientations
25249  dependentstate(homogenization_typeinstance(h))%orientation = spread(eu2om(prm%angles*inrad),3,nofmyhomog)
25250  !dst%orientation = spread(eu2om(prm%angles*inRad),3,NofMyHomog) ifort version 18.0.1 crashes (for whatever reason)
25251 
25252  end associate
25253 
25254  enddo
25255 
25256 end subroutine mech_rgc_init
25257 
25258 
25259 !--------------------------------------------------------------------------------------------------
25261 !--------------------------------------------------------------------------------------------------
25262 module subroutine mech_rgc_partitiondeformation(f,avgf,instance,of)
25263 
25264  real(preal), dimension (:,:,:), intent(out) :: f
25265 
25266  real(preal), dimension (3,3), intent(in) :: avgf
25267  integer, intent(in) :: &
25268  instance, &
25269  of
25270 
25271  real(preal), dimension(3) :: avect,nvect
25272  integer, dimension(4) :: intface
25273  integer, dimension(3) :: igrain3
25274  integer :: igrain,iface,i,j
25275 
25276  associate(prm => param(instance))
25277 
25278 !--------------------------------------------------------------------------------------------------
25279 ! compute the deformation gradient of individual grains due to relaxations
25280  f = 0.0_preal
25281  do igrain = 1,product(prm%Nconstituents)
25282  igrain3 = grain1to3(igrain,prm%Nconstituents)
25283  do iface = 1,6
25284  intface = getinterface(iface,igrain3) ! identifying 6 interfaces of each grain
25285  avect = relaxationvector(intface,instance,of) ! get the relaxation vectors for each interface from global relaxation vector array
25286  nvect = interfacenormal(intface,instance,of)
25287  forall (i=1:3,j=1:3) &
25288  f(i,j,igrain) = f(i,j,igrain) + avect(i)*nvect(j) ! calculating deformation relaxations due to interface relaxation
25289  enddo
25290  f(1:3,1:3,igrain) = f(1:3,1:3,igrain) + avgf ! resulting relaxed deformation gradient
25291 
25292 # 234 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25293  enddo
25294 
25295  end associate
25296 
25297 end subroutine mech_rgc_partitiondeformation
25298 
25299 
25300 !--------------------------------------------------------------------------------------------------
25302 ! "happy" with result
25303 !--------------------------------------------------------------------------------------------------
25304 module procedure mech_rgc_updatestate
25305 
25306  integer, dimension(4) :: intfacen,intfacep,faceid
25307  integer, dimension(3) :: ngdim,igr3n,igr3p
25308  integer :: instance,inum,i,j,nintfacetot,igrn,igrp,imun,iface,k,l,ipert,igrain,ngrain, of
25309  real(preal), dimension(3,3,size(P,3)) :: r,pf,pr,d,pd
25310  real(preal), dimension(3,size(P,3)) :: nn,devnull
25311  real(preal), dimension(3) :: normp,normn,mornp,mornn
25312  real(preal) :: residmax,stresmax
25313  logical :: error
25314  real(preal), dimension(:,:), allocatable :: tract,jmatrix,jnverse,smatrix,pmatrix,rmatrix
25315  real(preal), dimension(:), allocatable :: resid,relax,p_relax,p_resid,drelax
25316 
25317 
25318 
25319 
25320 
25321  zerotimestep: if(deq0(dt)) then
25322  mech_rgc_updatestate = .true. ! pretend everything is fine and return
25323  return
25324  endif zerotimestep
25325 
25326  instance = homogenization_typeinstance(material_homogenizationat(el))
25327  of = material_homogenizationmemberat(ip,el)
25328 
25329  associate(stt => state(instance), st0 => state0(instance), dst => dependentstate(instance), prm => param(instance))
25330 
25331 !--------------------------------------------------------------------------------------------------
25332 ! get the dimension of the cluster (grains and interfaces)
25333  ngdim = prm%Nconstituents
25334  ngrain = product(ngdim)
25335  nintfacetot = (ngdim(1)-1)*ngdim(2)*ngdim(3) &
25336  + ngdim(1)*(ngdim(2)-1)*ngdim(3) &
25337  + ngdim(1)*ngdim(2)*(ngdim(3)-1)
25338 
25339 !--------------------------------------------------------------------------------------------------
25340 ! allocate the size of the global relaxation arrays/jacobian matrices depending on the size of the cluster
25341  allocate(resid(3*nintfacetot), source=0.0_preal)
25342  allocate(tract(nintfacetot,3), source=0.0_preal)
25343  relax = stt%relaxationVector(:,of)
25344  drelax = stt%relaxationVector(:,of) - st0%relaxationVector(:,of)
25345 
25346 # 296 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25347 
25348 !--------------------------------------------------------------------------------------------------
25349 ! computing interface mismatch and stress penalty tensor for all interfaces of all grains
25350  call stresspenalty(r,nn,avgf,f,ip,el,instance,of)
25351 
25352 !--------------------------------------------------------------------------------------------------
25353 ! calculating volume discrepancy and stress penalty related to overall volume discrepancy
25354  call volumepenalty(d,dst%volumeDiscrepancy(of),avgf,f,ngrain,instance,of)
25355 
25356 # 320 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25357 
25358 !------------------------------------------------------------------------------------------------
25359 ! computing the residual stress from the balance of traction at all (interior) interfaces
25360  do inum = 1,nintfacetot
25361  faceid = interface1to4(inum,param(instance)%Nconstituents) ! identifying the interface ID in local coordinate system (4-dimensional index)
25362 
25363 !--------------------------------------------------------------------------------------------------
25364 ! identify the left/bottom/back grain (-|N)
25365  igr3n = faceid(2:4) ! identifying the grain ID in local coordinate system (3-dimensional index)
25366  igrn = grain3to1(igr3n,param(instance)%Nconstituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
25367  intfacen = getinterface(2*faceid(1),igr3n)
25368  normn = interfacenormal(intfacen,instance,of)
25369 
25370 !--------------------------------------------------------------------------------------------------
25371 ! identify the right/up/front grain (+|P)
25372  igr3p = igr3n
25373  igr3p(faceid(1)) = igr3n(faceid(1))+1 ! identifying the grain ID in local coordinate system (3-dimensional index)
25374  igrp = grain3to1(igr3p,param(instance)%Nconstituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
25375  intfacep = getinterface(2*faceid(1)-1,igr3p)
25376  normp = interfacenormal(intfacep,instance,of)
25377 
25378 !--------------------------------------------------------------------------------------------------
25379 ! compute the residual of traction at the interface (in local system, 4-dimensional index)
25380  do i = 1,3
25381  tract(inum,i) = sign(num%viscModus*(abs(drelax(i+3*(inum-1)))/(num%refRelaxRate*dt))**num%viscPower, &
25382  drelax(i+3*(inum-1))) ! contribution from the relaxation viscosity
25383  do j = 1,3
25384  tract(inum,i) = tract(inum,i) + (p(i,j,igrp) + r(i,j,igrp) + d(i,j,igrp))*normp(j) & ! contribution from material stress P, mismatch penalty R, and volume penalty D projected into the interface
25385  + (p(i,j,igrn) + r(i,j,igrn) + d(i,j,igrn))*normn(j)
25386  resid(i+3*(inum-1)) = tract(inum,i) ! translate the local residual into global 1-dimensional residual array
25387  enddo
25388  enddo
25389 
25390 
25391 
25392 
25393 
25394 
25395 
25396 
25397  enddo
25398 
25399 !--------------------------------------------------------------------------------------------------
25400 ! convergence check for stress residual
25401  stresmax = maxval(abs(p)) ! get the maximum of first Piola-Kirchhoff (material) stress
25402  residmax = maxval(abs(tract)) ! get the maximum of the residual
25403 
25404 # 380 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25405 
25406  mech_rgc_updatestate = .false.
25407 
25408 !--------------------------------------------------------------------------------------------------
25409 ! If convergence reached => done and happy
25410  if (residmax < num%rtol*stresmax .or. residmax < num%atol) then
25411  mech_rgc_updatestate = .true.
25412 
25413 
25414 
25415 
25416 
25417 !--------------------------------------------------------------------------------------------------
25418 ! compute/update the state for postResult, i.e., all energy densities computed by time-integration
25419  do igrain = 1,product(prm%Nconstituents)
25420  do i = 1,3;do j = 1,3
25421  stt%work(of) = stt%work(of) &
25422  + p(i,j,igrain)*(f(i,j,igrain) - f0(i,j,igrain))/real(ngrain,preal)
25423  stt%penaltyEnergy(of) = stt%penaltyEnergy(of) &
25424  + r(i,j,igrain)*(f(i,j,igrain) - f0(i,j,igrain))/real(ngrain,preal)
25425  enddo; enddo
25426  enddo
25427 
25428  dst%mismatch(1:3,of) = sum(nn,2)/real(ngrain,preal)
25429  dst%relaxationRate_avg(of) = sum(abs(drelax))/dt/real(3*nintfacetot,preal)
25430  dst%relaxationRate_max(of) = maxval(abs(drelax))/dt
25431 
25432 # 420 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25433 
25434  return
25435 
25436 !--------------------------------------------------------------------------------------------------
25437 ! if residual blows-up => done but unhappy
25438  elseif (residmax > num%relMax*stresmax .or. residmax > num%absMax) then ! try to restart when residual blows up exceeding maximum bound
25439  mech_rgc_updatestate = [.true.,.false.] ! with direct cut-back
25440 
25441 
25442 
25443 
25444 
25445 
25446  return
25447 
25448  else ! proceed with computing the Jacobian and state update
25449 
25450 
25451 
25452 
25453 
25454  endif
25455 
25456 !---------------------------------------------------------------------------------------------------
25457 ! construct the global Jacobian matrix for updating the global relaxation vector array when
25458 ! convergence is not yet reached ...
25459 
25460 !--------------------------------------------------------------------------------------------------
25461 ! ... of the constitutive stress tangent, assembled from dPdF or material constitutive model "smatrix"
25462  allocate(smatrix(3*nintfacetot,3*nintfacetot), source=0.0_preal)
25463  do inum = 1,nintfacetot
25464  faceid = interface1to4(inum,param(instance)%Nconstituents) ! assembling of local dPdF into global Jacobian matrix
25465 
25466 !--------------------------------------------------------------------------------------------------
25467 ! identify the left/bottom/back grain (-|N)
25468  igr3n = faceid(2:4) ! identifying the grain ID in local coordinate sytem
25469  igrn = grain3to1(igr3n,param(instance)%Nconstituents) ! translate into global grain ID
25470  intfacen = getinterface(2*faceid(1),igr3n) ! identifying the connecting interface in local coordinate system
25471  normn = interfacenormal(intfacen,instance,of)
25472  do iface = 1,6
25473  intfacen = getinterface(iface,igr3n) ! identifying all interfaces that influence relaxation of the above interface
25474  mornn = interfacenormal(intfacen,instance,of)
25475  imun = interface4to1(intfacen,param(instance)%Nconstituents) ! translate the interfaces ID into local 4-dimensional index
25476  if (imun > 0) then ! get the corresponding tangent
25477  do i=1,3; do j=1,3; do k=1,3; do l=1,3
25478  smatrix(3*(inum-1)+i,3*(imun-1)+j) = smatrix(3*(inum-1)+i,3*(imun-1)+j) &
25479  + dpdf(i,k,j,l,igrn)*normn(k)*mornn(l)
25480  enddo;enddo;enddo;enddo
25481 ! projecting the material tangent dPdF into the interface
25482 ! to obtain the Jacobian matrix contribution of dPdF
25483  endif
25484  enddo
25485 
25486 !--------------------------------------------------------------------------------------------------
25487 ! identify the right/up/front grain (+|P)
25488  igr3p = igr3n
25489  igr3p(faceid(1)) = igr3n(faceid(1))+1 ! identifying the grain ID in local coordinate sytem
25490  igrp = grain3to1(igr3p,param(instance)%Nconstituents) ! translate into global grain ID
25491  intfacep = getinterface(2*faceid(1)-1,igr3p) ! identifying the connecting interface in local coordinate system
25492  normp = interfacenormal(intfacep,instance,of)
25493  do iface = 1,6
25494  intfacep = getinterface(iface,igr3p) ! identifying all interfaces that influence relaxation of the above interface
25495  mornp = interfacenormal(intfacep,instance,of)
25496  imun = interface4to1(intfacep,param(instance)%Nconstituents) ! translate the interfaces ID into local 4-dimensional index
25497  if (imun > 0) then ! get the corresponding tangent
25498  do i=1,3; do j=1,3; do k=1,3; do l=1,3
25499  smatrix(3*(inum-1)+i,3*(imun-1)+j) = smatrix(3*(inum-1)+i,3*(imun-1)+j) &
25500  + dpdf(i,k,j,l,igrp)*normp(k)*mornp(l)
25501  enddo;enddo;enddo;enddo
25502  endif
25503  enddo
25504  enddo
25505 
25506 # 503 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25507 
25508 !--------------------------------------------------------------------------------------------------
25509 ! ... of the stress penalty tangent (mismatch penalty and volume penalty, computed using numerical
25510 ! perturbation method) "pmatrix"
25511  allocate(pmatrix(3*nintfacetot,3*nintfacetot), source=0.0_preal)
25512  allocate(p_relax(3*nintfacetot), source=0.0_preal)
25513  allocate(p_resid(3*nintfacetot), source=0.0_preal)
25514 
25515  do ipert = 1,3*nintfacetot
25516  p_relax = relax
25517  p_relax(ipert) = relax(ipert) + num%pPert ! perturb the relaxation vector
25518  stt%relaxationVector(:,of) = p_relax
25519  call graindeformation(pf,avgf,instance,of) ! rain deformation from perturbed state
25520  call stresspenalty(pr,devnull, avgf,pf,ip,el,instance,of) ! stress penalty due to interface mismatch from perturbed state
25521  call volumepenalty(pd,devnull(1,1), avgf,pf,ngrain,instance,of) ! stress penalty due to volume discrepancy from perturbed state
25522 
25523 !--------------------------------------------------------------------------------------------------
25524 ! computing the global stress residual array from the perturbed state
25525  p_resid = 0.0_preal
25526  do inum = 1,nintfacetot
25527  faceid = interface1to4(inum,param(instance)%Nconstituents) ! identifying the interface ID in local coordinate system (4-dimensional index)
25528 
25529 !--------------------------------------------------------------------------------------------------
25530 ! identify the left/bottom/back grain (-|N)
25531  igr3n = faceid(2:4) ! identify the grain ID in local coordinate system (3-dimensional index)
25532  igrn = grain3to1(igr3n,param(instance)%Nconstituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
25533  intfacen = getinterface(2*faceid(1),igr3n) ! identify the interface ID of the grain
25534  normn = interfacenormal(intfacen,instance,of)
25535 
25536 !--------------------------------------------------------------------------------------------------
25537 ! identify the right/up/front grain (+|P)
25538  igr3p = igr3n
25539  igr3p(faceid(1)) = igr3n(faceid(1))+1 ! identify the grain ID in local coordinate system (3-dimensional index)
25540  igrp = grain3to1(igr3p,param(instance)%Nconstituents) ! translate the local grain ID into global coordinate system (1-dimensional index)
25541  intfacep = getinterface(2*faceid(1)-1,igr3p) ! identify the interface ID of the grain
25542  normp = interfacenormal(intfacep,instance,of)
25543 
25544 !--------------------------------------------------------------------------------------------------
25545 ! compute the residual stress (contribution of mismatch and volume penalties) from perturbed state
25546 ! at all interfaces
25547  do i = 1,3; do j = 1,3
25548  p_resid(i+3*(inum-1)) = p_resid(i+3*(inum-1)) + (pr(i,j,igrp) - r(i,j,igrp))*normp(j) &
25549  + (pr(i,j,igrn) - r(i,j,igrn))*normn(j) &
25550  + (pd(i,j,igrp) - d(i,j,igrp))*normp(j) &
25551  + (pd(i,j,igrn) - d(i,j,igrn))*normn(j)
25552  enddo; enddo
25553  enddo
25554  pmatrix(:,ipert) = p_resid/num%pPert
25555  enddo
25556 
25557 # 563 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25558 
25559 !--------------------------------------------------------------------------------------------------
25560 ! ... of the numerical viscosity traction "rmatrix"
25561  allocate(rmatrix(3*nintfacetot,3*nintfacetot),source=0.0_preal)
25562  do i=1,3*nintfacetot
25563  rmatrix(i,i) = num%viscModus*num%viscPower/(num%refRelaxRate*dt)* & ! tangent due to numerical viscosity traction appears
25564  (abs(drelax(i))/(num%refRelaxRate*dt))**(num%viscPower - 1.0_preal) ! only in the main diagonal term
25565  enddo
25566 
25567 # 582 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25568 
25569 !--------------------------------------------------------------------------------------------------
25570 ! The overall Jacobian matrix summarizing contributions of smatrix, pmatrix, rmatrix
25571  allocate(jmatrix(3*nintfacetot,3*nintfacetot)); jmatrix = smatrix + pmatrix + rmatrix
25572 
25573 # 597 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25574 
25575 !--------------------------------------------------------------------------------------------------
25576 ! computing the update of the state variable (relaxation vectors) using the Jacobian matrix
25577  allocate(jnverse(3*nintfacetot,3*nintfacetot),source=0.0_preal)
25578  call math_invert(jnverse,error,jmatrix)
25579 
25580 # 613 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25581 
25582 !--------------------------------------------------------------------------------------------------
25583 ! calculate the state update (global relaxation vectors) for the next Newton-Raphson iteration
25584  drelax = 0.0_preal
25585  do i = 1,3*nintfacetot;do j = 1,3*nintfacetot
25586  drelax(i) = drelax(i) - jnverse(i,j)*resid(j) ! Calculate the correction for the state variable
25587  enddo; enddo
25588  stt%relaxationVector(:,of) = relax + drelax ! Updateing the state variable for the next iteration
25589  if (any(abs(drelax) > num%maxdRelax)) then ! Forcing cutback when the incremental change of relaxation vector becomes too large
25590  mech_rgc_updatestate = [.true.,.false.]
25591  !$OMP CRITICAL (write2out)
25592  write(6,'(1x,a,1x,i3,1x,a,1x,i3,1x,a)')'RGC_updateState: ip',ip,'| el',el,'enforces cutback'
25593  write(6,'(1x,a,1x,e15.8)')'due to large relaxation change =',maxval(abs(drelax))
25594  flush(6)
25595  !$OMP END CRITICAL (write2out)
25596  endif
25597 
25598 # 640 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25599 
25600  end associate
25601 
25602  contains
25603  !------------------------------------------------------------------------------------------------
25605  !------------------------------------------------------------------------------------------------
25606  subroutine stresspenalty(rPen,nMis,avgF,fDef,ip,el,instance,of)
25607 
25608  real(preal), dimension (:,:,:), intent(out) :: rpen
25609  real(preal), dimension (:,:), intent(out) :: nmis
25610 
25611  real(preal), dimension (:,:,:), intent(in) :: fdef
25612  real(preal), dimension (3,3), intent(in) :: avgf
25613  integer, intent(in) :: ip,el,instance,of
25614 
25615  integer, dimension (4) :: intFace
25616  integer, dimension (3) :: iGrain3,iGNghb3,nGDim
25617  real(pReal), dimension (3,3) :: gDef,nDef
25618  real(pReal), dimension (3) :: nVect,surfCorr
25619  real(pReal), dimension (2) :: Gmoduli
25620  integer :: iGrain,iGNghb,iFace,i,j,k,l
25621  real(pReal) :: muGrain,muGNghb,nDefNorm,bgGrain,bgGNghb
25622  real(pReal), parameter :: nDefToler = 1.0e-10_preal
25623 
25624 
25625 
25626 
25627  ngdim = param(instance)%Nconstituents
25628  rpen = 0.0_preal
25629  nmis = 0.0_preal
25630 
25631  !----------------------------------------------------------------------------------------------
25632  ! get the correction factor the modulus of penalty stress representing the evolution of area of
25633  ! the interfaces due to deformations
25634 
25635  surfcorr = surfacecorrection(avgf,instance,of)
25636 
25637  associate(prm => param(instance))
25638 
25639 # 688 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/homogenization_mech_RGC.f90"
25640 
25641  !-----------------------------------------------------------------------------------------------
25642  ! computing the mismatch and penalty stress tensor of all grains
25643  grainloop: do igrain = 1,product(prm%Nconstituents)
25644  gmoduli = equivalentmoduli(igrain,ip,el)
25645  mugrain = gmoduli(1) ! collecting the equivalent shear modulus of grain
25646  bggrain = gmoduli(2) ! and the lengthh of Burgers vector
25647  igrain3 = grain1to3(igrain,prm%Nconstituents) ! get the grain ID in local 3-dimensional index (x,y,z)-position
25648 
25649  interfaceloop: do iface = 1,6
25650  intface = getinterface(iface,igrain3) ! get the 4-dimensional index of the interface in local numbering system of the grain
25651  nvect = interfacenormal(intface,instance,of)
25652  ignghb3 = igrain3 ! identify the neighboring grain across the interface
25653  ignghb3(abs(intface(1))) = ignghb3(abs(intface(1))) &
25654  + int(real(intface(1),preal)/real(abs(intface(1)),preal))
25655  where(ignghb3 < 1) ignghb3 = ngdim
25656  where(ignghb3 >ngdim) ignghb3 = 1
25657  ignghb = grain3to1(ignghb3,prm%Nconstituents) ! get the ID of the neighboring grain
25658  gmoduli = equivalentmoduli(ignghb,ip,el) ! collect the shear modulus and Burgers vector of the neighbor
25659  mugnghb = gmoduli(1)
25660  bggnghb = gmoduli(2)
25661  gdef = 0.5_preal*(fdef(1:3,1:3,ignghb) - fdef(1:3,1:3,igrain)) ! difference/jump in deformation gradeint across the neighbor
25662 
25663  !-------------------------------------------------------------------------------------------
25664  ! compute the mismatch tensor of all interfaces
25665  ndefnorm = 0.0_preal
25666  ndef = 0.0_preal
25667  do i = 1,3; do j = 1,3
25668  do k = 1,3; do l = 1,3
25669  ndef(i,j) = ndef(i,j) - nvect(k)*gdef(i,l)*math_levicivita(j,k,l) ! compute the interface mismatch tensor from the jump of deformation gradient
25670  enddo; enddo
25671  ndefnorm = ndefnorm + ndef(i,j)**2.0_preal ! compute the norm of the mismatch tensor
25672  enddo; enddo
25673  ndefnorm = max(ndeftoler,sqrt(ndefnorm)) ! approximation to zero mismatch if mismatch is zero (singularity)
25674  nmis(abs(intface(1)),igrain) = nmis(abs(intface(1)),igrain) + ndefnorm ! total amount of mismatch experienced by the grain (at all six interfaces)
25675 
25676 
25677 
25678 
25679 
25680 
25681 
25682 
25683  !-------------------------------------------------------------------------------------------
25684  ! compute the stress penalty of all interfaces
25685  do i = 1,3; do j = 1,3; do k = 1,3; do l = 1,3
25686  rpen(i,j,igrain) = rpen(i,j,igrain) + 0.5_preal*(mugrain*bggrain + mugnghb*bggnghb)*prm%xiAlpha &
25687  *surfcorr(abs(intface(1)))/prm%dAlpha(abs(intface(1))) &
25688  *cosh(prm%ciAlpha*ndefnorm) &
25689  *0.5_preal*nvect(l)*ndef(i,k)/ndefnorm*math_levicivita(k,l,j) &
25690  *tanh(ndefnorm/num%xSmoo)
25691  enddo; enddo;enddo; enddo
25692  enddo interfaceloop
25693 
25694 
25695 
25696 
25697 
25698 
25699 
25700  enddo grainloop
25701 
25702  end associate
25703 
25704  end subroutine stresspenalty
25705 
25706 
25707  !------------------------------------------------------------------------------------------------
25709  !------------------------------------------------------------------------------------------------
25710  subroutine volumepenalty(vPen,vDiscrep,fAvg,fDef,nGrain,instance,of)
25711 
25712  real(pReal), dimension (:,:,:), intent(out) :: vPen ! stress-like penalty due to volume
25713  real(pReal), intent(out) :: vDiscrep ! total volume discrepancy
25714 
25715  real(pReal), dimension (:,:,:), intent(in) :: fDef ! deformation gradients
25716  real(pReal), dimension (3,3), intent(in) :: fAvg ! overall deformation gradient
25717  integer, intent(in) :: &
25718  Ngrain, &
25719  instance, &
25720  of
25721 
25722  real(pReal), dimension(size(vPen,3)) :: gVol
25723  integer :: i
25724 
25725  !----------------------------------------------------------------------------------------------
25726  ! compute the volumes of grains and of cluster
25727  vdiscrep = math_det33(favg) ! compute the volume of the cluster
25728  do i = 1,ngrain
25729  gvol(i) = math_det33(fdef(1:3,1:3,i)) ! compute the volume of individual grains
25730  vdiscrep = vdiscrep - gvol(i)/real(ngrain,preal) ! calculate the difference/dicrepancy between
25731  ! the volume of the cluster and the the total volume of grains
25732  enddo
25733 
25734  !----------------------------------------------------------------------------------------------
25735  ! calculate the stress and penalty due to volume discrepancy
25736  vpen = 0.0_preal
25737  do i = 1,ngrain
25738  vpen(:,:,i) = -1.0_preal/real(ngrain,preal)*num%volDiscrMod*num%volDiscrPow/num%maxVolDiscr* &
25739  sign((abs(vdiscrep)/num%maxVolDiscr)**(num%volDiscrPow - 1.0),vdiscrep)* &
25740  gvol(i)*transpose(math_inv33(fdef(:,:,i)))
25741 
25742 
25743 
25744 
25745 
25746 
25747 
25748 
25749  enddo
25750 
25751  end subroutine volumepenalty
25752 
25753 
25754  !--------------------------------------------------------------------------------------------------
25756  ! deformation
25757  !--------------------------------------------------------------------------------------------------
25758  function surfacecorrection(avgF,instance,of)
25759 
25760  real(pReal), dimension(3) :: surfaceCorrection
25761 
25762  real(pReal), dimension(3,3), intent(in) :: avgF
25763  integer, intent(in) :: &
25764  instance, &
25765  of
25766  real(preal), dimension(3,3) :: invc
25767  real(preal), dimension(3) :: nvect
25768  real(preal) :: detf
25769  integer :: i,j,ibase
25770  logical :: error
25771 
25772  call math_invert33(invc,detf,error,matmul(transpose(avgf),avgf))
25773 
25774  surfacecorrection = 0.0_preal
25775  do ibase = 1,3
25776  nvect = interfacenormal([ibase,1,1,1],instance,of)
25777  do i = 1,3; do j = 1,3
25778  surfacecorrection(ibase) = surfacecorrection(ibase) + invc(i,j)*nvect(i)*nvect(j) ! compute the component of (the inverse of) the stretch in the direction of the normal
25779  enddo; enddo
25780  surfacecorrection(ibase) = sqrt(surfacecorrection(ibase))*detf ! get the surface correction factor (area contraction/enlargement)
25781  enddo
25782 
25783  end function surfacecorrection
25784 
25785 
25786  !--------------------------------------------------------------------------------------------------
25788  !--------------------------------------------------------------------------------------------------
25789  function equivalentmoduli(grainID,ip,el)
25790 
25791  real(preal), dimension(2) :: equivalentmoduli
25792 
25793  integer, intent(in) :: &
25794  grainid,&
25795  ip, & !< integration point number
25796  el
25797  real(preal), dimension(6,6) :: elastens
25798  real(preal) :: &
25799  cequiv_11, &
25800  cequiv_12, &
25801  cequiv_44
25802 
25803  elastens = constitutive_homogenizedc(grainid,ip,el)
25804 
25805  !----------------------------------------------------------------------------------------------
25806  ! compute the equivalent shear modulus after Turterltaub and Suiker, JMPS (2005)
25807  cequiv_11 = (elastens(1,1) + elastens(2,2) + elastens(3,3))/3.0_preal
25808  cequiv_12 = (elastens(1,2) + elastens(2,3) + elastens(3,1) + &
25809  elastens(1,3) + elastens(2,1) + elastens(3,2))/6.0_preal
25810  cequiv_44 = (elastens(4,4) + elastens(5,5) + elastens(6,6))/3.0_preal
25811  equivalentmoduli(1) = 0.2_preal*(cequiv_11 - cequiv_12) + 0.6_preal*cequiv_44
25812 
25813  !----------------------------------------------------------------------------------------------
25814  ! obtain the length of Burgers vector (could be model dependend)
25815  equivalentmoduli(2) = 2.5e-10_preal
25816 
25817  end function equivalentmoduli
25818 
25819 
25820  !--------------------------------------------------------------------------------------------------
25822  ! homogenization_RGC_partitionDeformation, but used only for perturbation scheme)
25823  !--------------------------------------------------------------------------------------------------
25824  subroutine graindeformation(F, avgF, instance, of)
25825 
25826  real(preal), dimension(:,:,:), intent(out) :: f
25827 
25828  real(preal), dimension(:,:), intent(in) :: avgf
25829  integer, intent(in) :: &
25830  instance, &
25831  of
25832 
25833  real(pReal), dimension(3) :: aVect,nVect
25834  integer, dimension(4) :: intFace
25835  integer, dimension(3) :: iGrain3
25836  integer :: iGrain,iFace,i,j
25837 
25838  !-------------------------------------------------------------------------------------------------
25839  ! compute the deformation gradient of individual grains due to relaxations
25840 
25841  associate(prm => param(instance))
25842 
25843  f = 0.0_preal
25844  do igrain = 1,product(prm%Nconstituents)
25845  igrain3 = grain1to3(igrain,prm%Nconstituents)
25846  do iface = 1,6
25847  intface = getinterface(iface,igrain3)
25848  avect = relaxationvector(intface,instance,of)
25849  nvect = interfacenormal(intface,instance,of)
25850  forall (i=1:3,j=1:3) &
25851  f(i,j,igrain) = f(i,j,igrain) + avect(i)*nvect(j) ! effective relaxations
25852  enddo
25853  f(1:3,1:3,igrain) = f(1:3,1:3,igrain) + avgf ! relaxed deformation gradient
25854  enddo
25855 
25856  end associate
25857 
25858  end subroutine graindeformation
25859 
25860 end procedure mech_rgc_updatestate
25861 
25862 
25863 !--------------------------------------------------------------------------------------------------
25865 !--------------------------------------------------------------------------------------------------
25866 module subroutine mech_rgc_averagestressanditstangent(avgp,davgpdavgf,p,dpdf,instance)
25867 
25868  real(pReal), dimension (3,3), intent(out) :: avgP
25869  real(pReal), dimension (3,3,3,3), intent(out) :: dAvgPdAvgF
25870 
25871  real(pReal), dimension (:,:,:), intent(in) :: P
25872  real(pReal), dimension (:,:,:,:,:), intent(in) :: dPdF
25873  integer, intent(in) :: instance
25874 
25875  avgp = sum(p,3) /real(product(param(instance)%Nconstituents),preal)
25876  davgpdavgf = sum(dpdf,5)/real(product(param(instance)%Nconstituents),preal)
25877 
25878 end subroutine mech_rgc_averagestressanditstangent
25879 
25880 
25881 !--------------------------------------------------------------------------------------------------
25883 !--------------------------------------------------------------------------------------------------
25884 module subroutine mech_rgc_results(instance,group)
25885 
25886  integer, intent(in) :: instance
25887  character(len=*), intent(in) :: group
25888 
25889  integer :: o
25890 
25891  associate(stt => state(instance), dst => dependentstate(instance), prm => param(instance))
25892  outputsloop: do o = 1,size(prm%output)
25893  select case(trim(prm%output(o)))
25894  case('constitutivework')
25895  call results_writedataset(group,stt%work,'W',&
25896  'work density','J/m³')
25897  case('magnitudemismatch')
25898  call results_writedataset(group,dst%mismatch,'N',&
25899  'average mismatch tensor','1')
25900  case('penaltyenergy')
25901  call results_writedataset(group,stt%penaltyEnergy,'R',&
25902  'mismatch penalty density','J/m³')
25903  case('volumediscrepancy')
25904  call results_writedataset(group,dst%volumeDiscrepancy,'Delta_V',&
25905  'volume discrepancy','m³')
25906  case('maximumrelaxrate')
25907  call results_writedataset(group,dst%relaxationrate_max,'max_alpha_dot',&
25908  'maximum relaxation rate','m/s')
25909  case('averagerelaxrate')
25910  call results_writedataset(group,dst%relaxationrate_avg,'avg_alpha_dot',&
25911  'average relaxation rate','m/s')
25912  end select
25913  enddo outputsloop
25914  end associate
25915 
25916 end subroutine mech_rgc_results
25917 
25918 
25919 !--------------------------------------------------------------------------------------------------
25921 !--------------------------------------------------------------------------------------------------
25922 pure function relaxationvector(intFace,instance,of)
25923 
25924  real(pReal), dimension (3) :: relaxationVector
25925 
25926  integer, intent(in) :: instance,of
25927  integer, dimension(4), intent(in) :: intFace
25928 
25929  integer :: inum
25930 
25931 !--------------------------------------------------------------------------------------------------
25932 ! collect the interface relaxation vector from the global state array
25933 
25934  inum = interface4to1(intface,param(instance)%Nconstituents) ! identify the position of the interface in global state array
25935  if (inum > 0) then
25936  relaxationvector = state(instance)%relaxationVector((3*inum-2):(3*inum),of)
25937  else
25938  relaxationvector = 0.0_preal
25939  endif
25940 
25941 end function relaxationvector
25942 
25943 
25944 !--------------------------------------------------------------------------------------------------
25946 !--------------------------------------------------------------------------------------------------
25947 pure function interfacenormal(intFace,instance,of)
25948 
25949  real(preal), dimension(3) :: interfacenormal
25950 
25951  integer, dimension(4), intent(in) :: intface
25952  integer, intent(in) :: &
25953  instance, &
25954  of
25955 
25956  integer :: npos
25957 
25958 !--------------------------------------------------------------------------------------------------
25959 ! get the normal of the interface, identified from the value of intFace(1)
25960  interfacenormal = 0.0_preal
25961  npos = abs(intface(1)) ! identify the position of the interface in global state array
25962  interfacenormal(npos) = real(intface(1)/abs(intface(1)),preal) ! get the normal vector w.r.t. cluster axis
25963 
25964  interfacenormal = matmul(dependentstate(instance)%orientation(1:3,1:3,of),interfacenormal) ! map the normal vector into sample coordinate system (basis)
25965 
25966 end function interfacenormal
25967 
25968 
25969 !--------------------------------------------------------------------------------------------------
25971 !--------------------------------------------------------------------------------------------------
25972 pure function getinterface(iFace,iGrain3)
25973 
25974  integer, dimension(4) :: getinterface
25975 
25976  integer, dimension(3), intent(in) :: igrain3
25977  integer, intent(in) :: iface
25978 
25979  integer :: idir
25980 
25981  idir = (int(real(iface-1,preal)/2.0_preal)+1)*(-1)**iface
25982  getinterface(1) = idir
25983 
25984 !--------------------------------------------------------------------------------------------------
25985 ! identify the interface position by the direction of its normal
25986  getinterface(2:4) = igrain3
25987  if (idir < 0) getinterface(1-idir) = getinterface(1-idir)-1 ! to have a correlation with coordinate/position in real space
25988 
25989 end function getinterface
25990 
25991 
25992 !--------------------------------------------------------------------------------------------------
25994 !--------------------------------------------------------------------------------------------------
25995 pure function grain1to3(grain1,nGDim)
25996 
25997  integer, dimension(3) :: grain1to3
25998 
25999  integer, intent(in) :: grain1
26000  integer, dimension(3), intent(in) :: ngdim
26001 
26002  grain1to3 = 1 + [mod((grain1-1), ngdim(1)), &
26003  mod((grain1-1)/ ngdim(1),ngdim(2)), &
26004  (grain1-1)/(ngdim(1)*ngdim(2))]
26005 
26006 end function grain1to3
26007 
26008 
26009 !--------------------------------------------------------------------------------------------------
26011 !--------------------------------------------------------------------------------------------------
26012 integer pure function grain3to1(grain3,ngdim)
26013 
26014  integer, dimension(3), intent(in) :: grain3
26015  integer, dimension(3), intent(in) :: ngdim
26016 
26017  grain3to1 = grain3(1) &
26018  + ngdim(1)*(grain3(2)-1) &
26019  + ngdim(1)*ngdim(2)*(grain3(3)-1)
26020 
26021 end function grain3to1
26022 
26023 
26024 !--------------------------------------------------------------------------------------------------
26026 !--------------------------------------------------------------------------------------------------
26027 integer pure function interface4to1(iface4d, ngdim)
26028 
26029  integer, dimension(4), intent(in) :: iface4d
26030  integer, dimension(3), intent(in) :: ngdim
26031 
26032 
26033  select case(abs(iface4d(1)))
26035  case(1)
26036  if ((iface4d(2) == 0) .or. (iface4d(2) == ngdim(1))) then
26037  interface4to1 = 0
26038  else
26039  interface4to1 = iface4d(3) + ngdim(2)*(iface4d(4)-1) &
26040  + ngdim(2)*ngdim(3)*(iface4d(2)-1)
26041  endif
26042 
26043  case(2)
26044  if ((iface4d(3) == 0) .or. (iface4d(3) == ngdim(2))) then
26045  interface4to1 = 0
26046  else
26047  interface4to1 = iface4d(4) + ngdim(3)*(iface4d(2)-1) &
26048  + ngdim(3)*ngdim(1)*(iface4d(3)-1) &
26049  + (ngdim(1)-1)*ngdim(2)*ngdim(3) ! total # of interfaces normal || e1
26050  endif
26051 
26052  case(3)
26053  if ((iface4d(4) == 0) .or. (iface4d(4) == ngdim(3))) then
26054  interface4to1 = 0
26055  else
26056  interface4to1 = iface4d(2) + ngdim(1)*(iface4d(3)-1) &
26057  + ngdim(1)*ngdim(2)*(iface4d(4)-1) &
26058  + (ngdim(1)-1)*ngdim(2)*ngdim(3) & ! total # of interfaces normal || e1
26059  + ngdim(1)*(ngdim(2)-1)*ngdim(3) ! total # of interfaces normal || e2
26060  endif
26061 
26062  case default
26063  interface4to1 = -1
26064 
26065  end select
26066 
26067 end function interface4to1
26068 
26069 
26070 !--------------------------------------------------------------------------------------------------
26072 !--------------------------------------------------------------------------------------------------
26073 pure function interface1to4(iFace1D, nGDim)
26074 
26075  integer, dimension(4) :: interface1to4
26076 
26077  integer, intent(in) :: iface1d
26078  integer, dimension(3), intent(in) :: ngdim
26079  integer, dimension(3) :: nintface
26081 !--------------------------------------------------------------------------------------------------
26082 ! compute the total number of interfaces, which ...
26083  nintface = [(ngdim(1)-1)*ngdim(2)*ngdim(3), & ! ... normal || e1
26084  ngdim(1)*(ngdim(2)-1)*ngdim(3), & ! ... normal || e2
26085  ngdim(1)*ngdim(2)*(ngdim(3)-1)] ! ... normal || e3
26086 
26087 !--------------------------------------------------------------------------------------------------
26088 ! get the corresponding interface ID in 4D (normal and local position)
26089  if (iface1d > 0 .and. iface1d <= nintface(1)) then ! interface with normal || e1
26090  interface1to4(1) = 1
26091  interface1to4(3) = mod((iface1d-1),ngdim(2))+1
26092  interface1to4(4) = mod(int(real(iface1d-1,preal)/real(ngdim(2),preal)),ngdim(3))+1
26093  interface1to4(2) = int(real(iface1d-1,preal)/real(ngdim(2),preal)/real(ngdim(3),preal))+1
26094  elseif (iface1d > nintface(1) .and. iface1d <= (nintface(2) + nintface(1))) then ! interface with normal || e2
26095  interface1to4(1) = 2
26096  interface1to4(4) = mod((iface1d-nintface(1)-1),ngdim(3))+1
26097  interface1to4(2) = mod(int(real(iface1d-nintface(1)-1,preal)/real(ngdim(3),preal)),ngdim(1))+1
26098  interface1to4(3) = int(real(iface1d-nintface(1)-1,preal)/real(ngdim(3),preal)/real(ngdim(1),preal))+1
26099  elseif (iface1d > nintface(2) + nintface(1) .and. iface1d <= (nintface(3) + nintface(2) + nintface(1))) then ! interface with normal || e3
26100  interface1to4(1) = 3
26101  interface1to4(2) = mod((iface1d-nintface(2)-nintface(1)-1),ngdim(1))+1
26102  interface1to4(3) = mod(int(real(iface1d-nintface(2)-nintface(1)-1,preal)/real(ngdim(1),preal)),ngdim(2))+1
26103  interface1to4(4) = int(real(iface1d-nintface(2)-nintface(1)-1,preal)/real(ngdim(1),preal)/real(ngdim(2),preal))+1
26104  endif
26105 
26106 end function interface1to4
26107 
26108 
26109 end submodule homogenization_mech_rgc
26110 # 55 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
26111 
26112 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/CPFEM.f90" 1
26113 !--------------------------------------------------------------------------------------------------
26117 !--------------------------------------------------------------------------------------------------
26118 module cpfem
26119  use prec
26120  use numerics
26121  use debug
26122  use fesolving
26123  use math
26124  use rotations
26126  use material
26127  use config
26128  use crystallite
26129  use homogenization
26130  use io
26131  use discretization
26132  use damask_interface
26133  use numerics
26134  use hdf5_utilities
26135  use results
26136  use lattice
26137  use constitutive
26138 
26139  implicit none
26140  private
26141 
26142  real(preal), dimension (:,:,:), allocatable, private :: &
26143  cpfem_cs
26144  real(preal), dimension (:,:,:,:), allocatable, private :: &
26145  cpfem_dcsde
26146  real(preal), dimension (:,:,:,:), allocatable, private :: &
26147  cpfem_dcsde_knowngood
26148  integer(pInt), public :: &
26149  cyclecounter = 0_pint, &
26150  theinc = -1_pint, &
26151  lastlovl = 0_pint
26152  real(preal), public :: &
26153  thetime = 0.0_preal, &
26154  thedelta = 0.0_preal
26155  logical, public :: &
26156  outdatedffn1 = .false., &
26157  lastincconverged = .false., &
26158  outdatedbynewinc = .false.
26159 
26160  logical, public, protected :: &
26161  cpfem_init_done = .false.
26162  logical, private :: &
26163  cpfem_calc_done = .false.
26164 
26165  integer(pInt), parameter, public :: &
26166  cpfem_collect = 2_pint**0_pint, &
26167  cpfem_calcresults = 2_pint**1_pint, &
26168  cpfem_ageresults = 2_pint**2_pint, &
26169  cpfem_backupjacobian = 2_pint**3_pint, &
26170  cpfem_restorejacobian = 2_pint**4_pint
26171 
26172  public :: &
26173  cpfem_general, &
26174  cpfem_initall, &
26176 
26177 contains
26178 
26179 
26180 !--------------------------------------------------------------------------------------------------
26182 !--------------------------------------------------------------------------------------------------
26183 subroutine cpfem_initall(el,ip)
26184 
26185  integer(pInt), intent(in) :: el, & !< FE el number
26186  ip
26187 
26188  !$OMP CRITICAL(init)
26189  if (.not. cpfem_init_done) then
26191  call prec_init
26192  call io_init
26193  call numerics_init
26194  call debug_init
26195  call config_init
26196  call math_init
26197  call rotations_init
26198  call hdf5_utilities_init
26199  call results_init
26200  call discretization_marc_init(ip, el)
26201  call lattice_init
26202  call material_init
26203  call constitutive_init
26204  call crystallite_init
26205  call homogenization_init
26206  call cpfem_init
26207  cpfem_init_done = .true.
26208  endif
26209  !$OMP END CRITICAL(init)
26210 
26211 end subroutine cpfem_initall
26212 
26213 
26214 !--------------------------------------------------------------------------------------------------
26216 !--------------------------------------------------------------------------------------------------
26217 subroutine cpfem_init
26218 
26219  write(6,'(/,a)') ' <<<+- CPFEM init -+>>>'
26220  flush(6)
26221 
26222  allocate(cpfem_cs( 6,discretization_nip,discretization_nelem), source= 0.0_preal)
26223  allocate(cpfem_dcsde( 6,6,discretization_nip,discretization_nelem), source= 0.0_preal)
26224  allocate(cpfem_dcsde_knowngood(6,6,discretization_nip,discretization_nelem), source= 0.0_preal)
26225 
26226  if (iand(debug_level(debug_cpfem), debug_levelbasic) /= 0) then
26227  write(6,'(a32,1x,6(i8,1x))') 'CPFEM_cs: ', shape(cpfem_cs)
26228  write(6,'(a32,1x,6(i8,1x))') 'CPFEM_dcsdE: ', shape(cpfem_dcsde)
26229  write(6,'(a32,1x,6(i8,1x),/)') 'CPFEM_dcsdE_knownGood: ', shape(cpfem_dcsde_knowngood)
26230  flush(6)
26231  endif
26232 
26233 end subroutine cpfem_init
26234 
26235 
26236 !--------------------------------------------------------------------------------------------------
26238 !--------------------------------------------------------------------------------------------------
26239 subroutine cpfem_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyStress, jacobian)
26240 
26241  integer(pInt), intent(in) :: elFE, & !< FE element number
26242  ip
26243  real(pReal), intent(in) :: dt
26244  real(pReal), dimension (3,3), intent(in) :: ffn, & !< deformation gradient for t=t0
26245  ffn1
26246  integer(pInt), intent(in) :: mode
26247  real(pReal), intent(in) :: temperature_inp
26248  logical, intent(in) :: parallelExecution
26249  real(pReal), dimension(6), intent(out) :: cauchyStress
26250  real(pReal), dimension(6,6), intent(out) :: jacobian
26251 
26252  real(pReal) J_inverse, & ! inverse of Jacobian
26253  rnd
26254  real(pReal), dimension (3,3) :: Kirchhoff, & ! Piola-Kirchhoff stress
26255  cauchyStress33 ! stress vector
26256  real(pReal), dimension (3,3,3,3) :: H_sym, &
26257  H, &
26258  jacobian3333 ! jacobian in Matrix notation
26259 
26260  integer(pInt) elCP, & ! crystal plasticity element number
26261  i, j, k, l, m, n, ph, homog, mySource
26262  logical updateJaco ! flag indicating if Jacobian has to be updated
26263 
26264  real(pReal), parameter :: ODD_STRESS = 1e15_preal, &
26265  odd_jacobian = 1e50_preal
26266 
26267  elcp = mesh_fem2damask_elem(elfe)
26268 
26269  if (iand(debug_level(debug_cpfem), debug_levelbasic) /= 0_pint &
26270  .and. elcp == debug_e .and. ip == debug_i) then
26271  write(6,'(/,a)') '#############################################'
26272  write(6,'(a1,a22,1x,i8,a13)') '#','element', elcp, '#'
26273  write(6,'(a1,a22,1x,i8,a13)') '#','ip', ip, '#'
26274  write(6,'(a1,a22,1x,f15.7,a6)') '#','theTime', thetime, '#'
26275  write(6,'(a1,a22,1x,f15.7,a6)') '#','theDelta', thedelta, '#'
26276  write(6,'(a1,a22,1x,i8,a13)') '#','theInc', theinc, '#'
26277  write(6,'(a1,a22,1x,i8,a13)') '#','cycleCounter', cyclecounter, '#'
26278  write(6,'(a1,a22,1x,i8,a13)') '#','computationMode',mode, '#'
26279  if (terminallyill) &
26280  write(6,'(a,/)') '# --- terminallyIll --- #'
26281  write(6,'(a,/)') '#############################################'; flush (6)
26282  endif
26283 
26284  if (iand(mode, cpfem_backupjacobian) /= 0_pint) &
26285  cpfem_dcsde_knowngood = cpfem_dcsde
26286  if (iand(mode, cpfem_restorejacobian) /= 0_pint) &
26287  cpfem_dcsde = cpfem_dcsde_knowngood
26288 
26289  !*** age results
26290  if (iand(mode, cpfem_ageresults) /= 0_pint) call cpfem_forward
26291 
26292 
26293  !*** collection of FEM input with returning of randomize odd stress and jacobian
26294  !* If no parallel execution is required, there is no need to collect FEM input
26295  if (.not. parallelexecution) then
26296  chosenthermal1: select case (thermal_type(material_homogenizationat(elcp)))
26297  case (thermal_conduction_id) chosenthermal1
26299  temperature_inp
26300  end select chosenthermal1
26301  materialpoint_f0(1:3,1:3,ip,elcp) = ffn
26302  materialpoint_f(1:3,1:3,ip,elcp) = ffn1
26303 
26304  elseif (iand(mode, cpfem_collect) /= 0_pint) then
26305  call random_number(rnd)
26306  if (rnd < 0.5_preal) rnd = rnd - 1.0_preal
26307  cpfem_cs(1:6,ip,elcp) = rnd * odd_stress
26308  cpfem_dcsde(1:6,1:6,ip,elcp) = odd_jacobian * math_identity2nd(6)
26309  chosenthermal2: select case (thermal_type(material_homogenizationat(elcp)))
26310  case (thermal_conduction_id) chosenthermal2
26312  temperature_inp
26313  end select chosenthermal2
26314  materialpoint_f0(1:3,1:3,ip,elcp) = ffn
26315  materialpoint_f(1:3,1:3,ip,elcp) = ffn1
26316  cpfem_calc_done = .false.
26317  endif
26318 
26319 
26320  !*** calculation of stress and jacobian
26321  if (iand(mode, cpfem_calcresults) /= 0_pint) then
26322 
26323  !*** deformation gradient outdated or any actual deformation gradient differs more than relevantStrain from the stored one
26324  validcalculation: if (terminallyill &
26325  .or. outdatedffn1 &
26326  .or. any(abs(ffn1 - materialpoint_f(1:3,1:3,ip,elcp)) > defgradtolerance)) then
26327  if (any(abs(ffn1 - materialpoint_f(1:3,1:3,ip,elcp)) > defgradtolerance)) then
26328  if (iand(debug_level(debug_cpfem), debug_levelbasic) /= 0_pint) then
26329  write(6,'(a,1x,i8,1x,i2)') '<< CPFEM >> OUTDATED at elFE ip',elfe,ip
26330  write(6,'(a,/,3(12x,3(f10.6,1x),/))') '<< CPFEM >> FFN1 old:',&
26331  transpose(materialpoint_f(1:3,1:3,ip,elcp))
26332  write(6,'(a,/,3(12x,3(f10.6,1x),/))') '<< CPFEM >> FFN1 now:',transpose(ffn1)
26333  endif
26334  outdatedffn1 = .true.
26335  endif
26336  call random_number(rnd)
26337  if (rnd < 0.5_preal) rnd = rnd - 1.0_preal
26338  cpfem_cs(1:6,ip,elcp) = odd_stress * rnd
26339  cpfem_dcsde(1:6,1:6,ip,elcp) = odd_jacobian * math_identity2nd(6)
26340 
26341  !*** deformation gradient is not outdated
26342  else validcalculation
26343  updatejaco = mod(cyclecounter,ijacostiffness) == 0
26344  !* no parallel computation, so we use just one single elFE and ip for computation
26345  if (.not. parallelexecution) then
26346  fesolving_execelem = elcp
26347  fesolving_execip = ip
26348  if (iand(debug_level(debug_cpfem), debug_levelextensive) /= 0_pint) &
26349  write(6,'(a,i8,1x,i2)') '<< CPFEM >> calculation for elFE ip ',elfe,ip
26350  call materialpoint_stressanditstangent(updatejaco, dt)
26351 
26352  !* parallel computation and calulation not yet done
26353  elseif (.not. cpfem_calc_done) then
26354  if (iand(debug_level(debug_cpfem), debug_levelextensive) /= 0_pint) &
26355  write(6,'(a,i8,a,i8)') '<< CPFEM >> calculation for elements ',fesolving_execelem(1),&
26356  ' to ',fesolving_execelem(2)
26357  call materialpoint_stressanditstangent(updatejaco, dt)
26358  cpfem_calc_done = .true.
26359  endif
26360 
26361  !* map stress and stiffness (or return odd values if terminally ill)
26362  terminalillness: if (terminallyill) then
26363 
26364  call random_number(rnd)
26365  if (rnd < 0.5_preal) rnd = rnd - 1.0_preal
26366  cpfem_cs(1:6,ip,elcp) = odd_stress * rnd
26367  cpfem_dcsde(1:6,1:6,ip,elcp) = odd_jacobian * math_identity2nd(6)
26368 
26369  else terminalillness
26370 
26371  ! translate from P to CS
26372  kirchhoff = matmul(materialpoint_p(1:3,1:3,ip,elcp), transpose(materialpoint_f(1:3,1:3,ip,elcp)))
26373  j_inverse = 1.0_preal / math_det33(materialpoint_f(1:3,1:3,ip,elcp))
26374  cpfem_cs(1:6,ip,elcp) = math_sym33to6(j_inverse * kirchhoff,weighted=.false.)
26375 
26376  ! translate from dP/dF to dCS/dE
26377  h = 0.0_preal
26378  do i=1,3; do j=1,3; do k=1,3; do l=1,3; do m=1,3; do n=1,3
26379  h(i,j,k,l) = h(i,j,k,l) &
26380  + materialpoint_f(j,m,ip,elcp) * materialpoint_f(l,n,ip,elcp) &
26381  * materialpoint_dpdf(i,m,k,n,ip,elcp) &
26382  - math_delta(j,l) * materialpoint_f(i,m,ip,elcp) * materialpoint_p(k,m,ip,elcp) &
26383  + 0.5_preal * ( kirchhoff(j,l)*math_delta(i,k) + kirchhoff(i,k)*math_delta(j,l) &
26384  + kirchhoff(j,k)*math_delta(i,l) + kirchhoff(i,l)*math_delta(j,k))
26385  enddo; enddo; enddo; enddo; enddo; enddo
26386 
26387  forall(i=1:3, j=1:3,k=1:3,l=1:3) &
26388  h_sym(i,j,k,l) = 0.25_preal * (h(i,j,k,l) + h(j,i,k,l) + h(i,j,l,k) + h(j,i,l,k))
26389 
26390  cpfem_dcsde(1:6,1:6,ip,elcp) = math_sym3333to66(j_inverse * h_sym,weighted=.false.)
26391 
26392  endif terminalillness
26393  endif validcalculation
26394 
26395  !* report stress and stiffness
26396  if ((iand(debug_level(debug_cpfem), debug_levelextensive) /= 0_pint) &
26397  .and. ((debug_e == elcp .and. debug_i == ip) &
26398  .or. .not. iand(debug_level(debug_cpfem), debug_levelselective) /= 0_pint)) then
26399  write(6,'(a,i8,1x,i2,/,12x,6(f10.3,1x)/)') &
26400  '<< CPFEM >> stress/MPa at elFE ip ', elfe, ip, cpfem_cs(1:6,ip,elcp)*1.0e-6_preal
26401  write(6,'(a,i8,1x,i2,/,6(12x,6(f10.3,1x)/))') &
26402  '<< CPFEM >> Jacobian/GPa at elFE ip ', elfe, ip, transpose(cpfem_dcsde(1:6,1:6,ip,elcp))*1.0e-9_preal
26403  flush(6)
26404  endif
26405 
26406  endif
26407 
26408  !*** warn if stiffness close to zero
26409  if (all(abs(cpfem_dcsde(1:6,1:6,ip,elcp)) < 1e-10_preal)) call io_warning(601,elcp,ip)
26410 
26411  !*** copy to output if using commercial FEM solver
26412  cauchystress = cpfem_cs(1:6, ip,elcp)
26413  jacobian = cpfem_dcsde(1:6,1:6,ip,elcp)
26414 
26415 
26416  !*** remember extreme values of stress ...
26417  cauchystress33 = math_6tosym33(cpfem_cs(1:6,ip,elcp),weighted=.false.)
26418  if (maxval(cauchystress33) > debug_stressmax) then
26419  debug_stressmaxlocation = [elcp, ip]
26420  debug_stressmax = maxval(cauchystress33)
26421  endif
26422  if (minval(cauchystress33) < debug_stressmin) then
26423  debug_stressminlocation = [elcp, ip]
26424  debug_stressmin = minval(cauchystress33)
26425  endif
26426  !*** ... and Jacobian
26427  jacobian3333 = math_66tosym3333(cpfem_dcsde(1:6,1:6,ip,elcp),weighted=.false.)
26428  if (maxval(jacobian3333) > debug_jacobianmax) then
26429  debug_jacobianmaxlocation = [elcp, ip]
26430  debug_jacobianmax = maxval(jacobian3333)
26431  endif
26432  if (minval(jacobian3333) < debug_jacobianmin) then
26433  debug_jacobianminlocation = [elcp, ip]
26434  debug_jacobianmin = minval(jacobian3333)
26435  endif
26436 
26437 end subroutine cpfem_general
26438 
26439 
26440 !--------------------------------------------------------------------------------------------------
26442 !--------------------------------------------------------------------------------------------------
26443 subroutine cpfem_forward
26444 
26445  call crystallite_forward
26446 
26447 end subroutine cpfem_forward
26448 
26449 
26450 !--------------------------------------------------------------------------------------------------
26452 !--------------------------------------------------------------------------------------------------
26453 subroutine cpfem_results(inc,time)
26454 
26455  integer(pInt), intent(in) :: inc
26456  real(pReal), intent(in) :: time
26457 
26458  call results_openjobfile
26459  call results_addincrement(inc,time)
26461  call crystallite_results
26466 
26467 end subroutine cpfem_results
26468 
26469 end module cpfem
26470 # 56 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/commercialFEM_fileList.f90" 2
26471 # 163 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/DAMASK_marc.f90" 2
26472 
26473 !--------------------------------------------------------------------------------------------------
26480 !--------------------------------------------------------------------------------------------------
26481 subroutine hypela2(d,g,e,de,s,t,dt,ngens,m,nn,kcus,matus,ndi,nshear,disp, &
26482  dispt,coord,ffn,frotn,strechn,eigvn,ffn1,frotn1, &
26483  strechn1,eigvn1,ncrd,itel,ndeg,ndm,nnode, &
26484  jtype,lclass,ifr,ifu)
26485  use prec
26486  use damask_interface
26487  use numerics
26488  use fesolving
26489  use debug
26491  use cpfem
26492 
26493  implicit none
26494 !$ include "omp_lib.h" ! the openMP function library
26495  integer, intent(in) :: & ! according to MSC.Marc 2012 Manual D
26496  ngens, & !< size of stress-strain law
26497  nn, & !< integration point number
26498  ndi, & !< number of direct components
26499  nshear, & !< number of shear components
26500  ncrd, & !< number of coordinates
26501  itel, & !< dimension of F and R, either 2 or 3
26502  ndeg, & !< number of degrees of freedom
26503  ndm, & !< not specified in MSC.Marc 2012 Manual D
26504  nnode, & !< number of nodes per element
26505  jtype, & !< element type
26506  ifr, & !< set to 1 if R has been calculated
26507  ifu
26508  integer, dimension(2), intent(in) :: & ! according to MSC.Marc 2012 Manual D
26509  m, & !< (1) user element number, (2) internal element number
26510  matus, & !< (1) user material identification number, (2) internal material identification number
26511  kcus, & !< (1) layer number, (2) internal layer number
26512  lclass
26513  real(pReal), dimension(*), intent(in) :: & ! has dimension(1) according to MSC.Marc 2012 Manual D, but according to example hypela2.f dimension(*)
26514  e, & !< total elastic strain
26515  de, & !< increment of strain
26516  dt
26517  real(pReal), dimension(itel), intent(in) :: & ! according to MSC.Marc 2012 Manual D
26518  strechn, & !< square of principal stretch ratios, lambda(i) at t=n
26519  strechn1
26520  real(pReal), dimension(3,3), intent(in) :: & ! has dimension(itel,*) according to MSC.Marc 2012 Manual D, but we alway assume dimension(3,3)
26521  ffn, & !< deformation gradient at t=n
26522  ffn1
26523  real(pReal), dimension(itel,*), intent(in) :: & ! according to MSC.Marc 2012 Manual D
26524  frotn, & !< rotation tensor at t=n
26525  eigvn, & !< i principal direction components for j eigenvalues at t=n
26526  frotn1, & !< rotation tensor at t=n+1
26527  eigvn1
26528  real(pReal), dimension(ndeg,*), intent(in) :: & ! according to MSC.Marc 2012 Manual D
26529  disp, & !< incremental displacements
26530  dispt
26531  real(pReal), dimension(ncrd,*), intent(in) :: & ! according to MSC.Marc 2012 Manual D
26532  coord
26533  real(pReal), dimension(*), intent(inout) :: & ! according to MSC.Marc 2012 Manual D
26534  t
26535  real(pReal), dimension(ndi+nshear), intent(out) :: & ! has dimension(*) according to MSC.Marc 2012 Manual D, but we need to loop over it
26536  s, & !< stress - should be updated by user
26537  g
26538  real(pReal), dimension(ngens,ngens), intent(out) :: & ! according to MSC.Marc 2012 Manual D, but according to example hypela2.f dimension(ngens,*)
26539  d
26540 
26541 !--------------------------------------------------------------------------------------------------
26542 ! Marc common blocks are in fixed format so they have to be reformated to free format (f90)
26543 ! Beware of changes in newer Marc versions
26544 
26545 
26546 
26547 
26548  logical :: cutBack
26549  real(pReal), dimension(6) :: stress
26550  real(pReal), dimension(6,6) :: ddsdde
26551  integer :: computationMode, i, cp_en, node, CPnodeID
26552  !$ integer(4) :: defaultNumThreadsInt !< default value set by Marc
26553 
26554  if (iand(debug_level(debug_marc),debug_levelbasic) /= 0) then
26555  write(6,'(a,/,i8,i8,i2)') ' MSC.MARC information on shape of element(2), IP:', m, nn
26556  write(6,'(a,2(i1))') ' Jacobian: ', ngens,ngens
26557  write(6,'(a,i1)') ' Direct stress: ', ndi
26558  write(6,'(a,i1)') ' Shear stress: ', nshear
26559  write(6,'(a,i2)') ' DoF: ', ndeg
26560  write(6,'(a,i2)') ' Coordinates: ', ncrd
26561  write(6,'(a,i12)') ' Nodes: ', nnode
26562  write(6,'(a,i1)') ' Deformation gradient: ', itel
26563  write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') ' Deformation gradient at t=n:', &
26564  transpose(ffn)
26565  write(6,'(/,a,/,3(3(f12.7,1x)/))',advance='no') ' Deformation gradient at t=n+1:', &
26566  transpose(ffn1)
26567  endif
26568 
26569  !$ defaultNumThreadsInt = omp_get_num_threads() ! remember number of threads set by Marc
26570 
26571  if (.not. cpfem_init_done) call cpfem_initall(m(1),nn)
26572 
26573  !$ call omp_set_num_threads(DAMASK_NumThreadsInt) ! set number of threads for parallel execution set by DAMASK_NUM_THREADS
26574 
26575  computationmode = 0 ! save initialization value, since it does not result in any calculation
26576  if (lovl == 4 ) then ! jacobian requested by marc
26577  if (timinc < thedelta .and. theinc == inc .and. lastlovl /= lovl) & ! first after cutback
26578  computationmode = cpfem_restorejacobian
26579  elseif (lovl == 6) then ! stress requested by marc
26580  cp_en = mesh_fem2damask_elem(m(1))
26581  if (cptim > thetime .or. inc /= theinc) then ! reached "convergence"
26582  terminallyill = .false.
26583  cyclecounter = -1 ! first calc step increments this to cycle = 0
26584  if (inc == 0) then ! >> start of analysis <<
26585  lastincconverged = .false. ! no Jacobian backup
26586  outdatedbynewinc = .false. ! no aging of state
26587  calcmode = .false. ! pretend last step was collection
26588  lastlovl = lovl ! pretend that this is NOT the first after a lovl change
26589  write(6,'(a,i6,1x,i2)') '<< HYPELA2 >> start of analysis..! ',m(1),nn
26590  flush(6)
26591  else if (inc - theinc > 1) then ! >> restart of broken analysis <<
26592  lastincconverged = .false. ! no Jacobian backup
26593  outdatedbynewinc = .false. ! no aging of state
26594  calcmode = .true. ! pretend last step was calculation
26595  write(6,'(a,i6,1x,i2)') '<< HYPELA2 >> restart of analysis..! ',m(1),nn
26596  flush(6)
26597  else ! >> just the next inc <<
26598  lastincconverged = .true. ! request Jacobian backup
26599  outdatedbynewinc = .true. ! request aging of state
26600  calcmode = .true. ! assure last step was calculation
26601  write(6,'(a,i6,1x,i2)') '<< HYPELA2 >> new increment..! ',m(1),nn
26602  flush(6)
26603  endif
26604  else if ( timinc < thedelta ) then ! >> cutBack <<
26605  lastincconverged = .false. ! no Jacobian backup
26606  outdatedbynewinc = .false. ! no aging of state
26607  terminallyill = .false.
26608  cyclecounter = -1 ! first calc step increments this to cycle = 0
26609  calcmode = .true. ! pretend last step was calculation
26610  write(6,'(a,i6,1x,i2)') '<< HYPELA2 >> cutback detected..! ',m(1),nn
26611  flush(6)
26612  endif ! convergence treatment end
26613 
26614 
26615  if (usepingpong) then
26616  calcmode(nn,cp_en) = .not. calcmode(nn,cp_en) ! ping pong (calc <--> collect)
26617  if (calcmode(nn,cp_en)) then ! now --- CALC ---
26618  computationmode = cpfem_calcresults
26619  if (lastlovl /= lovl) then ! first after ping pong
26620  call debug_reset() ! resets debugging
26621  outdatedffn1 = .false.
26622  cyclecounter = cyclecounter + 1
26623  !mesh_cellnode = mesh_build_cellnodes() ! update cell node coordinates
26624  !call mesh_build_ipCoordinates() ! update ip coordinates
26625  endif
26626  if (outdatedbynewinc) then
26627  computationmode = ior(computationmode,cpfem_ageresults) ! calc and age results
26628  outdatedbynewinc = .false. ! reset flag
26629  endif
26630  else ! now --- COLLECT ---
26631  computationmode = cpfem_collect ! plain collect
26632  if (lastlovl /= lovl .and. & .not. terminallyill) &
26633  call debug_info() ! first after ping pong reports (meaningful) debugging
26634  if (lastincconverged) then
26635  computationmode = ior(computationmode,cpfem_backupjacobian) ! collect and backup Jacobian after convergence
26636  lastincconverged = .false. ! reset flag
26637  endif
26638  !do node = 1,theMesh%elem%nNodes
26639  !CPnodeID = mesh_element(4+node,cp_en)
26640  !mesh_node(1:ndeg,CPnodeID) = mesh_node0(1:ndeg,CPnodeID) + numerics_unitlength * dispt(1:ndeg,node)
26641  !enddo
26642  endif
26643 
26644  else ! --- PLAIN MODE ---
26645  computationmode = cpfem_calcresults ! always calc
26646  if (lastlovl /= lovl) then
26647  if (.not. terminallyill) &
26648  call debug_info() ! first reports (meaningful) debugging
26649  call debug_reset() ! and resets debugging
26650  outdatedffn1 = .false.
26651  cyclecounter = cyclecounter + 1
26652  !mesh_cellnode = mesh_build_cellnodes() ! update cell node coordinates
26653  !call mesh_build_ipCoordinates() ! update ip coordinates
26654  endif
26655  if (outdatedbynewinc) then
26656  computationmode = ior(computationmode,cpfem_ageresults)
26657  outdatedbynewinc = .false. ! reset flag
26658  endif
26659  if (lastincconverged) then
26660  computationmode = ior(computationmode,cpfem_backupjacobian) ! backup Jacobian after convergence
26661  lastincconverged = .false. ! reset flag
26662  endif
26663  endif
26664 
26665  thetime = cptim ! record current starting time
26666  thedelta = timinc ! record current time increment
26667  theinc = inc ! record current increment number
26668 
26669  endif
26670  lastlovl = lovl ! record lovl
26671 
26672  call cpfem_general(computationmode,usepingpong,ffn,ffn1,t(1),timinc,m(1),nn,stress,ddsdde)
26673 
26674  d = ddsdde(1:ngens,1:ngens)
26675  s = stress(1:ndi+nshear)
26676  g = 0.0_preal
26677  if(symmetricsolver) d = 0.5_preal*(d+transpose(d))
26678 
26679  !$ call omp_set_num_threads(defaultNumThreadsInt) ! reset number of threads to stored default value
26680 
26681 end subroutine hypela2
26682 
26683 
26684 !--------------------------------------------------------------------------------------------------
26686 !--------------------------------------------------------------------------------------------------
26687 subroutine flux(f,ts,n,time)
26688  use prec
26689  use thermal_conduction
26691 
26692  implicit none
26693  real(pReal), dimension(6), intent(in) :: &
26694  ts
26695  integer, dimension(10), intent(in) :: &
26696  n
26697  real(pReal), intent(in) :: &
26698  time
26699  real(pReal), dimension(2), intent(out) :: &
26700  f
26701 
26702  call thermal_conduction_getsourceanditstangent(f(1), f(2), ts(3), n(3),mesh_fem2damask_elem(n(1)))
26703 
26704  end subroutine flux
26705 
26706 
26707 !--------------------------------------------------------------------------------------------------
26711 ! same increment multiple times.
26712 !--------------------------------------------------------------------------------------------------
26713 subroutine uedinc(inc,incsub)
26714  use prec
26715  use cpfem
26716 
26717  implicit none
26718  integer, intent(in) :: inc, incsub
26719  integer, save :: inc_written
26721 
26722  if (inc > inc_written) then
26723  call cpfem_results(inc,cptim)
26724  inc_written = inc
26725  endif
26726 
26727 end subroutine uedinc
26728 
lattice::fcc_ncleavagesystem
integer, dimension(1), parameter fcc_ncleavagesystem
Definition: DAMASK_marc.f90:11980
material::thermalmapping
type(thomogmapping), dimension(:), allocatable, public thermalmapping
mapping for thermal state/fields
Definition: DAMASK_marc.f90:11335
discretization::discretization_setipcoords
subroutine, public discretization_setipcoords(IPcoords)
stores current IP coordinates
Definition: DAMASK_marc.f90:10020
material::sourcestate
type(tsourcestate), dimension(:), allocatable, public sourcestate
Definition: DAMASK_marc.f90:11304
element::cell8
integer, dimension(ncellnodepercell(celltype(8)), nip(8)), parameter cell8
Definition: DAMASK_marc.f90:6627
discretization_marc::mesh_unitlength
real(preal), public, protected mesh_unitlength
physical length of one unit in mesh
Definition: DAMASK_marc.f90:10076
geometry_plastic_nonlocal::geometry_plastic_nonlocal_ipareanormal0
real(preal), dimension(:,:,:,:), allocatable, protected geometry_plastic_nonlocal_ipareanormal0
area normal of interface to neighboring IP (initially!)
Definition: DAMASK_marc.f90:9795
material::damage_local_label
character(len= *), parameter, public damage_local_label
Definition: DAMASK_marc.f90:11190
results::results_setlink
subroutine, public results_setlink(path, link)
set link to object in results file
Definition: DAMASK_marc.f90:8944
fesolving::fesolving_execip
integer, dimension(2) fesolving_execip
for ping-pong scheme always range to max IP, otherwise one specific IP
Definition: DAMASK_marc.f90:5905
source_damage_anisobrittle::source_damage_anisobrittle_getrateanditstangent
subroutine, public source_damage_anisobrittle_getrateanditstangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
returns local part of nonlocal damage driving force
Definition: DAMASK_marc.f90:15088
io::io_divider
character(len= *), parameter, private io_divider
Definition: DAMASK_marc.f90:459
element::cellnodeparentnodeweights1
integer, dimension(nnode(1), ncellnode(geomtype(1))), parameter cellnodeparentnodeweights1
Definition: DAMASK_marc.f90:6213
lattice::buildtransformationsystem
subroutine buildtransformationsystem(Q, S, Ntrans, cOverA, a_fcc, a_bcc)
Helper function to define transformation systems.
Definition: DAMASK_marc.f90:14004
source_damage_isoductile::source_damage_isoductile_dotstate
subroutine, public source_damage_isoductile_dotstate(ipc, ip, el)
calculates derived quantities from state
Definition: DAMASK_marc.f90:14831
discretization_marc::inputread_mapelems
subroutine inputread_mapelems(FEM2DAMASK, nElems, nNodesPerElem, fileContent)
Maps elements from FE ID to internal (consecutive) representation.
Definition: DAMASK_marc.f90:10474
discretization_marc::mesh_fem2damask_elem
integer, dimension(:), allocatable, public mesh_fem2damask_elem
DAMASK element ID for Marc element ID.
Definition: DAMASK_marc.f90:10079
quaternions::dot_product
Definition: DAMASK_marc.f90:3893
hdf5_utilities::hdf5_write_real1
subroutine hdf5_write_real1(loc_id, dataset, datasetName, parallel)
write dataset of type real with 1 dimension
Definition: DAMASK_marc.f90:7948
discretization_marc::cellnodedefinition
type(tcellnodedefinition), dimension(:), allocatable cellnodedefinition
Definition: DAMASK_marc.f90:10074
constitutive::constitutive_lpanditstangents
subroutine, public constitutive_lpanditstangents(Lp, dLp_dS, dLp_dFi, S, Fi, ipc, ip, el)
contains the constitutive equation for calculating the velocity gradient
Definition: DAMASK_marc.f90:16289
parallel_id
@ parallel_id
Definition: DAMASK_marc.f90:24965
kinetics_twin
pure subroutine kinetics_twin(Mp, instance, of, gdot_twin, dgdot_dtau_twin)
Calculate shear rates on twin systems and their derivatives with respect to resolved.
Definition: DAMASK_marc.f90:17559
thermal_adiabatic::thermal_adiabatic_init
subroutine, public thermal_adiabatic_init
module initialization
Definition: DAMASK_marc.f90:23353
hdf5_utilities::hdf5_addgroup
integer(hid_t) function hdf5_addgroup(fileHandle, groupName)
adds a new group to the fileHandle
Definition: DAMASK_marc.f90:7036
crystallite_restartwrite
subroutine crystallite_restartwrite
Write current restart information (Field and constitutive data) to file.
Definition: DAMASK_marc.f90:23156
lattice::lattice_interaction_twinbyslip
real(preal) function, dimension(sum(ntwin), sum(nslip)), public lattice_interaction_twinbyslip(Ntwin, Nslip, interactionValues, structure)
Twin-slip interaction matrix details only active twin and slip systems are considered.
Definition: DAMASK_marc.f90:13283
element::cellnodeparentnodeweights9
integer, dimension(nnode(9), ncellnode(geomtype(9))), parameter cellnodeparentnodeweights9
Definition: DAMASK_marc.f90:6355
list::add
subroutine add(this, string)
add element
Definition: DAMASK_marc.f90:1705
io::io_gettag
pure character(len=:) function, allocatable, public io_gettag(string, openChar, closeChar)
get tagged content of string
Definition: DAMASK_marc.f90:611
material::material_phaseat
integer, dimension(:,:), allocatable, public, protected material_phaseat
phase ID of each element
Definition: DAMASK_marc.f90:11297
hdf5_utilities::hdf5_read_int4
subroutine hdf5_read_int4(loc_id, dataset, datasetName, parallel)
read dataset of type integer withh 4 dimensions
Definition: DAMASK_marc.f90:7787
material::phase_elasticityinstance
integer, dimension(:), allocatable, public, protected phase_elasticityinstance
instance of particular elasticity of each phase
Definition: DAMASK_marc.f90:11278
numerics::charlength
real(preal), public, protected charlength
characteristic length scale for gradient problems
Definition: DAMASK_marc.f90:1158
hdf5_utilities::hdf5_write_int7
subroutine hdf5_write_int7(loc_id, dataset, datasetName, parallel)
write dataset of type integer with 7 dimensions
Definition: DAMASK_marc.f90:8483
kinematics_thermal_expansion::kinematics_thermal_expansion_lianditstangent
subroutine, public kinematics_thermal_expansion_lianditstangent(Li, dLi_dTstar, ipc, ip, el)
contains the constitutive equation for calculating the velocity gradient
Definition: DAMASK_marc.f90:15791
lattice::lattice_interaction_slipbytwin
real(preal) function, dimension(sum(nslip), sum(ntwin)), public lattice_interaction_slipbytwin(Nslip, Ntwin, interactionValues, structure)
Slip-twin interaction matrix details only active slip and twin systems are considered.
Definition: DAMASK_marc.f90:13087
discretization_marc::ipvolume
real(preal) function, dimension(elem%nips, size(connectivity, 3)) ipvolume(elem, node, connectivity)
Calculates IP volume.
Definition: DAMASK_marc.f90:10988
io::verifyintvalue
integer function verifyintvalue(string)
returns verified integer value in given string
Definition: DAMASK_marc.f90:1056
kinematics_cleavage_opening::kinematics_cleavage_opening_init
subroutine, public kinematics_cleavage_opening_init
module initialization
Definition: DAMASK_marc.f90:15373
source_damage_anisobrittle::source_damage_anisobrittle_offset
integer, dimension(:), allocatable source_damage_anisobrittle_offset
which source is my current source mechanism?
Definition: DAMASK_marc.f90:14931
lattice::buildcoordinatesystem
real(preal) function, dimension(3, 3, sum(active)) buildcoordinatesystem(active, potential, system, structure, cOverA)
Build a local coordinate system on slip, twin, trans, cleavage systems.
Definition: DAMASK_marc.f90:13933
prec::unittest
subroutine, private unittest
check correctness of some prec functions
Definition: DAMASK_marc.f90:280
source_damage_isobrittle
material subroutine incoprorating isotropic brittle damage source mechanism
Definition: DAMASK_marc.f90:14533
prec::deq
logical elemental pure function deq(a, b, tol)
equality comparison for float with double precision
Definition: DAMASK_marc.f90:152
debug::debug_init
subroutine, public debug_init
reads in parameters from debug.config and allocates arrays
Definition: DAMASK_marc.f90:1459
math::math_expand
pure real(preal) function, dimension(sum(how)) math_expand(what, how)
vector expansion
Definition: DAMASK_marc.f90:2669
numerics::numerics_integrator
integer, public, protected numerics_integrator
method used for state integration Default 1: fix-point iteration
Definition: DAMASK_marc.f90:1150
hdf5_utilities::hdf5_read_int7
subroutine hdf5_read_int7(loc_id, dataset, datasetName, parallel)
read dataset of type integer with 7 dimensions
Definition: DAMASK_marc.f90:7907
discretization_marc::inputread_nnodesandelements
subroutine inputread_nnodesandelements(nNodes, nElems, fileContent)
Count overall number of nodes and elements.
Definition: DAMASK_marc.f90:10366
homogenization::materialpoint_subdt
real(preal), dimension(:,:), allocatable materialpoint_subdt
Definition: DAMASK_marc.f90:24315
quaternions::p
real(preal), parameter, public p
parameter for orientation conversion.
Definition: DAMASK_marc.f90:3833
rotations
rotation storage and conversion
Definition: DAMASK_marc.f90:4604
future
New fortran functions for compiler versions that do not support them.
Definition: DAMASK_marc.f90:2114
constitutive::constitutive_collectdotstate
subroutine, public constitutive_collectdotstate(S, FArray, Fi, FpArray, subdt, ipc, ip, el)
contains the constitutive equation for calculating the rate of change of microstructure
Definition: DAMASK_marc.f90:16544
damage_nonlocal
material subroutine for non-locally evolving damage field
Definition: DAMASK_marc.f90:24054
io::io_stringpos
pure integer function, dimension(:), allocatable, public io_stringpos(string)
locates all whitespace-separated chunks in given string and returns array containing number them and ...
Definition: DAMASK_marc.f90:640
debug::debug_spectraldivergence
integer, parameter, public debug_spectraldivergence
Definition: DAMASK_marc.f90:1400
lattice::bct_nslipsystem
integer, dimension(13), parameter bct_nslipsystem
Definition: DAMASK_marc.f90:12233
io::io_read_ascii
character(len=pstringlen) function, dimension(:), allocatable, public io_read_ascii(fileName)
reads an entire ASCII file into an array
Definition: DAMASK_marc.f90:497
lambert::lambert_balltocube
pure real(preal) function, dimension(3), public lambert_balltocube(xyz)
map from 3D ball to 3D cubic grid
Definition: DAMASK_marc.f90:4479
element::cellnodeparentnodeweights5
integer, dimension(nnode(5), ncellnode(geomtype(5))), parameter cellnodeparentnodeweights5
Definition: DAMASK_marc.f90:6280
rotations::ho2ax
pure real(preal) function, dimension(4) ho2ax(ho)
convert homochoric to axis angle pair
Definition: DAMASK_marc.f90:5632
element::ipneighbor1
integer, dimension(nipneighbor(celltype(1)), nip(1)), parameter ipneighbor1
Definition: DAMASK_marc.f90:6068
homogenization::materialpoint_dpdf
real(preal), dimension(:,:,:,:,:,:), allocatable, public materialpoint_dpdf
tangent of first P–K stress at IP
Definition: DAMASK_marc.f90:24309
discretization_marc::continuousintvalues
integer function, dimension(1+maxn) continuousintvalues(fileContent, maxN, lookupName, lookupMap, lookupMaxN)
return integer list corresponding to items in consecutive lines. First integer in array is counter
Definition: DAMASK_marc.f90:11097
discretization_marc::inputread_tablestyles
subroutine inputread_tablestyles(initialcond, hypoelastic, fileContent)
Figures out table styles for initial cond and hypoelastic.
Definition: DAMASK_marc.f90:10302
crystallite_orientations
subroutine crystallite_orientations
calculates orientations
Definition: DAMASK_marc.f90:21972
rotations::ax2eu
pure real(preal) function, dimension(3) ax2eu(ax)
convert axis angle pair to Euler angles
Definition: DAMASK_marc.f90:5419
lattice::lattice_bcc_id
@, public lattice_bcc_id
Definition: DAMASK_marc.f90:12341
material::source_damage_isoductile_id
@, public source_damage_isoductile_id
Definition: DAMASK_marc.f90:11252
prec::emptyrealarray
real(preal), dimension(0), parameter emptyrealarray
Definition: DAMASK_marc.f90:115
integratestateeuler
subroutine integratestateeuler
integrate state with 1st order explicit Euler method
Definition: DAMASK_marc.f90:22544
homogenization::materialpoint_p
real(preal), dimension(:,:,:,:), allocatable, public materialpoint_p
first P–K stress of IP
Definition: DAMASK_marc.f90:24305
source_damage_anisoductile::source_damage_anisoductile_instance
integer, dimension(:), allocatable source_damage_anisoductile_instance
instance of damage source mechanism
Definition: DAMASK_marc.f90:15156
element::telement
Properties of a single element.
Definition: DAMASK_marc.f90:5931
source_damage_isobrittle::source_damage_isobrittle_offset
integer, dimension(:), allocatable source_damage_isobrittle_offset
Definition: DAMASK_marc.f90:14546
source_damage_isoductile
material subroutine incoprorating isotropic ductile damage source mechanism
Definition: DAMASK_marc.f90:14734
math::math_symmetric33
pure real(preal) function, dimension(3, 3) math_symmetric33(m)
symmetrize a 3x3 matrix
Definition: DAMASK_marc.f90:3008
material::damagemapping
type(thomogmapping), dimension(:), allocatable, public damagemapping
mapping for damage state/fields
Definition: DAMASK_marc.f90:11335
math::invnrmmandel
real(preal), dimension(6), parameter, private invnrmmandel
backward weighting for Mandel notation
Definition: DAMASK_marc.f90:2506
prec::tol_math_check
real(preal), parameter tol_math_check
tolerance for internal math self-checks (rotation)
Definition: DAMASK_marc.f90:59
results::results_addattribute_real_array
subroutine results_addattribute_real_array(attrLabel, attrValue, path)
adds a real array attribute an object in the results file
Definition: DAMASK_marc.f90:9027
homogenization::materialpoint_converged
logical, dimension(:,:), allocatable materialpoint_converged
Definition: DAMASK_marc.f90:24319
quaternions::mul_scal__
type(quaternion) elemental pure function mul_scal__(self, scal)
multiply with a scalar
Definition: DAMASK_marc.f90:4051
material::plasticity_isotropic_label
character(len= *), parameter, public plasticity_isotropic_label
Definition: DAMASK_marc.f90:11190
rotations::om2ro
pure real(preal) function, dimension(4) om2ro(om)
convert rotation matrix to Rodrigues vector
Definition: DAMASK_marc.f90:5186
element::cellnodeparentnodeweights7
integer, dimension(nnode(7), ncellnode(geomtype(7))), parameter cellnodeparentnodeweights7
Definition: DAMASK_marc.f90:6309
lattice::lattice_damagediffusion
real(preal), dimension(:,:,:), allocatable, public, protected lattice_damagediffusion
Definition: DAMASK_marc.f90:12350
graindeformation
subroutine graindeformation(F, avgF, instance, of)
calculating the grain deformation gradient (the same with
Definition: DAMASK_marc.f90:25831
material::plasticity_kinehardening_label
character(len= *), parameter, public plasticity_kinehardening_label
Definition: DAMASK_marc.f90:11190
hdf5_utilities::hdf5_addattribute_str
subroutine hdf5_addattribute_str(loc_id, attrLabel, attrValue, path)
adds a string attribute to the path given relative to the location
Definition: DAMASK_marc.f90:7147
element::nnode
integer, dimension(nelemtype), parameter nnode
number of nodes that constitute a specific type of element
Definition: DAMASK_marc.f90:5960
prec::plongint
integer, parameter plongint
number with at least up to +-1e18 (typically 64 bit)
Definition: DAMASK_marc.f90:55
lambert
Mapping homochoric <-> cubochoric.
Definition: DAMASK_marc.f90:4391
thermal_isothermal::thermal_isothermal_init
subroutine thermal_isothermal_init
allocates all neccessary fields, reads information from material configuration file
Definition: DAMASK_marc.f90:23284
lattice::lattice_c66
real(preal), dimension(:,:,:), allocatable, public, protected lattice_c66
Definition: DAMASK_marc.f90:12350
debug::debug_info
subroutine, public debug_info
writes debug statements to standard out
Definition: DAMASK_marc.f90:1634
kinematics_thermal_expansion::kinematics_thermal_expansion_initialstrain
pure real(preal) function, dimension(3, 3), public kinematics_thermal_expansion_initialstrain(homog, phase, offset)
report initial thermal strain based on current temperature deviation from reference
Definition: DAMASK_marc.f90:15768
math::math_binomial
integer pure function math_binomial(n, k)
binomial coefficient
Definition: DAMASK_marc.f90:3594
homogenization::materialpoint_substep
real(preal), dimension(:,:), allocatable materialpoint_substep
Definition: DAMASK_marc.f90:24315
quaternions::exp
Definition: DAMASK_marc.f90:3901
damage_nonlocal::damage_nonlocal_init
subroutine, public damage_nonlocal_init
module initialization
Definition: DAMASK_marc.f90:24093
qsort_partition
integer function qsort_partition(a, istart, iend, sort)
Partitioning required for quicksort.
Definition: DAMASK_marc.f90:2630
material::material_phasememberat
integer, dimension(:,:,:), allocatable, public, protected material_phasememberat
position of the element within its phase instance
Definition: DAMASK_marc.f90:11299
list::show
subroutine show(this)
prints all elements
Definition: DAMASK_marc.f90:1729
lattice::lattice_schmidmatrix_twin
real(preal) function, dimension(3, 3, sum(ntwin)), public lattice_schmidmatrix_twin(Ntwin, structure, cOverA)
Schmid matrix for twinning details only active twin systems are considered.
Definition: DAMASK_marc.f90:13413
source_damage_anisobrittle::source_damage_anisobrittle_instance
integer, dimension(:), allocatable source_damage_anisobrittle_instance
instance of source mechanism
Definition: DAMASK_marc.f90:14931
constitutive::constitutive_plasticity_maxsizedotstate
integer, public, protected constitutive_plasticity_maxsizedotstate
Definition: DAMASK_marc.f90:15863
results::results_closejobfile
subroutine, public results_closejobfile
closes the results file
Definition: DAMASK_marc.f90:8868
lattice::fcc_ntrans
integer, parameter fcc_ntrans
total # of transformation systems for fcc
Definition: DAMASK_marc.f90:11983
source_thermal_dissipation::source_thermal_dissipation_instance
integer, dimension(:), allocatable source_thermal_dissipation_instance
instance of thermal dissipation source mechanism
Definition: DAMASK_marc.f90:14296
volumepenalty
subroutine volumepenalty(vPen, vDiscrep, fAvg, fDef, nGrain, instance, of)
calculate stress-like penalty due to volume discrepancy
Definition: DAMASK_marc.f90:25717
quaternions::eq__
logical elemental pure function eq__(self, other)
test equality
Definition: DAMASK_marc.f90:4089
math::math_voigt66to3333
pure real(preal) function, dimension(3, 3, 3, 3) math_voigt66to3333(m66)
convert 66 Voigt matrix into symmetric 3x3x3x3 matrix
Definition: DAMASK_marc.f90:3296
io::io_error
subroutine, public io_error(error_ID, el, ip, g, instance, ext_msg)
write error statements to standard out and terminate the Marc/spectral run with exit #9xxx
Definition: DAMASK_marc.f90:741
hdf5_utilities::hdf5_closegroup
subroutine hdf5_closegroup(group_id)
close a group
Definition: DAMASK_marc.f90:7105
rotations::rotvector
pure real(preal) function, dimension(3) rotvector(self, v, active)
rotate a vector passively (default) or actively
Definition: DAMASK_marc.f90:4825
rotations::rottensor2
pure real(preal) function, dimension(3, 3) rottensor2(self, T, active)
rotate a rank-2 tensor passively (default) or actively
Definition: DAMASK_marc.f90:4862
kinematics_cleavage_opening
material subroutine incorporating kinematics resulting from opening of cleavage planes
Definition: DAMASK_marc.f90:15333
prec::ppathlen
integer, parameter ppathlen
maximum length of a path name on linux
Definition: DAMASK_marc.f90:57
thermal_adiabatic::thermal_adiabatic_getsourceanditstangent
subroutine, public thermal_adiabatic_getsourceanditstangent(Tdot, dTdot_dT, T, ip, el)
returns heat generation rate
Definition: DAMASK_marc.f90:23430
hdf5_utilities::hdf5_addattribute
attached attributes of type char, integer or real to a file/dataset/group
Definition: DAMASK_marc.f90:6930
lattice::bct_nslip
integer, parameter bct_nslip
total # of slip systems for bct
Definition: DAMASK_marc.f90:12236
rotations::rotation
Definition: DAMASK_marc.f90:4614
prec::thomogmapping
Definition: DAMASK_marc.f90:106
rotations::asaxisangle
pure real(preal) function, dimension(4) asaxisangle(self)
Definition: DAMASK_marc.f90:4679
element::cell1
integer, dimension(ncellnodepercell(celltype(1)), nip(1)), parameter cell1
Definition: DAMASK_marc.f90:6543
source_thermal_externalheat::source_thermal_externalheat_dotstate
subroutine, public source_thermal_externalheat_dotstate(phase, of)
rate of change of state
Definition: DAMASK_marc.f90:14473
debug::debug_i
integer, public, protected debug_i
Definition: DAMASK_marc.f90:1426
discretization_marc::inputread
subroutine inputread(elem, node0_elem, connectivity_elem, microstructureAt, homogenizationAt)
Read mesh from marc input file.
Definition: DAMASK_marc.f90:10214
debug::debug_mesh
integer, parameter, public debug_mesh
stores debug level for mesh part of DAMASK bitwise coded
Definition: DAMASK_marc.f90:1407
quaternions::abs__
real(preal) elemental pure function abs__(self)
return norm
Definition: DAMASK_marc.f90:4180
rotations::asrodrigues
pure real(preal) function, dimension(4) asrodrigues(self)
Definition: DAMASK_marc.f90:4697
material::source_damage_isobrittle_id
@, public source_damage_isobrittle_id
Definition: DAMASK_marc.f90:11252
lattice::bcc_ncleavagesystem
integer, dimension(1), parameter bcc_ncleavagesystem
Definition: DAMASK_marc.f90:12068
config::config_phase
type(tpartitionedstringlist), dimension(:), allocatable, public, protected config_phase
Definition: DAMASK_marc.f90:2166
hdf5_utilities::finalize_read
subroutine finalize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id)
closes HDF5 handles
Definition: DAMASK_marc.f90:8665
material::source_thermal_dissipation_id
@, public source_thermal_dissipation_id
Definition: DAMASK_marc.f90:11252
material::kinematics_thermal_expansion_id
@, public kinematics_thermal_expansion_id
Definition: DAMASK_marc.f90:11252
lambert::a
real(preal), parameter a
Definition: DAMASK_marc.f90:4398
io::io_eol
character, parameter, public io_eol
end of line character
Definition: DAMASK_marc.f90:456
geometry_plastic_nonlocal::geometry_plastic_nonlocal_setipneighborhood
subroutine geometry_plastic_nonlocal_setipneighborhood(IPneighborhood)
Set the integration point (IP) neighborhood.
Definition: DAMASK_marc.f90:9810
select_rotations
type(rotation) function, dimension(:), allocatable select_rotations(dataset, instance)
select rotations for output
Definition: DAMASK_marc.f90:22124
lattice::bct_systemslip
real(preal), dimension(3+3, bct_nslip), parameter bct_systemslip
slip systems for bct sorted by Bieler
Definition: DAMASK_marc.f90:12243
hdf5_utilities::hdf5_read_int1
subroutine hdf5_read_int1(loc_id, dataset, datasetName, parallel)
read dataset of type integer with 1 dimension
Definition: DAMASK_marc.f90:7666
quaternions::log__
type(quaternion) elemental pure function log__(a)
take logarithm
Definition: DAMASK_marc.f90:4160
homogenization::materialpoint_f0
real(preal), dimension(:,:,:,:), allocatable, public materialpoint_f0
def grad of IP at start of FE increment
Definition: DAMASK_marc.f90:24305
element::telement_init
subroutine telement_init(self, elemType)
define properties of an element
Definition: DAMASK_marc.f90:6745
rotations::cu2om
pure real(preal) function, dimension(3, 3) cu2om(cu)
convert cubochoric to rotation matrix
Definition: DAMASK_marc.f90:5714
discretization_marc::inputread_matnumber
subroutine inputread_matnumber(matNumber, tableStyle, fileContent)
Figures out material number of hypoelastic material.
Definition: DAMASK_marc.f90:10330
hypela2
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)
This is the MSC.Marc user subroutine for defining material behavior.
Definition: DAMASK_marc.f90:26491
results::results_addattribute
Definition: DAMASK_marc.f90:8804
debug::debug_level
integer, dimension(debug_maxntype+2), public, protected debug_level
Definition: DAMASK_marc.f90:1423
element::nipneighbor
integer, dimension(maxval(celltype)), parameter nipneighbor
number of ip neighbors / cell faces
Definition: DAMASK_marc.f90:6038
math::math_outer
pure real(preal) function, dimension(size(a, 1), size(b, 1)) math_outer(A, B)
outer product of arbitrary sized vectors (A ⊗ B / i,j)
Definition: DAMASK_marc.f90:2789
lattice::lattice_specificheat
real(preal), dimension(:), allocatable, public, protected lattice_specificheat
Definition: DAMASK_marc.f90:12345
damper
real(preal) pure function damper(current, previous, previous2)
calculate the damping for correction of state and dot state
Definition: DAMASK_marc.f90:22521
material::material_allocateplasticstate
subroutine, public material_allocateplasticstate(phase, NipcMyPhase, sizeState, sizeDotState, sizeDeltaState)
allocates the plastic state of a phase
Definition: DAMASK_marc.f90:11876
element::cellnodeparentnodeweights4
integer, dimension(nnode(4), ncellnode(geomtype(4))), parameter cellnodeparentnodeweights4
Definition: DAMASK_marc.f90:6256
lc
character(len=len(string)) function lc(string)
changes characters in string to lower case
Definition: DAMASK_marc.f90:411
geometry_plastic_nonlocal::geometry_plastic_nonlocal_ipvolume0
real(preal), dimension(:,:), allocatable, protected geometry_plastic_nonlocal_ipvolume0
volume associated with IP (initially!)
Definition: DAMASK_marc.f90:9789
material::source_thermal_externalheat_label
character(len= *), parameter, public source_thermal_externalheat_label
Definition: DAMASK_marc.f90:11190
fesolving::calcmode
logical, dimension(:,:), allocatable calcmode
do calculation or simply collect when using ping pong scheme
Definition: DAMASK_marc.f90:5910
select_tensors
real(preal) function, dimension(:,:,:), allocatable select_tensors(dataset, instance)
select tensors for output
Definition: DAMASK_marc.f90:22097
lattice::hex_ntwin
integer, parameter hex_ntwin
total # of twin systems for hex
Definition: DAMASK_marc.f90:12146
math::math_99to3333
pure real(preal) function, dimension(3, 3, 3, 3) math_99to3333(m99)
convert 9x9 matrix into 3x3x3x3 matrix
Definition: DAMASK_marc.f90:3220
integratestaterkck45
subroutine integratestaterkck45
integrate stress, state with 5th order Runge-Kutta Cash-Karp method with adaptive step size (use 5th ...
Definition: DAMASK_marc.f90:22893
source_damage_isoductile::source_damage_isoductile_results
subroutine, public source_damage_isoductile_results(phase, group)
writes results to HDF5 output file
Definition: DAMASK_marc.f90:14889
lattice::equivalent_nu
real(preal) function equivalent_nu(C, assumption)
Equivalent Poisson's ratio (ν)
Definition: DAMASK_marc.f90:14185
lattice::fcc_nslip
integer, parameter fcc_nslip
total # of slip systems for fcc
Definition: DAMASK_marc.f90:11983
material::phase_plasticity
integer(kind(plasticity_undefined_id)), dimension(:), allocatable, public, protected phase_plasticity
plasticity of each phase
Definition: DAMASK_marc.f90:11257
hdf5_utilities::hdf5_write_real3
subroutine hdf5_write_real3(loc_id, dataset, datasetName, parallel)
write dataset of type real with 3 dimensions
Definition: DAMASK_marc.f90:8030
lambert::sc
real(preal), parameter sc
Definition: DAMASK_marc.f90:4398
homogenization::homogenization_init
subroutine, public homogenization_init
module initialization
Definition: DAMASK_marc.f90:24415
rotations::fromaxisangle
subroutine fromaxisangle(self, ax, degrees, P)
Definition: DAMASK_marc.f90:4751
io::io_comment
character, parameter, public io_comment
Definition: DAMASK_marc.f90:456
results::results_opengroup
integer(hid_t) function, public results_opengroup(groupName)
open a group from the results file
Definition: DAMASK_marc.f90:8908
numerics::residualstiffness
real(preal), public, protected residualstiffness
non-zero residual damage
Definition: DAMASK_marc.f90:1158
results::results_mapping_materialpoint
subroutine, public results_mapping_materialpoint(homogenizationAt, memberAtLocal, label)
adds the unique mapping from spatial position and constituent ID to results
Definition: DAMASK_marc.f90:9385
math::math_3333to99
pure real(preal) function, dimension(9, 9) math_3333to99(m3333)
convert 3x3x3x3 matrix into 9x9 matrix
Definition: DAMASK_marc.f90:3203
source_thermal_dissipation
material subroutine for thermal source due to plastic dissipation
Definition: DAMASK_marc.f90:14286
material::thermal_adiabatic_id
@, public thermal_adiabatic_id
Definition: DAMASK_marc.f90:11252
element::ncellnodepercellface
integer, dimension(maxval(celltype)), parameter ncellnodepercellface
number of cell nodes per face
Definition: DAMASK_marc.f90:6046
math::math_identity2nd
pure real(preal) function, dimension(d, d) math_identity2nd(d)
second rank identity tensor of specified dimension
Definition: DAMASK_marc.f90:2702
numerics::err_thermal_tolrel
real(preal), public, protected err_thermal_tolrel
relative tolerance for thermal equilibrium
Definition: DAMASK_marc.f90:1168
io::io_init
subroutine, public io_init
does nothing.
Definition: DAMASK_marc.f90:485
material::plasticity_isotropic_id
@, public plasticity_isotropic_id
Definition: DAMASK_marc.f90:11252
material::material_parsetexture
subroutine material_parsetexture
parses the texture part in the material configuration file
Definition: DAMASK_marc.f90:11809
crystallite_forward
subroutine crystallite_forward
Forward data after successful increment.
Definition: DAMASK_marc.f90:23238
homogenization::materialpoint_subfrac
real(preal), dimension(:,:), allocatable materialpoint_subfrac
Definition: DAMASK_marc.f90:24315
rotations::asmatrix
pure real(preal) function, dimension(3, 3) asmatrix(self)
Definition: DAMASK_marc.f90:4688
prec::emptystringarray
character(len=pstringlen), dimension(0), parameter emptystringarray
Definition: DAMASK_marc.f90:117
discretization_marc::inputread_elemtype
subroutine inputread_elemtype(elem, nElem, fileContent)
Gets element type (and checks if the whole mesh comprises of only one type)
Definition: DAMASK_marc.f90:10587
results::results_init
subroutine, public results_init
Definition: DAMASK_marc.f90:8833
math::indeg
real(preal), parameter indeg
conversion from radian into degree
Definition: DAMASK_marc.f90:2490
debug::debug_stressminlocation
integer, dimension(2), public debug_stressminlocation
Definition: DAMASK_marc.f90:1431
uniquerows
pure integer function uniquerows(A)
count unique rows (same rows need to be stored consecutively)
Definition: DAMASK_marc.f90:10903
hdf5_utilities
Definition: DAMASK_marc.f90:6865
hdf5_utilities::hdf5_write_int6
subroutine hdf5_write_int6(loc_id, dataset, datasetName, parallel)
write dataset of type integer with 6 dimensions
Definition: DAMASK_marc.f90:8442
material::damage_nonlocal_id
@, public damage_nonlocal_id
Definition: DAMASK_marc.f90:11252
lattice::ort_systemcleavage
real(preal), dimension(3+3, ort_ncleavage), parameter ort_systemcleavage
Definition: DAMASK_marc.f90:12325
rotations::ho2qu
pure real(preal) function, dimension(4) ho2qu(ho)
convert homochoric to unit quaternion
Definition: DAMASK_marc.f90:5590
numerics::randomseed
integer, public, protected randomseed
fixed seeding for pseudo-random number generator, Default 0: use random seed
Definition: DAMASK_marc.f90:1150
lattice::bcc_ncleavage
integer, parameter bcc_ncleavage
total # of cleavage systems for bcc
Definition: DAMASK_marc.f90:12071
lattice::lattice_forestprojection_edge
Definition: DAMASK_marc.f90:12358
damage_local
material subroutine for locally evolving damage field
Definition: DAMASK_marc.f90:23870
quaternions::pos__
type(quaternion) elemental pure function pos__(self)
return (unary positive operator)
Definition: DAMASK_marc.f90:3999
list::free
subroutine free(this)
empties list and frees associated memory
Definition: DAMASK_marc.f90:1747
material::plasticity_dislotwin_id
@, public plasticity_dislotwin_id
Definition: DAMASK_marc.f90:11252
list::getstrings
character(len=pstringlen) function, dimension(:), allocatable getstrings(this, key, defaultVal, raw)
gets array of string values of for a given key from a linked list
Definition: DAMASK_marc.f90:2039
hdf5_utilities::hdf5_openfile
integer(hid_t) function hdf5_openfile(fileName, mode, parallel)
open and initializes HDF5 output file
Definition: DAMASK_marc.f90:6973
lambert::ap
real(preal), parameter ap
Definition: DAMASK_marc.f90:4398
material::temperature
type(group_float), dimension(:), allocatable, public temperature
temperature field
Definition: DAMASK_marc.f90:11339
math::math_sym3333to66
pure real(preal) function, dimension(6, 6) math_sym3333to66(m3333, weighted)
convert symmetric 3x3x3x3 matrix into 6x6 matrix
Definition: DAMASK_marc.f90:3240
stateinit
subroutine stateinit(ini, phase, NipcMyPhase)
material subroutine for plasticity including dislocation flux
Definition: DAMASK_marc.f90:21165
thermal_adiabatic
material subroutine for adiabatic temperature evolution
Definition: DAMASK_marc.f90:23315
constitutive::constitutive_dependentstate
subroutine, public constitutive_dependentstate(F, Fp, ipc, ip, el)
calls microstructure function of the different constitutive models
Definition: DAMASK_marc.f90:16252
discretization_marc::mesh_fem2damask_node
integer, dimension(:), allocatable, public mesh_fem2damask_node
DAMASK node ID for Marc node ID.
Definition: DAMASK_marc.f90:10079
kinematics_thermal_expansion::kinematics_thermal_expansion_init
subroutine, public kinematics_thermal_expansion_init
module initialization
Definition: DAMASK_marc.f90:15725
rotations::fromquaternion
subroutine fromquaternion(self, qu)
Definition: DAMASK_marc.f90:4718
source_damage_anisobrittle::source_damage_anisobrittle_init
subroutine, public source_damage_anisobrittle_init
module initialization
Definition: DAMASK_marc.f90:14967
config::config_crystallite
type(tpartitionedstringlist), dimension(:), allocatable, public, protected config_crystallite
Definition: DAMASK_marc.f90:2166
element::ipneighbor10
integer, dimension(nipneighbor(celltype(10)), nip(10)), parameter ipneighbor10
Definition: DAMASK_marc.f90:6177
homogenization::materialpoint_f
real(preal), dimension(:,:,:,:), allocatable, public materialpoint_f
def grad of IP to be reached at end of FE increment
Definition: DAMASK_marc.f90:24305
cpfem_results
subroutine cpfem_results(inc, time)
Trigger writing of results.
Definition: DAMASK_marc.f90:26460
rotations::misorientation
pure elemental type(rotation) function misorientation(self, other)
misorientation
Definition: DAMASK_marc.f90:4942
list::getints
integer function, dimension(:), allocatable getints(this, key, defaultVal, requiredSize)
gets array of integer values of for a given key from a linked list
Definition: DAMASK_marc.f90:1993
source_damage_isoductile::source_damage_isoductile_init
subroutine, public source_damage_isoductile_init
module initialization
Definition: DAMASK_marc.f90:14775
math::math_spherical33
pure real(preal) function, dimension(3, 3) math_spherical33(m)
hydrostatic part of a 3x3 matrix
Definition: DAMASK_marc.f90:3047
config::config_name_phase
character(len=pstringlen), dimension(:), allocatable, public, protected config_name_phase
name of each phase
Definition: DAMASK_marc.f90:2177
crystallite_push33toref
real(preal) function, dimension(3, 3) crystallite_push33toref(ipc, ip, el, tensor33)
Map 2nd order tensor to reference config.
Definition: DAMASK_marc.f90:22004
math::math_33to9
pure real(preal) function, dimension(9) math_33to9(m33)
convert 3x3 matrix into vector 9
Definition: DAMASK_marc.f90:3112
element::ipneighbor8
integer, dimension(nipneighbor(celltype(8)), nip(8)), parameter ipneighbor8
Definition: DAMASK_marc.f90:6152
parse_debugandnumericsconfig
subroutine parse_debugandnumericsconfig(config_list, fileContent)
parses the material.config file
Definition: DAMASK_marc.f90:2415
homogenization::num
type(tnumerics) num
Definition: DAMASK_marc.f90:24334
discretization::discretization_setnodecoords
subroutine, public discretization_setnodecoords(NodeCoords)
stores current IP coordinates
Definition: DAMASK_marc.f90:10032
lattice::getlabels
character(len=:) function, dimension(:), allocatable getlabels(active, potential, system)
select active systems as strings
Definition: DAMASK_marc.f90:14128
numerics::worldsize
integer, public, protected worldsize
MPI worldsize (/=1 for MPI simulations only)
Definition: DAMASK_marc.f90:1150
math::math_eigvalsh
real(preal) function, dimension(size(m, 1)) math_eigvalsh(m)
Eigenvalues of symmetric matrix.
Definition: DAMASK_marc.f90:3508
rotations::cu2ro
pure real(preal) function, dimension(4) cu2ro(cu)
convert cubochoric to Rodrigues vector
Definition: DAMASK_marc.f90:5756
thermal_conduction::thermal_conduction_getmassdensity
real(preal) function, public thermal_conduction_getmassdensity(ip, el)
returns homogenized mass density
Definition: DAMASK_marc.f90:23752
math::inrad
real(preal), parameter inrad
conversion from degree into radian
Definition: DAMASK_marc.f90:2491
mapelemtype
integer function mapelemtype(what)
mapping of Marc element types to internal representation
Definition: DAMASK_marc.f90:10626
debug::debug_reset
subroutine, public debug_reset
resets all debug values
Definition: DAMASK_marc.f90:1617
list::getint
integer function getint(this, key, defaultVal)
gets integer value of for a given key from a linked list
Definition: DAMASK_marc.f90:1869
prec::preal_epsilon
real(preal), parameter, private preal_epsilon
minimum positive number such that 1.0 + EPSILON /= 1.0.
Definition: DAMASK_marc.f90:110
material::damage_initialphi
real(preal), dimension(:), allocatable, public, protected damage_initialphi
initial damage per each homogenization
Definition: DAMASK_marc.f90:11289
element::ipneighbor4
integer, dimension(nipneighbor(celltype(4)), nip(4)), parameter ipneighbor4
Definition: DAMASK_marc.f90:6100
quaternions::unittest
subroutine unittest
check correctness of some quaternions functions
Definition: DAMASK_marc.f90:4279
material
Parses material config file, either solverJobName.materialConfig or material.config.
Definition: DAMASK_marc.f90:11176
list::countkeys
integer function countkeys(this, key)
count number of key appearances
Definition: DAMASK_marc.f90:1814
element::cellnodeparentnodeweights13
integer, dimension(nnode(13), ncellnode(geomtype(13))), parameter cellnodeparentnodeweights13
Definition: DAMASK_marc.f90:6470
hdf5_utilities::hdf5_read_int2
subroutine hdf5_read_int2(loc_id, dataset, datasetName, parallel)
read dataset of type integer with 2 dimensions
Definition: DAMASK_marc.f90:7707
thermal_conduction::thermal_conduction_results
subroutine, public thermal_conduction_results(homog, group)
writes results to HDF5 output file
Definition: DAMASK_marc.f90:23802
rotations::ax2ho
pure real(preal) function, dimension(3) ax2ho(ax)
convert axis angle pair to homochoric
Definition: DAMASK_marc.f90:5455
material::homogenization_maxngrains
integer, public, protected homogenization_maxngrains
max number of grains in any USED homogenization
Definition: DAMASK_marc.f90:11275
source_thermal_externalheat::source_thermal_externalheat_getrateanditstangent
subroutine, public source_thermal_externalheat_getrateanditstangent(TDot, dTDot_dT, phase, of)
returns local heat generation rate
Definition: DAMASK_marc.f90:14492
homogenization::homogenization_results
subroutine, public homogenization_results
writes homogenization results to HDF5 output file
Definition: DAMASK_marc.f90:24858
material::material_orientation0
type(rotation), dimension(:,:,:), allocatable, public, protected material_orientation0
initial orientation of each grain,IP,element
Definition: DAMASK_marc.f90:11314
quaternions::div_scal__
type(quaternion) elemental pure function div_scal__(self, scal)
divide by a scalar
Definition: DAMASK_marc.f90:4076
material::microstructure_phase
integer, dimension(:,:), allocatable, private microstructure_phase
phase IDs of each microstructure
Definition: DAMASK_marc.f90:11323
material::texture_orientation
type(rotation), dimension(:), allocatable, private texture_orientation
Euler angles in material.config (possibly rotated for alignment)
Definition: DAMASK_marc.f90:11327
geometry_plastic_nonlocal::geometry_plastic_nonlocal_nipneighbors
integer, protected geometry_plastic_nonlocal_nipneighbors
Definition: DAMASK_marc.f90:9783
discretization::discretization_ipcoords
real(preal), dimension(:,:), allocatable, public, protected discretization_ipcoords
Definition: DAMASK_marc.f90:9940
debug::debug_spectralrestart
integer, parameter, public debug_spectralrestart
Definition: DAMASK_marc.f90:1400
debug::debug_fesolving
integer, parameter, public debug_fesolving
Definition: DAMASK_marc.f90:1407
constitutive::constitutive_lianditstangents
subroutine, public constitutive_lianditstangents(Li, dLi_dS, dLi_dFi, S, Fi, ipc, ip, el)
contains the constitutive equation for calculating the velocity gradient
Definition: DAMASK_marc.f90:16359
quaternions::mul_quat__
type(quaternion) elemental pure function mul_quat__(self, other)
multiply with a quaternion
Definition: DAMASK_marc.f90:4036
hdf5_utilities::initialize_write
subroutine initialize_write(dset_id, filespace_id, memspace_id, plist_id, myStart, totalShape, loc_id, myShape, datasetName, datatype, parallel)
initialize HDF5 handles, determines global shape and start for parallel write
Definition: DAMASK_marc.f90:8689
list::getfloats
real(preal) function, dimension(:), allocatable getfloats(this, key, defaultVal, requiredSize)
gets array of float values of for a given key from a linked list
Definition: DAMASK_marc.f90:1948
source_damage_anisoductile::source_damage_anisoductile_results
subroutine, public source_damage_anisoductile_results(phase, group)
writes results to HDF5 output file
Definition: DAMASK_marc.f90:15305
quaternions::inverse
type(quaternion) elemental pure function inverse(self)
inverse
Definition: DAMASK_marc.f90:4267
lattice::bcc_systemslip
real(preal), dimension(3+3, bcc_nslip), parameter bcc_systemslip
Definition: DAMASK_marc.f90:12082
lattice::lattice_iso_id
@, public lattice_iso_id
Definition: DAMASK_marc.f90:12341
rotations::qu2eu
pure real(preal) function, dimension(3) qu2eu(qu)
convert unit quaternion to Euler angles
Definition: DAMASK_marc.f90:4986
math::math_range
pure integer function, dimension(n) math_range(N)
range of integers starting at one
Definition: DAMASK_marc.f90:2688
math::math_voltetrahedron
real(preal) pure function math_voltetrahedron(v1, v2, v3, v4)
volume of tetrahedron given by four vertices
Definition: DAMASK_marc.f90:3629
lattice::lattice_massdensity
real(preal), dimension(:), allocatable, public, protected lattice_massdensity
Definition: DAMASK_marc.f90:12345
rotations::frommatrix
subroutine frommatrix(self, om)
Definition: DAMASK_marc.f90:4781
discretization_marc::buildcells
subroutine buildcells(connectivity_cell, cellNodeDefinition, elem, connectivity_elem)
Calculates cell node coordinates from element node coordinates.
Definition: DAMASK_marc.f90:10776
rotations::qu2cu
pure real(preal) function, dimension(3) qu2cu(qu)
convert unit quaternion to cubochoric
Definition: DAMASK_marc.f90:5091
config
Reads in the material configuration from file.
Definition: DAMASK_marc.f90:2156
hdf5_utilities::hdf5_addattribute_int_array
subroutine hdf5_addattribute_int_array(loc_id, attrLabel, attrValue, path)
adds a integer attribute to the path given relative to the location
Definition: DAMASK_marc.f90:7275
material::mappinghomogenizationconst
integer, dimension(:,:), allocatable, target, private mappinghomogenizationconst
mapping from material points to offset in constant state/field
Definition: DAMASK_marc.f90:11332
debug::debug_crystallite
integer, parameter, public debug_crystallite
Definition: DAMASK_marc.f90:1407
hdf5_utilities::initialize_read
subroutine initialize_read(dset_id, filespace_id, memspace_id, plist_id, aplist_id, myStart, globalShape, loc_id, localShape, datasetName, parallel)
initialize HDF5 handles, determines global shape and start for parallel read
Definition: DAMASK_marc.f90:8603
discretization_marc::buildcellnodes
subroutine buildcellnodes(node_cell, definition, node_elem)
Calculates cell node coordinates from element node coordinates.
Definition: DAMASK_marc.f90:10933
lattice::slipprojection_transverse
real(preal) function, dimension(sum(nslip), sum(nslip)) slipprojection_transverse(Nslip, structure, cOverA)
Projection of the transverse direction onto the slip plane.
Definition: DAMASK_marc.f90:13798
math::math_eye
Definition: DAMASK_marc.f90:2542
element::cell2
integer, dimension(ncellnodepercell(celltype(2)), nip(2)), parameter cell2
Definition: DAMASK_marc.f90:6552
lattice::lattice_interaction_twinbytwin
real(preal) function, dimension(sum(ntwin), sum(ntwin)), public lattice_interaction_twinbytwin(Ntwin, interactionValues, structure)
Twin-twin interaction matrix details only active twin systems are considered.
Definition: DAMASK_marc.f90:12941
lattice::lattice_nu
real(preal), dimension(:), allocatable, public, protected lattice_nu
Definition: DAMASK_marc.f90:12345
material::phase_nkinematics
integer, dimension(:), allocatable, public, protected phase_nkinematics
number of kinematic mechanisms active in each phase
Definition: DAMASK_marc.f90:11278
geometry_plastic_nonlocal
Geometric information about the IP cells needed for the nonlocal.
Definition: DAMASK_marc.f90:9776
damage_nonlocal::damage_nonlocal_putnonlocaldamage
subroutine, public damage_nonlocal_putnonlocaldamage(phi, ip, el)
updated nonlocal damage field with solution from damage phase field PDE
Definition: DAMASK_marc.f90:24231
lattice::hex_systemslip
real(preal), dimension(4+4, hex_nslip), parameter hex_systemslip
slip systems for hex, sorted by P. Eisenlohr CCW around starting next to a_1 axis
Definition: DAMASK_marc.f90:12155
hdf5_utilities::hdf5_write_int5
subroutine hdf5_write_int5(loc_id, dataset, datasetName, parallel)
write dataset of type integer with 5 dimensions
Definition: DAMASK_marc.f90:8401
math::math_eigh
subroutine math_eigh(m, w, v, error)
eigenvalues and eigenvectors of symmetric matrix
Definition: DAMASK_marc.f90:3350
material::elasticity_hooke_id
@, public elasticity_hooke_id
Definition: DAMASK_marc.f90:11252
material::damagestate
type(tstate), dimension(:), allocatable, public damagestate
Definition: DAMASK_marc.f90:11306
rotations::eu2ax
pure real(preal) function, dimension(4) eu2ax(eu)
convert euler to axis angle
Definition: DAMASK_marc.f90:5282
numerics::stagitmax
integer, public, protected stagitmax
max number of field level staggered iterations
Definition: DAMASK_marc.f90:1175
homogenization::materialpoint_subf
real(preal), dimension(:,:,:,:), allocatable materialpoint_subf
def grad of IP to be reached at end of homog inc
Definition: DAMASK_marc.f90:24312
material::source_undefined_id
@ source_undefined_id
Definition: DAMASK_marc.f90:11252
config::config_deallocate
subroutine, public config_deallocate(what)
deallocates the linked lists that store the content of the configuration files
Definition: DAMASK_marc.f90:2433
rotations::om2cu
real(preal) function, dimension(3) om2cu(om)
convert rotation matrix to cubochoric
Definition: DAMASK_marc.f90:5214
material::homogenization_ngrains
integer, dimension(:), allocatable, public, protected homogenization_ngrains
number of grains in each homogenization
Definition: DAMASK_marc.f90:11278
source_thermal_dissipation::param
type(tparameters), dimension(:), allocatable param
containers of constitutive parameters (len Ninstance)
Definition: DAMASK_marc.f90:14305
rotations::ashomochoric
pure real(preal) function, dimension(3) ashomochoric(self)
Definition: DAMASK_marc.f90:4706
results::results_writetensordataset_real
subroutine results_writetensordataset_real(group, dataset, label, description, SIunit, transposed)
stores a tensor dataset in a group
Definition: DAMASK_marc.f90:9118
constitutive::constitutive_source_maxsizedotstate
integer, public, protected constitutive_source_maxsizedotstate
Definition: DAMASK_marc.f90:15863
list::finalize
recursive subroutine finalize(this)
empties list and frees associated memory
Definition: DAMASK_marc.f90:1760
relaxationvector
pure real(preal) function, dimension(3) relaxationvector(intFace, instance, of)
derive average stress and stiffness from constituent quantities
Definition: DAMASK_marc.f90:25929
rotations::rottensor4
pure real(preal) function, dimension(3, 3, 3, 3) rottensor4(self, T, active)
rotate a rank-4 tensor passively (default) or actively
Definition: DAMASK_marc.f90:4892
source_thermal_externalheat::source_thermal_externalheat_instance
integer, dimension(:), allocatable source_thermal_externalheat_instance
instance of thermal dissipation source mechanism
Definition: DAMASK_marc.f90:14400
discretization_marc::inputread_nelemsets
subroutine inputread_nelemsets(nElemSets, maxNelemInSet, fileContent)
Count overall number of element sets in mesh.
Definition: DAMASK_marc.f90:10395
material::thermal_isothermal_id
@, public thermal_isothermal_id
Definition: DAMASK_marc.f90:11252
lattice::lattice_applylatticesymmetry33
real(preal) function, dimension(3, 3), public lattice_applylatticesymmetry33(T, structure)
Return 3x3 tensor with symmetry according to given crystal structure.
Definition: DAMASK_marc.f90:13638
rotations::qu2om
pure real(preal) function, dimension(3, 3) qu2om(qu)
convert unit quaternion to rotation matrix
Definition: DAMASK_marc.f90:4956
quaternions::homomorphed
type(quaternion) elemental pure function homomorphed(self)
homomorph
Definition: DAMASK_marc.f90:4216
damage_local::damage_local_init
subroutine, public damage_local_init
module initialization
Definition: DAMASK_marc.f90:23904
results::results_writescalardataset_real
subroutine results_writescalardataset_real(group, dataset, label, description, SIunit)
stores a scalar dataset in a group
Definition: DAMASK_marc.f90:9059
source_thermal_dissipation::source_thermal_dissipation_getrateanditstangent
subroutine, public source_thermal_dissipation_getrateanditstangent(TDot, dTDot_dT, Tstar, Lp, phase)
Ninstances dissipation rate.
Definition: DAMASK_marc.f90:14361
material::homogenization_undefined_id
@ homogenization_undefined_id
Definition: DAMASK_marc.f90:11252
element::ipneighbor9
integer, dimension(nipneighbor(celltype(9)), nip(9)), parameter ipneighbor9
Definition: DAMASK_marc.f90:6161
rotations::qu2ho
pure real(preal) function, dimension(3) qu2ho(qu)
convert unit quaternion to homochoric
Definition: DAMASK_marc.f90:5067
rotations::fromeulers
subroutine fromeulers(self, eu, degrees)
Definition: DAMASK_marc.f90:4730
lambert::pref
real(preal), parameter pref
Definition: DAMASK_marc.f90:4398
debug::debug_lattice
integer, parameter, public debug_lattice
stores debug level for lattice part of DAMASK bitwise coded
Definition: DAMASK_marc.f90:1407
debug::debug_stressmax
real(preal), public debug_stressmax
Definition: DAMASK_marc.f90:1438
integratestatefpi
subroutine integratestatefpi
integrate stress, state with adaptive 1st order explicit Euler method using Fixed Point Iteration to ...
Definition: DAMASK_marc.f90:22378
lattice::lattice_characteristicshear_twin
real(preal) function, dimension(sum(ntwin)), public lattice_characteristicshear_twin(Ntwin, structure, CoverA)
Characteristic shear for twinning.
Definition: DAMASK_marc.f90:12493
source_thermal_dissipation::tparameters
container type for internal constitutive parameters
Definition: DAMASK_marc.f90:14300
cpfem_initall
subroutine cpfem_initall(el, ip)
CPFEM engine.
Definition: DAMASK_marc.f90:26190
material::thermal_initialt
real(preal), dimension(:), allocatable, public, protected thermal_initialt
initial temperature per each homogenization
Definition: DAMASK_marc.f90:11289
material::damage_local_id
@, public damage_local_id
Definition: DAMASK_marc.f90:11252
math::math_symmetric66
pure real(preal) function, dimension(6, 6) math_symmetric66(m)
symmetrize a 6x6 matrix
Definition: DAMASK_marc.f90:3021
lattice::slipprojection_direction
real(preal) function, dimension(sum(nslip), sum(nslip)) slipprojection_direction(Nslip, structure, cOverA)
Projection of the slip direction onto the slip plane.
Definition: DAMASK_marc.f90:13822
lattice::bcc_nslipsystem
integer, dimension(2), parameter bcc_nslipsystem
Definition: DAMASK_marc.f90:12062
discretization_marc::inputread_microstructureandhomogenization
subroutine inputread_microstructureandhomogenization(microstructureAt, homogenizationAt, nElem, nNodes, nameElemSet, mapElemSet, initialcondTableStyle, fileContent)
Stores homogenization and microstructure ID.
Definition: DAMASK_marc.f90:10721
crystallite_stresstangent
subroutine crystallite_stresstangent
calculate tangent (dPdF)
Definition: DAMASK_marc.f90:21836
kinematics_thermal_expansion
material subroutine incorporating kinematics resulting from thermal expansion
Definition: DAMASK_marc.f90:15689
discretization_marc
Sets up the mesh for the solver MSC.Marc.
Definition: DAMASK_marc.f90:10052
source_thermal_externalheat::tparameters
container type for internal constitutive parameters
Definition: DAMASK_marc.f90:14404
source_damage_isobrittle::source_damage_isobrittle_instance
integer, dimension(:), allocatable source_damage_isobrittle_instance
Definition: DAMASK_marc.f90:14546
material::thermal_conduction_label
character(len= *), parameter, public thermal_conduction_label
Definition: DAMASK_marc.f90:11190
material::phase_elasticity
integer(kind(elasticity_undefined_id)), dimension(:), allocatable, public, protected phase_elasticity
elasticity of each phase
Definition: DAMASK_marc.f90:11255
material::thermal_type
integer(kind(thermal_isothermal_id)), dimension(:), allocatable, public, protected thermal_type
thermal transport model
Definition: DAMASK_marc.f90:11259
lattice::lattice_schmidmatrix_trans
real(preal) function, dimension(3, 3, sum(ntrans)), public lattice_schmidmatrix_trans(Ntrans, structure_target, cOverA, a_bcc, a_fcc)
Schmid matrix for twinning details only active twin systems are considered.
Definition: DAMASK_marc.f90:13462
prec
Interfaces DAMASK with MSC.Marc.
Definition: DAMASK_marc.f90:42
element::cellface2
integer, dimension(ncellnodepercellface(2), nipneighbor(2)), parameter cellface2
Definition: DAMASK_marc.f90:6699
discretization_marc::containsrange
logical function containsrange(str, chunkPos)
return whether a line contains a range ('X to Y')
Definition: DAMASK_marc.f90:11153
material::homogenization_typeinstance
integer, dimension(:), allocatable, public, protected homogenization_typeinstance
instance of particular type of each homogenization
Definition: DAMASK_marc.f90:11278
math::unittest
subroutine, private unittest
check correctness of some math functions
Definition: DAMASK_marc.f90:3676
element::ncellnodepercell
integer, dimension(maxval(celltype)), parameter ncellnodepercell
number of total cell nodes
Definition: DAMASK_marc.f90:6054
thermal_adiabatic::param
type(tparameters), dimension(:), allocatable param
Definition: DAMASK_marc.f90:23334
prec::pstringlen
integer, parameter pstringlen
default string length
Definition: DAMASK_marc.f90:56
hdf5_utilities::hdf5_write_real5
subroutine hdf5_write_real5(loc_id, dataset, datasetName, parallel)
write dataset of type real with 5 dimensions
Definition: DAMASK_marc.f90:8113
source_damage_anisoductile::source_damage_anisoductile_init
subroutine, public source_damage_anisoductile_init
module initialization
Definition: DAMASK_marc.f90:15186
math::mapnye
integer, dimension(2, 6), parameter, private mapnye
arrangement in Nye notation.
Definition: DAMASK_marc.f90:2509
debug::debug_jacobianminlocation
integer, dimension(2), public debug_jacobianminlocation
Definition: DAMASK_marc.f90:1431
quaternions::quaternion
Definition: DAMASK_marc.f90:3835
geometry_plastic_nonlocal::geometry_plastic_nonlocal_ipneighborhood
integer, dimension(:,:,:,:), allocatable, protected geometry_plastic_nonlocal_ipneighborhood
6 or less neighboring IPs as [element ID, IP ID, face ID that point to me]
Definition: DAMASK_marc.f90:9786
math::math_areatriangle
real(preal) pure function math_areatriangle(v1, v2, v3)
area of triangle given by three vertices
Definition: DAMASK_marc.f90:3646
math::math_det33
real(preal) pure function math_det33(m)
determinant of a 3x3 matrix
Definition: DAMASK_marc.f90:3085
quaternions::conjg__
type(quaternion) elemental pure function conjg__(self)
take conjugate complex
Definition: DAMASK_marc.f90:4204
quaternions::quaternions_init
subroutine, public quaternions_init
do self test
Definition: DAMASK_marc.f90:3931
debug::debug_material
integer, parameter, public debug_material
stores debug level for material part of DAMASK bitwise coded
Definition: DAMASK_marc.f90:1407
math::math_66tosym3333
pure real(preal) function, dimension(3, 3, 3, 3) math_66tosym3333(m66, weighted)
convert 66 matrix into symmetric 3x3x3x3 matrix
Definition: DAMASK_marc.f90:3268
material::homogstate
type(tstate), dimension(:), allocatable, public homogstate
Definition: DAMASK_marc.f90:11306
config::config_name_microstructure
character(len=pstringlen), dimension(:), allocatable, public, protected config_name_microstructure
name of each microstructure
Definition: DAMASK_marc.f90:2177
math::math_mul3333xx33
pure real(preal) function, dimension(3, 3) math_mul3333xx33(A, B)
matrix double contraction 3333x33 = 33 (ijkl,kl)
Definition: DAMASK_marc.f90:2830
lattice::applylatticesymmetryc66
real(preal) function, dimension(6, 6) applylatticesymmetryc66(C66, structure)
Return stiffness matrix in 6x6 notation with symmetry according to given crystal structure.
Definition: DAMASK_marc.f90:13676
quaternions::add__
type(quaternion) elemental pure function add__(self, other)
add a quaternion
Definition: DAMASK_marc.f90:3986
element::cellface1
integer, dimension(ncellnodepercellface(1), nipneighbor(1)), parameter cellface1
Definition: DAMASK_marc.f90:6688
rotations::cu2ax
real(preal) function, dimension(4) cu2ax(cu)
convert cubochoric to axis angle pair
Definition: DAMASK_marc.f90:5742
prec::prec_init
subroutine prec_init
reporting precision
Definition: DAMASK_marc.f90:130
lambert::getpyramidorder
pure integer function, dimension(3) getpyramidorder(xyz)
determine to which pyramid a point in a cubic grid belongs
Definition: DAMASK_marc.f90:4533
discretization::discretization_homogenizationat
integer, dimension(:), allocatable, public, protected discretization_homogenizationat
Definition: DAMASK_marc.f90:9936
material::source_damage_isobrittle_label
character(len= *), parameter, public source_damage_isobrittle_label
Definition: DAMASK_marc.f90:11190
lattice::fcc_systemcleavage
real(preal), dimension(3+3, fcc_ncleavage), parameter fcc_systemcleavage
Definition: DAMASK_marc.f90:12052
kinematics_slipplane_opening::kinematics_slipplane_opening_init
subroutine, public kinematics_slipplane_opening_init
module initialization
Definition: DAMASK_marc.f90:15541
damask_interface::inputfileextension
character(len= *), parameter, public inputfileextension
Definition: DAMASK_marc.f90:314
lattice::fcc_ncleavage
integer, parameter fcc_ncleavage
total # of cleavage systems for fcc
Definition: DAMASK_marc.f90:11983
lattice::lattice_init
subroutine, public lattice_init
Module initialization.
Definition: DAMASK_marc.f90:12403
discretization
spatial discretization
Definition: DAMASK_marc.f90:9924
material::homogenization_rgc_label
character(len= *), parameter, public homogenization_rgc_label
Definition: DAMASK_marc.f90:11190
list::keyexists
logical function keyexists(this, key)
reports wether a given key (string value at first position) exists in the list
Definition: DAMASK_marc.f90:1793
damage_nonlocal::damage_nonlocal_getmobility
real(preal) function, public damage_nonlocal_getmobility(ip, el)
Returns homogenized nonlocal damage mobility.
Definition: DAMASK_marc.f90:24208
rotations::rotrot__
pure elemental type(rotation) function rotrot__(self, R)
: Rotate a rotation
Definition: DAMASK_marc.f90:4798
debug::debug_levelselective
integer, parameter, public debug_levelselective
Definition: DAMASK_marc.f90:1394
material::microstructure_texture
integer, dimension(:,:), allocatable, private microstructure_texture
texture IDs of each microstructure
Definition: DAMASK_marc.f90:11323
math::twopiimg
complex(preal), parameter twopiimg
Re(0.0), Im(2xPi)
Definition: DAMASK_marc.f90:2492
rotations::qu2ro
pure real(preal) function, dimension(4) qu2ro(qu)
convert unit quaternion to Rodrigues vector
Definition: DAMASK_marc.f90:5040
rotations::ho2om
pure real(preal) function, dimension(3, 3) ho2om(ho)
convert homochoric to rotation matrix
Definition: DAMASK_marc.f90:5604
source_damage_isoductile::source_damage_isoductile_instance
integer, dimension(:), allocatable source_damage_isoductile_instance
instance of damage source mechanism
Definition: DAMASK_marc.f90:14746
material::elasticity_undefined_id
@ elasticity_undefined_id
Definition: DAMASK_marc.f90:11252
thermal_adiabatic::thermal_adiabatic_getspecificheat
real(preal) function, public thermal_adiabatic_getspecificheat(ip, el)
returns homogenized specific heat capacity
Definition: DAMASK_marc.f90:23488
material::material_parsemicrostructure
subroutine material_parsemicrostructure
parses the microstructure part in the material configuration file
Definition: DAMASK_marc.f90:11630
rotations::rottensor4sym
pure real(preal) function, dimension(6, 6) rottensor4sym(self, T, active)
rotate a symmetric rank-4 tensor stored as (6,6) passively (default) or actively ToDo: Need to check ...
Definition: DAMASK_marc.f90:4923
interfacenormal
pure real(preal) function, dimension(3) interfacenormal(intFace, instance, of)
identify the normal of an interface
Definition: DAMASK_marc.f90:25954
discretization::discretization_nip
integer, public, protected discretization_nip
Definition: DAMASK_marc.f90:9932
math::math_invariantssym33
pure real(preal) function, dimension(3) math_invariantssym33(m)
invariants of symmetrix 3x3 matrix
Definition: DAMASK_marc.f90:3566
material::stiffness_degradation_undefined_id
@ stiffness_degradation_undefined_id
Definition: DAMASK_marc.f90:11252
lambert::beta
real(preal), parameter beta
Definition: DAMASK_marc.f90:4398
quaternions::sub__
type(quaternion) elemental pure function sub__(self, other)
subtract a quaternion
Definition: DAMASK_marc.f90:4011
kinematics_slipplane_opening::kinematics_slipplane_opening_lianditstangent
subroutine, public kinematics_slipplane_opening_lianditstangent(Ld, dLd_dTstar, S, ipc, ip, el)
contains the constitutive equation for calculating the velocity gradient
Definition: DAMASK_marc.f90:15605
material::homogenization_none_label
character(len= *), parameter, public homogenization_none_label
Definition: DAMASK_marc.f90:11190
math::mapplain
integer, dimension(2, 9), parameter, private mapplain
arrangement in Plain notation
Definition: DAMASK_marc.f90:2529
kinematics_slipplane_opening
material subroutine incorporating kinematics resulting from opening of slip planes
Definition: DAMASK_marc.f90:15499
quaternions::conjg
Definition: DAMASK_marc.f90:3897
average_id
@ average_id
Definition: DAMASK_marc.f90:24965
discretization_marc::inputread_fileformat
subroutine inputread_fileformat(fileFormat, fileContent)
Figures out version of Marc input file format.
Definition: DAMASK_marc.f90:10279
lattice::lattice_c66_twin
real(preal) function, dimension(6, 6, sum(ntwin)), public lattice_c66_twin(Ntwin, C66, structure, CoverA)
Rotated elasticity matrices for twinning in 66-vector notation.
Definition: DAMASK_marc.f90:12570
material::source_thermal_externalheat_id
@, public source_thermal_externalheat_id
Definition: DAMASK_marc.f90:11252
quaternions::aimag
Definition: DAMASK_marc.f90:3913
cpfem_init
subroutine cpfem_init
allocate the arrays defined in module CPFEM and initialize them
Definition: DAMASK_marc.f90:26224
discretization::discretization_ipcoords0
real(preal), dimension(:,:), allocatable, public, protected discretization_ipcoords0
Definition: DAMASK_marc.f90:9940
prec::dneq0
logical elemental pure function dneq0(a, tol)
inequality to 0 comparison for float with double precision
Definition: DAMASK_marc.f90:218
lattice::lattice_slip_direction
real(preal) function, dimension(3, sum(nslip)), public lattice_slip_direction(Nslip, structure, cOverA)
Slip direction of slip systems (|| b)
Definition: DAMASK_marc.f90:13540
element::cell3
integer, dimension(ncellnodepercell(celltype(3)), nip(3)), parameter cell3
Definition: DAMASK_marc.f90:6563
thermal_conduction::thermal_conduction_getsourceanditstangent
subroutine, public thermal_conduction_getsourceanditstangent(Tdot, dTdot_dT, T, ip, el)
returns heat generation rate
Definition: DAMASK_marc.f90:23641
quaternions::abs
Definition: DAMASK_marc.f90:3889
material::homogenization_isostrain_id
@, public homogenization_isostrain_id
Definition: DAMASK_marc.f90:11252
results::results_removelink
subroutine, public results_removelink(link)
remove link to an object
Definition: DAMASK_marc.f90:9045
thermal_adiabatic::thermal_adiabatic_getmassdensity
real(preal) function, public thermal_adiabatic_getmassdensity(ip, el)
returns homogenized mass density
Definition: DAMASK_marc.f90:23515
element::celltype
integer, dimension(maxval(geomtype)), parameter celltype
cell type
Definition: DAMASK_marc.f90:6024
lattice::lattice_fcc_twinnucleationslippair
integer, dimension(2, fcc_ntwin), parameter, public lattice_fcc_twinnucleationslippair
Definition: DAMASK_marc.f90:12036
getrho0
real(preal) function, dimension(param(instance)%sum_n_sl, 10) getrho0(instance, of, ip, el)
returns copy of current dislocation densities from state
Definition: DAMASK_marc.f90:21381
lattice::lattice_hex_id
@, public lattice_hex_id
Definition: DAMASK_marc.f90:12341
geometry_plastic_nonlocal::geometry_plastic_nonlocal_setiparea
subroutine geometry_plastic_nonlocal_setiparea(IParea)
Set the initial areas of the unit triangle/unit quadrilateral/tetrahedron/hexahedron.
Definition: DAMASK_marc.f90:9837
hdf5_utilities::hdf5_read_real3
subroutine hdf5_read_real3(loc_id, dataset, datasetName, parallel)
read dataset of type real with 2 dimensions
Definition: DAMASK_marc.f90:7465
stresspenalty
subroutine stresspenalty(rPen, nMis, avgF, fDef, ip, el, instance, of)
allocates all neccessary fields, reads information from material configuration file
Definition: DAMASK_marc.f90:25613
material::kinematics_cleavage_opening_label
character(len= *), parameter, public kinematics_cleavage_opening_label
Definition: DAMASK_marc.f90:11190
results::results_writedataset
Definition: DAMASK_marc.f90:8791
material::thermal_isothermal_label
character(len= *), parameter, public thermal_isothermal_label
Definition: DAMASK_marc.f90:11190
constitutive::constitutive_results
subroutine, public constitutive_results
writes constitutive results to HDF5 output file
Definition: DAMASK_marc.f90:16671
source_thermal_dissipation::source_thermal_dissipation_offset
integer, dimension(:), allocatable source_thermal_dissipation_offset
which source is my current thermal dissipation mechanism?
Definition: DAMASK_marc.f90:14296
results::results_writetensordataset_int
subroutine results_writetensordataset_int(group, dataset, label, description, SIunit)
stores a tensor dataset in a group
Definition: DAMASK_marc.f90:9199
source_damage_isobrittle::source_damage_isobrittle_deltastate
subroutine, public source_damage_isobrittle_deltastate(C, Fe, ipc, ip, el)
calculates derived quantities from state
Definition: DAMASK_marc.f90:14631
math::math_mul3333xx3333
pure real(preal) function, dimension(3, 3, 3, 3) math_mul3333xx3333(A, B)
matrix multiplication 3333x3333 = 3333 (ijkl,klmn)
Definition: DAMASK_marc.f90:2847
hdf5_utilities::hdf5_objectexists
logical function hdf5_objectexists(loc_id, path)
check whether a group or a dataset exists
Definition: DAMASK_marc.f90:7119
io::io_warning
subroutine, public io_warning(warning_ID, el, ip, g, ext_msg)
writes warning statement to standard out
Definition: DAMASK_marc.f90:971
list::tpartitionedstring
Definition: DAMASK_marc.f90:1664
source_damage_anisoductile::param
type(tparameters), dimension(:), allocatable, private param
containers of constitutive parameters (len Ninstance)
Definition: DAMASK_marc.f90:15169
hdf5_utilities::hdf5_read
reads integer or float data of defined shape from file ! ToDo: order of arguments wrong
Definition: DAMASK_marc.f90:6883
debug::debug_jacobianmax
real(preal), public debug_jacobianmax
Definition: DAMASK_marc.f90:1438
material::plasticity_phenopowerlaw_id
@, public plasticity_phenopowerlaw_id
Definition: DAMASK_marc.f90:11252
rotations::ax2om
pure real(preal) function, dimension(3, 3) ax2om(ax)
convert axis angle pair to orientation matrix
Definition: DAMASK_marc.f90:5383
damask_interface::damask_interface_init
subroutine, public damask_interface_init
reports and sets working directory
Definition: DAMASK_marc.f90:326
flux
subroutine flux(f, ts, n, time)
calculate internal heat generated due to inelastic energy dissipation
Definition: DAMASK_marc.f90:26694
material::phase_localplasticity
logical, dimension(:), allocatable, public, protected phase_localplasticity
flags phases with local constitutive law
Definition: DAMASK_marc.f90:11317
rotations::om2eu
pure real(preal) function, dimension(3) om2eu(om)
orientation matrix to Euler angles
Definition: DAMASK_marc.f90:5120
interface4to1
integer pure function interface4to1(iFace4D, nGDim)
maps interface ID from 4D (normal and local position) into 1D (global array)
Definition: DAMASK_marc.f90:26034
io
all DAMASK files without solver
Definition: DAMASK_marc.f90:448
material::damage_typeinstance
integer, dimension(:), allocatable, public, protected damage_typeinstance
instance of particular type of each nonlocal damage
Definition: DAMASK_marc.f90:11278
quaternions::assign_quat__
elemental pure subroutine assign_quat__(self, other)
assign a quaternion
Definition: DAMASK_marc.f90:3957
quaternions::aimag__
pure real(preal) function, dimension(3) aimag__(self)
imaginary part (3-vector)
Definition: DAMASK_marc.f90:4254
config::config_name_texture
character(len=pstringlen), dimension(:), allocatable, public, protected config_name_texture
name of each texture
Definition: DAMASK_marc.f90:2177
material::phase_plasticityinstance
integer, dimension(:), allocatable, public, protected phase_plasticityinstance
instance of particular plasticity of each phase
Definition: DAMASK_marc.f90:11278
rotations::ax2cu
real(preal) function, dimension(3) ax2cu(ax)
convert axis angle pair to cubochoric
Definition: DAMASK_marc.f90:5473
rotations::ho2cu
pure real(preal) function, dimension(3) ho2cu(ho)
convert homochoric to cubochoric
Definition: DAMASK_marc.f90:5686
damage_local::tparameters
Definition: DAMASK_marc.f90:23884
debug::debug_homogenization
integer, parameter, public debug_homogenization
Definition: DAMASK_marc.f90:1407
source_thermal_externalheat::source_thermal_externalheat_offset
integer, dimension(:), allocatable source_thermal_externalheat_offset
which source is my current thermal dissipation mechanism?
Definition: DAMASK_marc.f90:14400
source_damage_anisoductile
material subroutine incorporating anisotropic ductile damage source mechanism
Definition: DAMASK_marc.f90:15143
thermal_conduction::thermal_conduction_puttemperatureanditsrate
subroutine, public thermal_conduction_puttemperatureanditsrate(T, Tdot, ip, el)
updates thermal state with solution from heat conduction PDE
Definition: DAMASK_marc.f90:23779
homogenization
homogenization manager, organizing deformation partitioning and stress homogenization
Definition: DAMASK_marc.f90:24280
material::plasticity_none_label
character(len= *), parameter, public plasticity_none_label
Definition: DAMASK_marc.f90:11190
rotations::ho2eu
pure real(preal) function, dimension(3) ho2eu(ho)
convert homochoric to Euler angles
Definition: DAMASK_marc.f90:5618
rotations::om2qu
pure real(preal) function, dimension(4) om2qu(om)
convert rotation matrix to cubochoric
Definition: DAMASK_marc.f90:5106
math::nrmmandel
real(preal), dimension(6), parameter, private nrmmandel
forward weighting for Mandel notation
Definition: DAMASK_marc.f90:2501
debug::debug_levelbasic
integer, parameter, public debug_levelbasic
Definition: DAMASK_marc.f90:1394
lattice::lattice_mu
real(preal), dimension(:), allocatable, public, protected lattice_mu
Definition: DAMASK_marc.f90:12345
prec::preal
integer, parameter preal
number with 15 significant digits, up to 1e+-307 (typically 64 bit)
Definition: DAMASK_marc.f90:49
numerics::usepingpong
logical, public, protected usepingpong
Definition: DAMASK_marc.f90:1163
math::math_invsym3333
real(preal) function, dimension(3, 3, 3, 3) math_invsym3333(A)
Inversion of symmetriced 3x3x3x3 matrix.
Definition: DAMASK_marc.f90:2951
numerics::err_struct_tolrel
real(preal), public, protected err_struct_tolrel
relative tolerance for mechanical equilibrium
Definition: DAMASK_marc.f90:1168
numerics::maxcutback
integer, public, protected maxcutback
max number of cut backs
Definition: DAMASK_marc.f90:1175
damage_local::damage_local_results
subroutine, public damage_local_results(homog, group)
writes results to HDF5 output file
Definition: DAMASK_marc.f90:24027
thermal_adiabatic::thermal_adiabatic_results
subroutine, public thermal_adiabatic_results(homog, group)
writes results to HDF5 output file
Definition: DAMASK_marc.f90:23541
cpfem_forward
subroutine cpfem_forward
Forward data for new time increment.
Definition: DAMASK_marc.f90:26450
debug
Reading in and interpretating the debugging settings for the various modules.
Definition: DAMASK_marc.f90:1387
damage_none::damage_none_init
subroutine damage_none_init
allocates all neccessary fields, reads information from material configuration file
Definition: DAMASK_marc.f90:23841
math::math_levicivita
real(preal) pure function math_levicivita(i, j, k)
permutation tensor e_ijk
Definition: DAMASK_marc.f90:2742
lattice::lattice_interaction_slipbyslip
real(preal) function, dimension(sum(nslip), sum(nslip)), public lattice_interaction_slipbyslip(Nslip, interactionValues, structure)
Slip-slip interaction matrix details only active slip systems are considered.
Definition: DAMASK_marc.f90:12721
damage_nonlocal::param
type(tparameters), dimension(:), allocatable param
Definition: DAMASK_marc.f90:24075
getinterface
pure integer function, dimension(4) getinterface(iFace, iGrain3)
collect six faces of a grain in 4D (normal and position)
Definition: DAMASK_marc.f90:25979
results::results_addattribute_int
subroutine results_addattribute_int(attrLabel, attrValue, path)
adds an integer attribute an object in the results file
Definition: DAMASK_marc.f90:8973
math::math_multinomial
integer pure function math_multinomial(alpha)
multinomial coefficient
Definition: DAMASK_marc.f90:3613
hdf5_utilities::hdf5_read_real6
subroutine hdf5_read_real6(loc_id, dataset, datasetName, parallel)
read dataset of type real with 6 dimensions
Definition: DAMASK_marc.f90:7585
source_damage_anisoductile::source_damage_anisoductile_offset
integer, dimension(:), allocatable source_damage_anisoductile_offset
which source is my current damage mechanism?
Definition: DAMASK_marc.f90:15156
lattice::lattice_slip_normal
real(preal) function, dimension(3, sum(nslip)), public lattice_slip_normal(Nslip, structure, cOverA)
Normal direction of slip systems (|| n)
Definition: DAMASK_marc.f90:13558
lattice::lattice_schmidmatrix_slip
real(preal) function, dimension(3, 3, sum(nslip)), public lattice_schmidmatrix_slip(Nslip, structure, cOverA)
Schmid matrix for slip details only active slip systems are considered.
Definition: DAMASK_marc.f90:13361
material::kinematics_slipplane_opening_id
@, public kinematics_slipplane_opening_id
Definition: DAMASK_marc.f90:11252
kinematics_cleavage_opening::tparameters
container type for internal constitutive parameters
Definition: DAMASK_marc.f90:15347
geometry_plastic_nonlocal::geometry_plastic_nonlocal_results
subroutine geometry_plastic_nonlocal_results
Write geometry data to results file.
Definition: DAMASK_marc.f90:9882
material::material_allocatesourcestate
subroutine, public material_allocatesourcestate(phase, of, NipcMyPhase, sizeState, sizeDotState, sizeDeltaState)
allocates the source state of a phase
Definition: DAMASK_marc.f90:11915
rotations::eu2cu
real(preal) function, dimension(3) eu2cu(eu)
convert Euler angles to cubochoric
Definition: DAMASK_marc.f90:5346
parse_materialconfig
subroutine parse_materialconfig(sectionNames, part, line, fileContent)
parses the material.config file
Definition: DAMASK_marc.f90:2363
material::phase_kinematics
integer(kind(source_undefined_id)), dimension(:,:), allocatable, public, protected phase_kinematics
active kinematic mechanisms of each phase
Definition: DAMASK_marc.f90:11270
config::config_texture
type(tpartitionedstringlist), dimension(:), allocatable, public, protected config_texture
Definition: DAMASK_marc.f90:2166
material::plasticity_undefined_id
@ plasticity_undefined_id
Definition: DAMASK_marc.f90:11252
debug::debug_spectralfftw
integer, parameter, public debug_spectralfftw
Definition: DAMASK_marc.f90:1400
element::cellface4
integer, dimension(ncellnodepercellface(4), nipneighbor(4)), parameter cellface4
Definition: DAMASK_marc.f90:6723
lambert::prek
real(preal), parameter prek
Definition: DAMASK_marc.f90:4398
debug::debug_stressmin
real(preal), public debug_stressmin
Definition: DAMASK_marc.f90:1438
kinematics_slipplane_opening::kinematics_slipplane_opening_instance
integer, dimension(:), allocatable kinematics_slipplane_opening_instance
Definition: DAMASK_marc.f90:15511
equivalentmoduli
real(preal) function, dimension(2) equivalentmoduli(grainID, ip, el)
compute the equivalent shear and bulk moduli from the elasticity tensor
Definition: DAMASK_marc.f90:25796
material::source_damage_anisobrittle_id
@, public source_damage_anisobrittle_id
Definition: DAMASK_marc.f90:11252
hdf5_utilities::hdf5_read_real4
subroutine hdf5_read_real4(loc_id, dataset, datasetName, parallel)
read dataset of type real with 4 dimensions
Definition: DAMASK_marc.f90:7505
results::results_addincrement
subroutine, public results_addincrement(inc, time)
creates the group of increment and adds time as attribute to the file
Definition: DAMASK_marc.f90:8878
prec::ceq
logical elemental pure function ceq(a, b, tol)
equality comparison for complex with double precision
Definition: DAMASK_marc.f90:239
element::cellnodeparentnodeweights3
integer, dimension(nnode(3), ncellnode(geomtype(3))), parameter cellnodeparentnodeweights3
Definition: DAMASK_marc.f90:6239
io::io_isblank
logical pure function, public io_isblank(string)
identifies strings without content
Definition: DAMASK_marc.f90:596
math::math_inner
real(preal) pure function math_inner(A, B)
inner product of arbitrary sized vectors (A · B / i,i)
Definition: DAMASK_marc.f90:2805
thermal_isothermal
material subroutine for isothermal temperature field
Definition: DAMASK_marc.f90:23271
material::phase_nstiffnessdegradations
integer, dimension(:), allocatable, public, protected phase_nstiffnessdegradations
number of stiffness degradation mechanisms active in each phase
Definition: DAMASK_marc.f90:11278
quaternions::neq__
logical elemental pure function neq__(self, other)
test inequality
Definition: DAMASK_marc.f90:4102
hdf5_utilities::hdf5_read_real2
subroutine hdf5_read_real2(loc_id, dataset, datasetName, parallel)
read dataset of type real with 2 dimensions
Definition: DAMASK_marc.f90:7425
math::math_samplegaussvar
real(preal) function math_samplegaussvar(meanvalue, stddev, width)
draw a random sample from Gauss variable
Definition: DAMASK_marc.f90:3315
damage_none
material subroutine for constant damage field
Definition: DAMASK_marc.f90:23828
prec::cneq
logical elemental pure function cneq(a, b, tol)
inequality comparison for complex with double precision
Definition: DAMASK_marc.f90:263
math::math_invert33
pure subroutine math_invert33(InvA, DetA, error, A)
Cramer inversion of 3x3 matrix (subroutine)
Definition: DAMASK_marc.f90:2916
math::math_eigvalsh33
real(preal) function, dimension(3) math_eigvalsh33(m)
eigenvalues of symmetric 3x3 matrix using an analytical expression
Definition: DAMASK_marc.f90:3533
math::math_clip
real(preal) pure elemental function math_clip(a, left, right)
limits a scalar value to a certain range (either one or two sided)
Definition: DAMASK_marc.f90:3659
lattice::ort_ncleavagesystem
integer, dimension(3), parameter ort_ncleavagesystem
Definition: DAMASK_marc.f90:12315
source_damage_isoductile::param
type(tparameters), dimension(:), allocatable, private param
containers of constitutive parameters (len Ninstance)
Definition: DAMASK_marc.f90:14758
results::results_addgroup
integer(hid_t) function, public results_addgroup(groupName)
adds a new group to the results file
Definition: DAMASK_marc.f90:8920
config::config_name_homogenization
character(len=pstringlen), dimension(:), allocatable, public, protected config_name_homogenization
name of each homogenization
Definition: DAMASK_marc.f90:2177
results::results_mapping_constituent
subroutine, public results_mapping_constituent(phaseAt, memberAtLocal, label)
adds the unique mapping from spatial position and constituent ID to results
Definition: DAMASK_marc.f90:9259
element::cell7
integer, dimension(ncellnodepercell(celltype(7)), nip(7)), parameter cell7
Definition: DAMASK_marc.f90:6613
damask_interface::symmetricsolver
logical, public, protected symmetricsolver
Definition: DAMASK_marc.f90:313
interface1to4
pure integer function, dimension(4) interface1to4(iFace1D, nGDim)
maps interface ID from 1D (global array) into 4D (normal and local position)
Definition: DAMASK_marc.f90:26080
numerics::err_thermal_tolabs
real(preal), public, protected err_thermal_tolabs
absolute tolerance for thermal equilibrium
Definition: DAMASK_marc.f90:1168
material::thermalstate
type(tstate), dimension(:), allocatable, public thermalstate
Definition: DAMASK_marc.f90:11306
lattice::lattice_undefined_id
@ lattice_undefined_id
Definition: DAMASK_marc.f90:12341
io::io_whitespace
character(len= *), parameter, public io_whitespace
whitespace characters
Definition: DAMASK_marc.f90:453
debug::debug_math
integer, parameter, public debug_math
Definition: DAMASK_marc.f90:1407
config::config_debug
type(tpartitionedstringlist), public, protected config_debug
Definition: DAMASK_marc.f90:2173
grain3to1
integer pure function grain3to1(grain3, nGDim)
map grain ID from in 3D (local position) to in 1D (global array)
Definition: DAMASK_marc.f90:26019
list::tpartitionedstringlist
Definition: DAMASK_marc.f90:1669
hdf5_utilities::hdf5_utilities_init
subroutine hdf5_utilities_init
open libary and do sanity checks
Definition: DAMASK_marc.f90:6945
element::cell4
integer, dimension(ncellnodepercell(celltype(4)), nip(4)), parameter cell4
Definition: DAMASK_marc.f90:6575
material::elasticity_hooke_label
character(len= *), parameter, public elasticity_hooke_label
Definition: DAMASK_marc.f90:11190
nonlocalconvergencecheck
subroutine nonlocalconvergencecheck
sets convergence flag for nonlocal calculations
Definition: DAMASK_marc.f90:23074
source_damage_anisobrittle
material subroutine incorporating anisotropic brittle damage source mechanism
Definition: DAMASK_marc.f90:14917
eigenvectorbasis
pure real(preal) function, dimension(3, 3) eigenvectorbasis(m)
eigenvector basis of positive-definite 3x3 matrix
Definition: DAMASK_marc.f90:3444
hdf5_utilities::hdf5_write_int3
subroutine hdf5_write_int3(loc_id, dataset, datasetName, parallel)
write dataset of type integer with 3 dimensions
Definition: DAMASK_marc.f90:8319
damage_nonlocal::tparameters
Definition: DAMASK_marc.f90:24070
numerics::damask_numthreadsint
integer(4), public, protected damask_numthreadsint
value stored in environment variable DAMASK_NUM_THREADS, set to zero if no OpenMP directive
Definition: DAMASK_marc.f90:1156
discretization::discretization_nodecoords0
real(preal), dimension(:,:), allocatable, public, protected discretization_nodecoords0
Definition: DAMASK_marc.f90:9940
source_damage_isobrittle::source_damage_isobrittle_results
subroutine, public source_damage_isobrittle_results(phase, group)
writes results to HDF5 output file
Definition: DAMASK_marc.f90:14706
kinematics_cleavage_opening::kinematics_cleavage_opening_instance
integer, dimension(:), allocatable kinematics_cleavage_opening_instance
Definition: DAMASK_marc.f90:15345
results::results_addattribute_str
subroutine results_addattribute_str(attrLabel, attrValue, path)
adds a string attribute to an object in the results file
Definition: DAMASK_marc.f90:8956
rotations::aseulers
pure real(preal) function, dimension(3) aseulers(self)
Definition: DAMASK_marc.f90:4670
prec::dneq
logical elemental pure function dneq(a, b, tol)
inequality comparison for float with double precision
Definition: DAMASK_marc.f90:175
lattice::fcc_systemslip
real(preal), dimension(3+3, fcc_nslip), parameter fcc_systemslip
Slip system <110>{111} directions. Sorted according to Eisenlohr & Hantcherli.
Definition: DAMASK_marc.f90:11996
rotations::om2ax
real(preal) function, dimension(4) om2ax(om)
convert orientation matrix to axis angle pair
Definition: DAMASK_marc.f90:5144
material::source_damage_anisobrittle_label
character(len= *), parameter, public source_damage_anisobrittle_label
Definition: DAMASK_marc.f90:11190
numerics::numerics_init
subroutine, public numerics_init
reads in parameters from numerics.config and sets openMP related parameters. Also does
Definition: DAMASK_marc.f90:1199
lattice::coordinatesystem_slip
real(preal) function, dimension(3, 3, sum(nslip)) coordinatesystem_slip(Nslip, structure, cOverA)
build a local coordinate system on slip systems
Definition: DAMASK_marc.f90:13846
lattice::lattice_fcc_id
@, public lattice_fcc_id
Definition: DAMASK_marc.f90:12341
source_damage_isobrittle::source_damage_isobrittle_getrateanditstangent
subroutine, public source_damage_isobrittle_getrateanditstangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
returns local part of nonlocal damage driving force
Definition: DAMASK_marc.f90:14677
geometry_plastic_nonlocal::geometry_plastic_nonlocal_disable
subroutine geometry_plastic_nonlocal_disable
Free memory used by variables only needed by plastic_nonlocal.
Definition: DAMASK_marc.f90:9862
numerics::err_struct_tolabs
real(preal), public, protected err_struct_tolabs
absolute tolerance for mechanical equilibrium
Definition: DAMASK_marc.f90:1168
lattice::lattice_forestprojection_screw
Definition: DAMASK_marc.f90:12362
thermal_conduction::thermal_conduction_getspecificheat
real(preal) function, public thermal_conduction_getspecificheat(ip, el)
returns homogenized specific heat capacity
Definition: DAMASK_marc.f90:23726
element::cell6
integer, dimension(ncellnodepercell(celltype(6)), nip(6)), parameter cell6
Definition: DAMASK_marc.f90:6601
list
linked list
Definition: DAMASK_marc.f90:1658
debug::debug_maxgeneral
integer, parameter, private debug_maxgeneral
Definition: DAMASK_marc.f90:1398
results::resultsfile
integer(hid_t) resultsfile
Definition: DAMASK_marc.f90:8789
element::cellnodeparentnodeweights11
integer, dimension(nnode(11), ncellnode(geomtype(11))), parameter cellnodeparentnodeweights11
Definition: DAMASK_marc.f90:6400
quaternions::exp__
type(quaternion) elemental pure function exp__(a)
take exponential
Definition: DAMASK_marc.f90:4140
list::finalizearray
subroutine finalizearray(this)
cleans entire array of linke lists
Definition: DAMASK_marc.f90:1773
kinematics_slipplane_opening::param
type(tparameters), dimension(:), allocatable param
containers of constitutive parameters (len Ninstance)
Definition: DAMASK_marc.f90:15527
discretization_marc::inputread_connectivityelem
integer function, dimension(nnodes, nelem) inputread_connectivityelem(nElem, nNodes, fileContent)
Stores node IDs.
Definition: DAMASK_marc.f90:10670
results::results_addattribute_real
subroutine results_addattribute_real(attrLabel, attrValue, path)
adds a real attribute an object in the results file
Definition: DAMASK_marc.f90:8991
geometry_plastic_nonlocal::geometry_plastic_nonlocal_iparea0
real(preal), dimension(:,:,:), allocatable, protected geometry_plastic_nonlocal_iparea0
area of interface to neighboring IP (initially!)
Definition: DAMASK_marc.f90:9792
material::damage_none_id
@, public damage_none_id
Definition: DAMASK_marc.f90:11252
source_damage_anisobrittle::param
type(tparameters), dimension(:), allocatable param
containers of constitutive parameters (len Ninstance)
Definition: DAMASK_marc.f90:14950
rotations::cu2eu
pure real(preal) function, dimension(3) cu2eu(cu)
convert cubochoric to Euler angles
Definition: DAMASK_marc.f90:5728
discretization::discretization_init
subroutine, public discretization_init(homogenizationAt, microstructureAt, IPcoords0, NodeCoords0, sharedNodesBegin)
stores the relevant information in globally accesible variables
Definition: DAMASK_marc.f90:9963
source_damage_isobrittle::source_damage_isobrittle_init
subroutine, public source_damage_isobrittle_init
module initialization
Definition: DAMASK_marc.f90:14575
lattice::lattice_c66_trans
real(preal) function, dimension(6, 6, sum(ntrans)), public lattice_c66_trans(Ntrans, C_parent66, structure_target, cOverA_trans, a_bcc, a_fcc)
Rotated elasticity matrices for transformation in 66-vector notation.
Definition: DAMASK_marc.f90:12611
debug::debug_levelextensive
integer, parameter, public debug_levelextensive
Definition: DAMASK_marc.f90:1394
lattice::lattice_bct_id
@, public lattice_bct_id
Definition: DAMASK_marc.f90:12341
source_damage_isoductile::source_damage_isoductile_getrateanditstangent
subroutine, public source_damage_isoductile_getrateanditstangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
returns local part of nonlocal damage driving force
Definition: DAMASK_marc.f90:14862
lattice::lattice_labels_twin
character(len=:) function, dimension(:), allocatable, public lattice_labels_twin(Ntwin, structure)
Labels for twin systems details only active twin systems are considered.
Definition: DAMASK_marc.f90:13757
quaternions
general quaternion math, not limited to unit quaternions
Definition: DAMASK_marc.f90:3826
thermal_conduction
material subroutine for temperature evolution from heat conduction
Definition: DAMASK_marc.f90:23567
discretization::discretization_nodecoords
real(preal), dimension(:,:), allocatable, public, protected discretization_nodecoords
Definition: DAMASK_marc.f90:9940
lattice::lattice_slip_transverse
real(preal) function, dimension(3, sum(nslip)), public lattice_slip_transverse(Nslip, structure, cOverA)
Transverse direction of slip systems ( || t = b x n)
Definition: DAMASK_marc.f90:13576
constitutive
elasticity, plasticity, internal microstructure state
Definition: DAMASK_marc.f90:15837
lattice::bcc_ntwinsystem
integer, dimension(1), parameter bcc_ntwinsystem
Definition: DAMASK_marc.f90:12065
debug::debug_jacobianmin
real(preal), public debug_jacobianmin
Definition: DAMASK_marc.f90:1438
element::cellnodeparentnodeweights12
integer, dimension(nnode(12), ncellnode(geomtype(12))), parameter cellnodeparentnodeweights12
Definition: DAMASK_marc.f90:6435
crystallite_init
subroutine crystallite_init
crystallite state integration functions and reporting of results
Definition: DAMASK_marc.f90:21524
discretization_marc::inputread_elemnodes
subroutine inputread_elemnodes(nodes, nNode, fileContent)
store x,y,z coordinates of all nodes in mesh.
Definition: DAMASK_marc.f90:10554
prec::group_float
variable length datatype used for storage of state
Definition: DAMASK_marc.f90:62
converged
logical pure function converged(residuum, state, atol)
determines whether a point is converged
Definition: DAMASK_marc.f90:23085
thermal_conduction::param
type(tparameters), dimension(:), allocatable param
Definition: DAMASK_marc.f90:23585
constitutive::constitutive_initialfi
pure real(preal) function, dimension(3, 3), public constitutive_initialfi(ipc, ip, el)
collects initial intermediate deformation gradient
Definition: DAMASK_marc.f90:16437
homogenization::materialpoint_subf0
real(preal), dimension(:,:,:,:), allocatable materialpoint_subf0
def grad of IP at beginning of homogenization increment
Definition: DAMASK_marc.f90:24312
lattice::lattice_labels_slip
character(len=:) function, dimension(:), allocatable, public lattice_labels_slip(Nslip, structure)
Labels for slip systems details only active slip systems are considered.
Definition: DAMASK_marc.f90:13595
lattice
contains lattice structure definitions including Schmid matrices for slip, twin, trans,
Definition: DAMASK_marc.f90:11959
lattice::equivalent_mu
real(preal) function equivalent_mu(C, assumption)
Equivalent shear modulus (μ)
Definition: DAMASK_marc.f90:14217
rotations::qu2ax
pure real(preal) function, dimension(4) qu2ax(qu)
convert unit quaternion to axis angle pair
Definition: DAMASK_marc.f90:5016
hdf5_utilities::hdf5_read_int6
subroutine hdf5_read_int6(loc_id, dataset, datasetName, parallel)
read dataset of type integer with 6 dimensions
Definition: DAMASK_marc.f90:7867
hdf5_utilities::hdf5_write_int1
subroutine hdf5_write_int1(loc_id, dataset, datasetName, parallel)
write dataset of type integer with 1 dimension
Definition: DAMASK_marc.f90:8237
hdf5_utilities::hdf5_addattribute_real
subroutine hdf5_addattribute_real(loc_id, attrLabel, attrValue, path)
adds a integer attribute to the path given relative to the location
Definition: DAMASK_marc.f90:7234
numerics::itmax
integer, public, protected itmax
maximum number of iterations
Definition: DAMASK_marc.f90:1175
prec::emptyintarray
integer, dimension(0), parameter emptyintarray
Definition: DAMASK_marc.f90:113
math::math_invert
subroutine math_invert(InvA, error, A)
invert quadratic matrix of arbitrary dimension
Definition: DAMASK_marc.f90:2983
lambert::r1
real(preal), parameter r1
Definition: DAMASK_marc.f90:4398
material::damage_nonlocal_label
character(len= *), parameter, public damage_nonlocal_label
Definition: DAMASK_marc.f90:11190
lattice::hex_ntwinsystem
integer, dimension(4), parameter hex_ntwinsystem
Definition: DAMASK_marc.f90:12143
source_damage_isoductile::tparameters
container type for internal constitutive parameters
Definition: DAMASK_marc.f90:14750
element::ipneighbor5
integer, dimension(nipneighbor(celltype(5)), nip(5)), parameter ipneighbor5
Definition: DAMASK_marc.f90:6117
hdf5_utilities::hdf5_addattribute_real_array
subroutine hdf5_addattribute_real_array(loc_id, attrLabel, attrValue, path)
adds a real attribute to the path given relative to the location
Definition: DAMASK_marc.f90:7319
material::thermal_typeinstance
integer, dimension(:), allocatable, public, protected thermal_typeinstance
instance of particular type of each thermal transport
Definition: DAMASK_marc.f90:11278
element::ncellnode
integer, dimension(maxval(geomtype)), parameter ncellnode
number of cell nodes
Definition: DAMASK_marc.f90:5996
hdf5_utilities::finalize_write
subroutine finalize_write(plist_id, dset_id, filespace_id, memspace_id)
closes HDF5 handles
Definition: DAMASK_marc.f90:8752
kinetics_trans
pure subroutine kinetics_trans(Mp, T, dot_gamma_sl, instance, of, dot_gamma_tr, ddot_gamma_dtau_trans)
Calculate shear rates on transformation systems and their derivatives with respect to.
Definition: DAMASK_marc.f90:19083
element
Definition: DAMASK_marc.f90:5922
quaternions::real
Definition: DAMASK_marc.f90:3909
prec::tstate
Definition: DAMASK_marc.f90:71
homogenization::tnumerics
Definition: DAMASK_marc.f90:24325
crystallite_results
subroutine crystallite_results
writes crystallite results to HDF5 output file
Definition: DAMASK_marc.f90:22024
lattice::lattice_schmidmatrix_cleavage
real(preal) function, dimension(3, 3, 3, sum(ncleavage)), public lattice_schmidmatrix_cleavage(Ncleavage, structure, cOverA)
Schmid matrix for cleavage details only active cleavage systems are considered.
Definition: DAMASK_marc.f90:13492
quaternions::pow_quat__
type(quaternion) elemental pure function pow_quat__(self, expon)
raise to the power of a quaternion
Definition: DAMASK_marc.f90:4114
hdf5_utilities::hdf5_read_real1
subroutine hdf5_read_real1(loc_id, dataset, datasetName, parallel)
read dataset of type real with 1 dimension
Definition: DAMASK_marc.f90:7385
math::math_trace33
real(preal) pure function math_trace33(m)
trace of a 3x3 matrix
Definition: DAMASK_marc.f90:3073
io::io_intvalue
integer function, public io_intvalue(string, chunkPos, myChunk)
reads integer value at myChunk from string
Definition: DAMASK_marc.f90:688
lattice::ort_ncleavage
integer, parameter ort_ncleavage
total # of cleavage systems for ortho
Definition: DAMASK_marc.f90:12318
rotations::cu2qu
pure real(preal) function, dimension(4) cu2qu(cu)
convert cubochoric to unit quaternion
Definition: DAMASK_marc.f90:5700
numerics::ijacostiffness
integer, public, protected ijacostiffness
frequency of stiffness update
Definition: DAMASK_marc.f90:1150
read_materialconfig
recursive character(len=pstringlen) function, dimension(:), allocatable read_materialconfig(fileName, cnt)
reads material.config Recursion is triggered by "{path/to/inputfile}" in a line
Definition: DAMASK_marc.f90:2281
rotations::standardize
pure elemental subroutine standardize(self)
quaternion representation with positive q
Definition: DAMASK_marc.f90:4812
math::math_delta
real(preal) pure function math_delta(i, j)
kronecker delta function d_ij
Definition: DAMASK_marc.f90:2762
quaternions::real__
pure real(preal) function real__(self)
real part (scalar)
Definition: DAMASK_marc.f90:4241
math::math_tensordot
real(preal) pure function math_tensordot(A, B)
double contraction of 3x3 matrices (A : B / ij,ij)
Definition: DAMASK_marc.f90:2818
hdf5_utilities::hdf5_read_int3
subroutine hdf5_read_int3(loc_id, dataset, datasetName, parallel)
read dataset of type integer with 3 dimensions
Definition: DAMASK_marc.f90:7747
numerics::err_damage_tolabs
real(preal), public, protected err_damage_tolabs
absolute tolerance for damage evolution
Definition: DAMASK_marc.f90:1168
material::stiffness_degradation_damage_label
character(len= *), parameter, public stiffness_degradation_damage_label
Definition: DAMASK_marc.f90:11190
element::cellnodeparentnodeweights10
integer, dimension(nnode(10), ncellnode(geomtype(10))), parameter cellnodeparentnodeweights10
Definition: DAMASK_marc.f90:6384
damask_interface
Definition: DAMASK_marc.f90:300
results::results_openjobfile
subroutine, public results_openjobfile
opens the results file to append data
Definition: DAMASK_marc.f90:8858
lattice::hex_systemtwin
real(preal), dimension(4+4, hex_ntwin), parameter hex_systemtwin
twin systems for hex, sorted by P. Eisenlohr CCW around starting next to a_1 axis
Definition: DAMASK_marc.f90:12199
quaternions::asarray
pure real(preal) function, dimension(4) asarray(self)
return as plain array
Definition: DAMASK_marc.f90:4228
rotations::rotations_init
subroutine, public rotations_init
doing self test
Definition: DAMASK_marc.f90:4649
results
Definition: DAMASK_marc.f90:8777
source_damage_anisoductile::source_damage_anisoductile_getrateanditstangent
subroutine, public source_damage_anisoductile_getrateanditstangent(localphiDot, dLocalphiDot_dPhi, phi, phase, constituent)
returns local part of nonlocal damage driving force
Definition: DAMASK_marc.f90:15278
material::stiffness_degradation_damage_id
@, public stiffness_degradation_damage_id
Definition: DAMASK_marc.f90:11252
kinematics_thermal_expansion::tparameters
Definition: DAMASK_marc.f90:15703
config::config_numerics
type(tpartitionedstringlist), public, protected config_numerics
Definition: DAMASK_marc.f90:2173
element::cellnodeparentnodeweights2
integer, dimension(nnode(2), ncellnode(geomtype(2))), parameter cellnodeparentnodeweights2
Definition: DAMASK_marc.f90:6224
hdf5_utilities::hdf5_write_int2
subroutine hdf5_write_int2(loc_id, dataset, datasetName, parallel)
write dataset of type integer with 2 dimensions
Definition: DAMASK_marc.f90:8278
element::cellnodeparentnodeweights6
integer, dimension(nnode(6), ncellnode(geomtype(6))), parameter cellnodeparentnodeweights6
Definition: DAMASK_marc.f90:6297
config::config_name_crystallite
character(len=pstringlen), dimension(:), allocatable, public, protected config_name_crystallite
name of each crystallite setting
Definition: DAMASK_marc.f90:2177
material::plasticity_disloucla_id
@, public plasticity_disloucla_id
Definition: DAMASK_marc.f90:11252
rotations::ro2om
pure real(preal) function, dimension(3, 3) ro2om(ro)
convert Rodrigues vector to rotation matrix
Definition: DAMASK_marc.f90:5501
io::io_eof
character(len= *), parameter, public io_eof
end of file string
Definition: DAMASK_marc.f90:453
element::ipneighbor3
integer, dimension(nipneighbor(celltype(3)), nip(3)), parameter ipneighbor3
Definition: DAMASK_marc.f90:6088
debug::debug_spectral
integer, parameter, public debug_spectral
Definition: DAMASK_marc.f90:1407
material::material_homogenizationat
integer, dimension(:), allocatable, public, protected material_homogenizationat
homogenization ID of each element (copy of discretization_homogenizationAt)
Definition: DAMASK_marc.f90:11293
source_thermal_externalheat
material subroutine for variable heat source
Definition: DAMASK_marc.f90:14390
material::material_nphase
integer, public, protected material_nphase
number of phases
Definition: DAMASK_marc.f90:11266
results::results_writevectordataset_int
subroutine results_writevectordataset_int(group, dataset, label, description, SIunit)
stores a vector dataset in a group
Definition: DAMASK_marc.f90:9169
results::results_addattribute_int_array
subroutine results_addattribute_int_array(attrLabel, attrValue, path)
adds an integer array attribute an object in the results file
Definition: DAMASK_marc.f90:9009
io::verifyfloatvalue
real(preal) function verifyfloatvalue(string)
returns verified float value in given string
Definition: DAMASK_marc.f90:1077
results::results_finalizeincrement
subroutine, public results_finalizeincrement
finalize increment
Definition: DAMASK_marc.f90:8898
hdf5_utilities::hdf5_closefile
subroutine hdf5_closefile(fileHandle)
close the opened HDF5 output file
Definition: DAMASK_marc.f90:7021
rotations::ro2ax
pure real(preal) function, dimension(4) ro2ax(ro)
convert Rodrigues vector to axis angle pair
Definition: DAMASK_marc.f90:5529
material::material_init
subroutine, public material_init
parses material configuration file
Definition: DAMASK_marc.f90:11382
math::math_sym33to6
pure real(preal) function, dimension(6) math_sym33to6(m33, weighted)
convert symmetric 3x3 matrix into 6 vector
Definition: DAMASK_marc.f90:3149
element::nelemtype
integer, parameter nelemtype
Definition: DAMASK_marc.f90:5957
rotations::ax2qu
pure real(preal) function, dimension(4) ax2qu(ax)
convert axis angle pair to quaternion
Definition: DAMASK_marc.f90:5360
material::kinematics_slipplane_opening_label
character(len= *), parameter, public kinematics_slipplane_opening_label
Definition: DAMASK_marc.f90:11190
rotations::asquaternion
pure real(preal) function, dimension(4) asquaternion(self)
Definition: DAMASK_marc.f90:4661
lattice::fcc_systemtwin
real(preal), dimension(3+3, fcc_ntwin), parameter fcc_systemtwin
Twin system <112>{111} directions. Sorted according to Eisenlohr & Hantcherli.
Definition: DAMASK_marc.f90:12020
prec::pint
integer, parameter pint
number with at least up to +-1e18 (typically 64 bit)
Definition: DAMASK_marc.f90:51
getrho
real(preal) function, dimension(param(instance)%sum_n_sl, 10) getrho(instance, of, ip, el)
returns copy of current dislocation densities from state
Definition: DAMASK_marc.f90:21356
numerics::worldrank
integer, public, protected worldrank
MPI worldrank (/=0 for MPI simulations only)
Definition: DAMASK_marc.f90:1150
kinematics_cleavage_opening::kinematics_cleavage_opening_lianditstangent
subroutine, public kinematics_cleavage_opening_lianditstangent(Ld, dLd_dTstar, S, ipc, ip, el)
contains the constitutive equation for calculating the velocity gradient
Definition: DAMASK_marc.f90:15427
integratestress
logical function integratestress(ipc, ip, el, timeFraction)
calculation of stress (P) with time integration based on a residuum in Lp and intermediate accelerati...
Definition: DAMASK_marc.f90:22154
debug::debug_marc
integer, parameter, public debug_marc
Definition: DAMASK_marc.f90:1407
debug::debug_stressmaxlocation
integer, dimension(2), public debug_stressmaxlocation
Definition: DAMASK_marc.f90:1431
lambert::pi12
real(preal), parameter pi12
Definition: DAMASK_marc.f90:4398
rotations::cu2ho
pure real(preal) function, dimension(3) cu2ho(cu)
convert cubochoric to homochoric
Definition: DAMASK_marc.f90:5770
material::plasticstate
type(tplasticstate), dimension(:), allocatable, public plasticstate
Definition: DAMASK_marc.f90:11302
math
Mathematical library, including random number generation and tensor representations.
Definition: DAMASK_marc.f90:2474
material::source_damage_anisoductile_label
character(len= *), parameter, public source_damage_anisoductile_label
Definition: DAMASK_marc.f90:11190
rotations::ho2ro
pure real(preal) function, dimension(4) ho2ro(ho)
convert homochoric to Rodrigues vector
Definition: DAMASK_marc.f90:5672
fesolving::terminallyill
logical terminallyill
at least one material point is terminally ill
Definition: DAMASK_marc.f90:5902
element::geomtype
integer, dimension(nelemtype), parameter geomtype
geometry type (same number of cell nodes and IPs)
Definition: DAMASK_marc.f90:5978
lattice::lattice_interaction_transbytrans
real(preal) function, dimension(sum(ntrans), sum(ntrans)), public lattice_interaction_transbytrans(Ntrans, interactionValues, structure)
Trans-trans interaction matrix details only active trans systems are considered.
Definition: DAMASK_marc.f90:13042
material::plasticity_dislotwin_label
character(len= *), parameter, public plasticity_dislotwin_label
Definition: DAMASK_marc.f90:11190
math::math_eigh33
subroutine math_eigh33(m, w, v)
eigenvalues and eigenvectors of symmetric 3x3 matrix using an analytical expression and the general L...
Definition: DAMASK_marc.f90:3377
rotations::eu2ho
pure real(preal) function, dimension(3) eu2ho(eu)
convert Euler angles to homochoric
Definition: DAMASK_marc.f90:5332
prec::group_int
Definition: DAMASK_marc.f90:66
lattice::fcc_ntwinsystem
integer, dimension(1), parameter fcc_ntwinsystem
Definition: DAMASK_marc.f90:11974
math::math_rotationalpart
real(preal) function, dimension(3, 3) math_rotationalpart(m)
rotational part from polar decomposition of 3x3 tensor
Definition: DAMASK_marc.f90:3424
hdf5_utilities::hdf5_write_real6
subroutine hdf5_write_real6(loc_id, dataset, datasetName, parallel)
write dataset of type real with 6 dimensions
Definition: DAMASK_marc.f90:8154
constitutive::constitutive_init
subroutine, public constitutive_init
allocates arrays pointing to array of the various constitutive modules
Definition: DAMASK_marc.f90:16171
config::config_microstructure
type(tpartitionedstringlist), dimension(:), allocatable, public, protected config_microstructure
Definition: DAMASK_marc.f90:2166
material::material_nhomogenization
integer, public, protected material_nhomogenization
number of homogenizations
Definition: DAMASK_marc.f90:11266
debug::debug_constitutive
integer, parameter, public debug_constitutive
stores debug level for constitutive part of DAMASK bitwise coded
Definition: DAMASK_marc.f90:1407
hdf5_utilities::hdf5_write_rotation
subroutine hdf5_write_rotation(loc_id, dataset, datasetName, parallel)
writes a scalar orientation dataset
Definition: DAMASK_marc.f90:8527
material::kinematics_cleavage_opening_id
@, public kinematics_cleavage_opening_id
Definition: DAMASK_marc.f90:11252
element::cell10
integer, dimension(ncellnodepercell(celltype(10)), nip(10)), parameter cell10
Definition: DAMASK_marc.f90:6652
lattice::bcc_systemcleavage
real(preal), dimension(3+3, bcc_ncleavage), parameter bcc_systemcleavage
Definition: DAMASK_marc.f90:12130
material::plasticity_nonlocal_label
character(len= *), parameter, public plasticity_nonlocal_label
Definition: DAMASK_marc.f90:11190
rotations::eu2ro
pure real(preal) function, dimension(4) eu2ro(eu)
Euler angles to Rodrigues vector.
Definition: DAMASK_marc.f90:5311
material::kinematics_thermal_expansion_label
character(len= *), parameter, public kinematics_thermal_expansion_label
Definition: DAMASK_marc.f90:11190
numerics::numerics_unitlength
real(preal), public, protected numerics_unitlength
determines the physical length of one computational length unit
Definition: DAMASK_marc.f90:1158
numerics::itmin
integer, public, protected itmin
minimum number of iterations
Definition: DAMASK_marc.f90:1175
math::math_deviatoric33
pure real(preal) function, dimension(3, 3) math_deviatoric33(m)
deviatoric part of a 3x3 matrix
Definition: DAMASK_marc.f90:3060
math::math_9to33
pure real(preal) function, dimension(3, 3) math_9to33(v9)
convert 9 vector into 3x3 matrix
Definition: DAMASK_marc.f90:3129
material::plasticity_nonlocal_id
@, public plasticity_nonlocal_id
Definition: DAMASK_marc.f90:11252
lattice::lattice_interaction_slipbytrans
real(preal) function, dimension(sum(nslip), sum(ntrans)), public lattice_interaction_slipbytrans(Nslip, Ntrans, interactionValues, structure)
Slip-trans interaction matrix details only active slip and trans systems are considered.
Definition: DAMASK_marc.f90:13227
discretization::discretization_nelem
integer, public, protected discretization_nelem
Definition: DAMASK_marc.f90:9932
rotations::om2ho
real(preal) function, dimension(3) om2ho(om)
convert rotation matrix to homochoric
Definition: DAMASK_marc.f90:5200
material::plasticity_kinehardening_id
@, public plasticity_kinehardening_id
Definition: DAMASK_marc.f90:11252
rotations::eu2om
pure real(preal) function, dimension(3, 3), public eu2om(eu)
Euler angles to orientation matrix.
Definition: DAMASK_marc.f90:5253
material::damage_none_label
character(len= *), parameter, public damage_none_label
Definition: DAMASK_marc.f90:11190
discretization::discretization_sharednodesbegin
integer discretization_sharednodesbegin
Definition: DAMASK_marc.f90:9946
kinematics_slipplane_opening::tparameters
container type for internal constitutive parameters
Definition: DAMASK_marc.f90:15513
lattice::bcc_ntwin
integer, parameter bcc_ntwin
total # of twin systems for bcc
Definition: DAMASK_marc.f90:12071
io::unittest
subroutine unittest
check correctness of some IO functions
Definition: DAMASK_marc.f90:1098
lattice::lattice_thermalconductivity
real(preal), dimension(:,:,:), allocatable, public, protected lattice_thermalconductivity
Definition: DAMASK_marc.f90:12350
damage_local::damage_local_getsourceanditstangent
subroutine damage_local_getsourceanditstangent(phiDot, dPhiDot_dPhi, phi, ip, el)
calculates homogenized local damage driving forces
Definition: DAMASK_marc.f90:23974
hdf5_utilities::hdf5_read_real5
subroutine hdf5_read_real5(loc_id, dataset, datasetName, parallel)
read dataset of type real with 5 dimensions
Definition: DAMASK_marc.f90:7545
damage_nonlocal::damage_nonlocal_results
subroutine, public damage_nonlocal_results(homog, group)
writes results to HDF5 output file
Definition: DAMASK_marc.f90:24252
debug::debug_e
integer, public, protected debug_e
Definition: DAMASK_marc.f90:1426
math::math_factorial
integer pure function math_factorial(n)
factorial
Definition: DAMASK_marc.f90:3582
discretization::discretization_microstructureat
integer, dimension(:), allocatable, public, protected discretization_microstructureat
Definition: DAMASK_marc.f90:9936
math::math_sort
recursive subroutine math_sort(a, istart, iend, sortDim)
Quicksort algorithm for two-dimensional integer arrays.
Definition: DAMASK_marc.f90:2594
hdf5_utilities::hdf5_write_real4
subroutine hdf5_write_real4(loc_id, dataset, datasetName, parallel)
write dataset of type real with 4 dimensions
Definition: DAMASK_marc.f90:8071
element::cell5
integer, dimension(ncellnodepercell(celltype(5)), nip(5)), parameter cell5
Definition: DAMASK_marc.f90:6592
rotations::ro2cu
pure real(preal) function, dimension(3) ro2cu(ro)
convert Rodrigues vector to cubochoric
Definition: DAMASK_marc.f90:5576
integratestateadaptiveeuler
subroutine integratestateadaptiveeuler
integrate stress, state with 1st order Euler method with adaptive step size
Definition: DAMASK_marc.f90:22618
rotations::ax2ro
pure real(preal) function, dimension(4) ax2ro(ax)
convert axis angle pair to Rodrigues vector
Definition: DAMASK_marc.f90:5433
discretization_marc::tcellnodedefinition
Definition: DAMASK_marc.f90:10069
crystallite_stress
logical function, dimension(discretization_nip, discretization_nelem) crystallite_stress(dummyArgumentToPreventInternalCompilerErrorWithGCC)
calculate stress (P)
Definition: DAMASK_marc.f90:21683
kinetics
pure subroutine kinetics(Mp, instance, of, gdot_pos, gdot_neg, dgdot_dtau_pos, dgdot_dtau_neg)
Phenomenological crystal plasticity using a power law formulation for the shear rates and a Voce-type...
Definition: DAMASK_marc.f90:17999
thermal_conduction::thermal_conduction_getconductivity
real(preal) function, dimension(3, 3), public thermal_conduction_getconductivity(ip, el)
returns homogenized thermal conductivity in reference configuration
Definition: DAMASK_marc.f90:23700
debug::debug_maxntype
integer, parameter, private debug_maxntype
must be set to the maximum defined debug type
Definition: DAMASK_marc.f90:1420
quaternions::log
Definition: DAMASK_marc.f90:3905
debug::debug_spectralpetsc
integer, parameter, public debug_spectralpetsc
Definition: DAMASK_marc.f90:1400
homogenization::materialpoint_doneandhappy
logical, dimension(:,:,:), allocatable materialpoint_doneandhappy
Definition: DAMASK_marc.f90:24322
quaternions::init__
type(quaternion) pure function init__(array)
construct a quaternion from a 4-vector
Definition: DAMASK_marc.f90:3942
material::material_texture
integer, dimension(:,:,:), allocatable, public, protected material_texture
texture (index) of each grain,IP,element. Only used by plastic_nonlocal
Definition: DAMASK_marc.f90:11311
material::phase_source
integer(kind(source_undefined_id)), dimension(:,:), allocatable, public, protected phase_source
active sources mechanisms of each phase
Definition: DAMASK_marc.f90:11270
debug::debug_spectralrotation
integer, parameter, public debug_spectralrotation
Definition: DAMASK_marc.f90:1400
damask_interface::solverissymmetric
logical function solverissymmetric()
determines whether a symmetric solver is used
Definition: DAMASK_marc.f90:387
config::config_init
subroutine, public config_init
reads material.config and stores its content per part
Definition: DAMASK_marc.f90:2194
damask_interface::getsolverjobname
character(len=:) function, allocatable, public getsolverjobname()
solver job name (no extension) as combination of geometry and load case name
Definition: DAMASK_marc.f90:369
uedinc
subroutine uedinc(inc, incsub)
trigger writing of results
Definition: DAMASK_marc.f90:26720
io::io_open_binary
integer function, public io_open_binary(fileName, mode)
opens an existing file for reading or a new file for writing.
Definition: DAMASK_marc.f90:564
lambert::lambert_cubetoball
pure real(preal) function, dimension(3), public lambert_cubetoball(cube)
map from 3D cubic grid to 3D ball
Definition: DAMASK_marc.f90:4423
results::results_writevectordataset_real
subroutine results_writevectordataset_real(group, dataset, label, description, SIunit)
stores a vector dataset in a group
Definition: DAMASK_marc.f90:9088
surfacecorrection
real(preal) function, dimension(3) surfacecorrection(avgF, instance, of)
compute the correction factor accouted for surface evolution (area change) due to
Definition: DAMASK_marc.f90:25765
geometry_plastic_nonlocal::geometry_plastic_nonlocal_setipareanormal
subroutine geometry_plastic_nonlocal_setipareanormal(IPareaNormal)
Set the direction normal of the areas of the triangle/quadrilateral/tetrahedron/hexahedron.
Definition: DAMASK_marc.f90:9850
quaternions::assign_vec__
pure subroutine assign_vec__(self, other)
assign a 4-vector
Definition: DAMASK_marc.f90:3970
lattice::buildinteraction
real(preal) function, dimension(sum(reacting_used), sum(acting_used)) buildinteraction(reacting_used, acting_used, reacting_max, acting_max, values, matrix)
Populate reduced interaction matrix.
Definition: DAMASK_marc.f90:13889
results::results_closegroup
subroutine, public results_closegroup(group_id)
close a group
Definition: DAMASK_marc.f90:8932
material::material_homogenizationmemberat
integer, dimension(:,:), allocatable, target, public material_homogenizationmemberat
position of the element within its homogenization instance
Definition: DAMASK_marc.f90:11295
discretization_marc::writegeometry
subroutine writegeometry(elem, connectivity_elem, connectivity_cell, coordinates_nodes, coordinates_points)
Write all information needed for the DADF5 geometry.
Definition: DAMASK_marc.f90:10170
io::io_lc
pure character(len=len(string)) function, public io_lc(string)
changes characters in string to lower case
Definition: DAMASK_marc.f90:716
future::findloc
integer function, dimension(:), allocatable findloc(a, v)
substitute for the findloc intrinsic (only for integer, dimension(:) at the moment)
Definition: DAMASK_marc.f90:2127
material::material_parsehomogenization
subroutine material_parsehomogenization
parses the homogenization part from the material configuration
Definition: DAMASK_marc.f90:11539
element::cellnodeparentnodeweights8
integer, dimension(nnode(8), ncellnode(geomtype(8))), parameter cellnodeparentnodeweights8
Definition: DAMASK_marc.f90:6332
source_damage_anisobrittle::source_damage_anisobrittle_dotstate
subroutine, public source_damage_anisobrittle_dotstate(S, ipc, ip, el)
calculates derived quantities from state
Definition: DAMASK_marc.f90:15039
thermal_conduction::thermal_conduction_init
subroutine, public thermal_conduction_init
module initialization
Definition: DAMASK_marc.f90:23605
fesolving::fesolving_execelem
integer, dimension(2) fesolving_execelem
for ping-pong scheme always whole range, otherwise one specific element
Definition: DAMASK_marc.f90:5905
hdf5_utilities::hdf5_setlink
subroutine hdf5_setlink(loc_id, target_name, link_name)
set link to object in results file
Definition: DAMASK_marc.f90:7363
numerics::defgradtolerance
real(preal), public, protected defgradtolerance
deviation of deformation gradient that is still allowed (used by CPFEM to determine outdated ffn1)
Definition: DAMASK_marc.f90:1158
rotations::ro2qu
pure real(preal) function, dimension(4) ro2qu(ro)
convert Rodrigues vector to unit quaternion
Definition: DAMASK_marc.f90:5487
quaternions::neg__
type(quaternion) elemental pure function neg__(self)
negate (unary negative operator)
Definition: DAMASK_marc.f90:4024
material::homogenization_type
integer(kind(homogenization_undefined_id)), dimension(:), allocatable, public, protected homogenization_type
type of each homogenization
Definition: DAMASK_marc.f90:11263
material::phase_stiffnessdegradation
integer(kind(source_undefined_id)), dimension(:,:), allocatable, public, protected phase_stiffnessdegradation
active stiffness degradation mechanisms of each phase
Definition: DAMASK_marc.f90:11270
thermal_adiabatic::tparameters
Definition: DAMASK_marc.f90:23329
damage_local::param
type(tparameters), dimension(:), allocatable param
Definition: DAMASK_marc.f90:23889
lattice::bcc_nslip
integer, parameter bcc_nslip
total # of slip systems for bcc
Definition: DAMASK_marc.f90:12071
element::ipneighbor2
integer, dimension(nipneighbor(celltype(2)), nip(2)), parameter ipneighbor2
Definition: DAMASK_marc.f90:6077
io::io_stringvalue
character(len=:) function, allocatable, public io_stringvalue(string, chunkPos, myChunk)
reads string value at myChunk from string
Definition: DAMASK_marc.f90:668
material::phase_nsources
integer, dimension(:), allocatable, public, protected phase_nsources
number of source mechanisms active in each phase
Definition: DAMASK_marc.f90:11278
material::plasticity_disloucla_label
character(len= *), parameter, public plasticity_disloucla_label
Definition: DAMASK_marc.f90:11190
math::math_init
subroutine math_init
initialization of random seed generator and internal checks
Definition: DAMASK_marc.f90:2557
math::pi
real(preal), parameter pi
ratio of a circle's circumference to its diameter
Definition: DAMASK_marc.f90:2489
material::plasticity_phenopowerlaw_label
character(len= *), parameter, public plasticity_phenopowerlaw_label
Definition: DAMASK_marc.f90:11190
hdf5_utilities::hdf5_write_real2
subroutine hdf5_write_real2(loc_id, dataset, datasetName, parallel)
write dataset of type real with 2 dimensions
Definition: DAMASK_marc.f90:7989
hdf5_utilities::hdf5_read_int5
subroutine hdf5_read_int5(loc_id, dataset, datasetName, parallel)
read dataset of type integer with 5 dimensions
Definition: DAMASK_marc.f90:7827
material::damage
type(group_float), dimension(:), allocatable, public damage
damage field
Definition: DAMASK_marc.f90:11339
discretization_marc::inputread_mapnodes
subroutine inputread_mapnodes(FEM2DAMASK, nNodes, fileContent)
Maps node from FE ID to internal (consecutive) representation.
Definition: DAMASK_marc.f90:10518
element::ipneighbor6
integer, dimension(nipneighbor(celltype(6)), nip(6)), parameter ipneighbor6
Definition: DAMASK_marc.f90:6126
lattice::lattice_damagemobility
real(preal), dimension(:), allocatable, public, protected lattice_damagemobility
Definition: DAMASK_marc.f90:12345
source_damage_anisoductile::tparameters
container type for internal constitutive parameters
Definition: DAMASK_marc.f90:15160
numerics::err_damage_tolrel
real(preal), public, protected err_damage_tolrel
relative tolerance for damage evolution
Definition: DAMASK_marc.f90:1168
prec::tplasticstate
Definition: DAMASK_marc.f90:94
source_damage_anisobrittle::tparameters
container type for internal constitutive parameters
Definition: DAMASK_marc.f90:14935
material::thermal_adiabatic_label
character(len= *), parameter, public thermal_adiabatic_label
Definition: DAMASK_marc.f90:11190
quaternions::dot_product__
real(preal) elemental pure function dot_product__(a, b)
calculate dot product
Definition: DAMASK_marc.f90:4192
list::getstring
character(len=pstringlen) function getstring(this, key, defaultVal, raw)
gets string value of for a given key from a linked list
Definition: DAMASK_marc.f90:1902
math::math_cross
pure real(preal) function, dimension(3) math_cross(A, B)
cross product a x b
Definition: DAMASK_marc.f90:2774
material::damage_type
integer(kind(damage_none_id)), dimension(:), allocatable, public, protected damage_type
nonlocal damage model
Definition: DAMASK_marc.f90:11261
geometry_plastic_nonlocal::geometry_plastic_nonlocal_setipvolume
subroutine geometry_plastic_nonlocal_setipvolume(IPvolume)
Set the initial volume associated with an integration point.
Definition: DAMASK_marc.f90:9824
lattice::hex_nslip
integer, parameter hex_nslip
total # of slip systems for hex
Definition: DAMASK_marc.f90:12146
integratestaterk4
subroutine integratestaterk4
integrate stress, state with 4th order explicit Runge Kutta method
Definition: DAMASK_marc.f90:22738
discretization_marc::inputread_mapelemsets
subroutine inputread_mapelemsets(nameElemSet, mapElemSet, fileContent)
map element sets
Definition: DAMASK_marc.f90:10441
element::ipneighbor7
integer, dimension(nipneighbor(celltype(7)), nip(7)), parameter ipneighbor7
Definition: DAMASK_marc.f90:6138
rotations::ro2ho
pure real(preal) function, dimension(3) ro2ho(ro)
convert Rodrigues vector to homochoric
Definition: DAMASK_marc.f90:5555
debug::debug_g
integer, public, protected debug_g
Definition: DAMASK_marc.f90:1426
damage_local::damage_local_updatestate
logical function, dimension(2), public damage_local_updatestate(subdt, ip, el)
calculates local change in damage field
Definition: DAMASK_marc.f90:23939
prec::tsourcestate
Definition: DAMASK_marc.f90:102
lattice::hex_nslipsystem
integer, dimension(6), parameter hex_nslipsystem
Definition: DAMASK_marc.f90:12140
lattice::lattice_structure
integer(kind(lattice_undefined_id)), dimension(:), allocatable, public, protected lattice_structure
Definition: DAMASK_marc.f90:12354
discretization::discretization_results
subroutine, public discretization_results
write the displacements
Definition: DAMASK_marc.f90:10000
lambert::spi
real(preal), parameter spi
Definition: DAMASK_marc.f90:4398
kinematics_thermal_expansion::kinematics_thermal_expansion_instance
integer, dimension(:), allocatable kinematics_thermal_expansion_instance
Definition: DAMASK_marc.f90:15701
math::math_6tosym33
pure real(preal) function, dimension(3, 3) math_6tosym33(v6, weighted)
convert 6 vector into symmetric 3x3 matrix
Definition: DAMASK_marc.f90:3177
math::math_inv33
pure real(preal) function, dimension(3, 3) math_inv33(A)
Cramer inversion of 3x3 matrix (function)
Definition: DAMASK_marc.f90:2897
lattice::fcc_nslipsystem
integer, dimension(2), parameter fcc_nslipsystem
Definition: DAMASK_marc.f90:11971
source_damage_anisoductile::source_damage_anisoductile_dotstate
subroutine, public source_damage_anisoductile_dotstate(ipc, ip, el)
calculates derived quantities from state
Definition: DAMASK_marc.f90:15247
numerics
Managing of parameters related to numerics.
Definition: DAMASK_marc.f90:1137
material::temperaturerate
type(group_float), dimension(:), allocatable, public temperaturerate
temperature change rate field
Definition: DAMASK_marc.f90:11339
hdf5_utilities::hdf5_opengroup
integer(hid_t) function hdf5_opengroup(fileHandle, groupName)
open an existing group of a file
Definition: DAMASK_marc.f90:7069
element::cellface3
integer, dimension(ncellnodepercellface(3), nipneighbor(3)), parameter cellface3
Definition: DAMASK_marc.f90:6711
material::microstructure_nconstituents
integer, dimension(:), allocatable, private microstructure_nconstituents
number of constituents in each microstructure
Definition: DAMASK_marc.f90:11320
material::source_damage_anisoductile_id
@, public source_damage_anisoductile_id
Definition: DAMASK_marc.f90:11252
debug::debug_jacobianmaxlocation
integer, dimension(2), public debug_jacobianmaxlocation
Definition: DAMASK_marc.f90:1431
debug::debug_debug
integer, parameter, public debug_debug
Definition: DAMASK_marc.f90:1407
material::plasticity_none_id
@, public plasticity_none_id
Definition: DAMASK_marc.f90:11252
homogenization::materialpoint_requested
logical, dimension(:,:), allocatable materialpoint_requested
Definition: DAMASK_marc.f90:24319
thermal_conduction::tparameters
Definition: DAMASK_marc.f90:23580
hdf5_utilities::hdf5_write_real7
subroutine hdf5_write_real7(loc_id, dataset, datasetName, parallel)
write dataset of type real with 7 dimensions
Definition: DAMASK_marc.f90:8195
discretization_marc::buildipcoordinates
subroutine buildipcoordinates(IPcoordinates, connectivity_cell, node_cell)
Calculates IP coordinates as center of cell.
Definition: DAMASK_marc.f90:10963
material::source_damage_isoductile_label
character(len= *), parameter, public source_damage_isoductile_label
Definition: DAMASK_marc.f90:11190
lambert::r2
real(preal), parameter r2
Definition: DAMASK_marc.f90:4398
fesolving
global variables for flow control
Definition: DAMASK_marc.f90:5897
thermal_adiabatic::thermal_adiabatic_updatestate
logical function, dimension(2), public thermal_adiabatic_updatestate(subdt, ip, el)
calculates adiabatic change in temperature based on local heat generation model
Definition: DAMASK_marc.f90:23391
rotations::ro2eu
pure real(preal) function, dimension(3) ro2eu(ro)
convert Rodrigues vector to Euler angles
Definition: DAMASK_marc.f90:5515
source_thermal_externalheat::source_thermal_externalheat_init
subroutine, public source_thermal_externalheat_init
module initialization
Definition: DAMASK_marc.f90:14428
lattice::fcc_ntranssystem
integer, dimension(1), parameter fcc_ntranssystem
Definition: DAMASK_marc.f90:11977
kinematics_cleavage_opening::param
type(tparameters), dimension(:), allocatable param
containers of constitutive parameters (len Ninstance)
Definition: DAMASK_marc.f90:15359
damage_nonlocal::damage_nonlocal_getdiffusion
real(preal) function, dimension(3, 3), public damage_nonlocal_getdiffusion(ip, el)
returns homogenized non local damage diffusion tensor in reference configuration
Definition: DAMASK_marc.f90:24181
config::config_homogenization
type(tpartitionedstringlist), dimension(:), allocatable, public, protected config_homogenization
Definition: DAMASK_marc.f90:2166
hdf5_utilities::hdf5_write_int4
subroutine hdf5_write_int4(loc_id, dataset, datasetName, parallel)
write dataset of type integer with 4 dimensions
Definition: DAMASK_marc.f90:8360
constitutive::constitutive_sanditstangents
subroutine, public constitutive_sanditstangents(S, dS_dFe, dS_dFi, Fe, Fi, ipc, ip, el)
returns the 2nd Piola-Kirchhoff stress tensor and its tangent with respect to the elastic/intermediat...
Definition: DAMASK_marc.f90:16472
material::homogenization_rgc_id
@, public homogenization_rgc_id
Definition: DAMASK_marc.f90:11252
source_damage_isoductile::source_damage_isoductile_offset
integer, dimension(:), allocatable source_damage_isoductile_offset
which source is my current damage mechanism?
Definition: DAMASK_marc.f90:14746
lattice::lattice_ort_id
@, public lattice_ort_id
Definition: DAMASK_marc.f90:12341
crystallite_restartread
subroutine crystallite_restartread
Read data for restart.
Definition: DAMASK_marc.f90:23197
source_thermal_dissipation::source_thermal_dissipation_init
subroutine, public source_thermal_dissipation_init
module initialization
Definition: DAMASK_marc.f90:14320
kinematics_thermal_expansion::param
type(tparameters), dimension(:), allocatable param
Definition: DAMASK_marc.f90:15710
math::math_detsym33
real(preal) pure function math_detsym33(m)
determinant of a symmetric 3x3 matrix
Definition: DAMASK_marc.f90:3099
discretization_marc::ipareanormal
real(preal) function, dimension(3, elem%nipneighbors, elem%nips, nelem) ipareanormal(elem, nElem, connectivity, node)
calculation of IP interface areas
Definition: DAMASK_marc.f90:11046
hdf5_utilities::hdf5_addattribute_int
subroutine hdf5_addattribute_int(loc_id, attrLabel, attrValue, path)
adds a integer attribute to the path given relative to the location
Definition: DAMASK_marc.f90:7193
prec::deq0
logical elemental pure function deq0(a, tol)
equality to 0 comparison for float with double precision
Definition: DAMASK_marc.f90:195
material::homogenization_none_id
@, public homogenization_none_id
Definition: DAMASK_marc.f90:11252
math::math_skew33
pure real(preal) function, dimension(3, 3) math_skew33(m)
skew part of a 3x3 matrix
Definition: DAMASK_marc.f90:3034
debug::debug_cpfem
integer, parameter, public debug_cpfem
Definition: DAMASK_marc.f90:1407
source_damage_isobrittle::tparameters
container type for internal constitutive parameters
Definition: DAMASK_marc.f90:14550
grain1to3
pure integer function, dimension(3) grain1to3(grain1, nGDim)
map grain ID from in 1D (global array) to in 3D (local position)
Definition: DAMASK_marc.f90:26002
element::nip
integer, dimension(maxval(geomtype)), parameter nip
number of IPs
Definition: DAMASK_marc.f90:6010
element::cell9
integer, dimension(ncellnodepercell(celltype(9)), nip(9)), parameter cell9
Definition: DAMASK_marc.f90:6636
material::kinematics_undefined_id
@ kinematics_undefined_id
Definition: DAMASK_marc.f90:11252
lattice::lattice_nonschmidmatrix
real(preal) function, dimension(1:3, 1:3, sum(nslip)), public lattice_nonschmidmatrix(Nslip, nonSchmidCoefficients, sense)
Non-schmid projections for bcc with up to 6 coefficients.
Definition: DAMASK_marc.f90:12674
lattice::fcc_ntwin
integer, parameter fcc_ntwin
total # of twin systems for fcc
Definition: DAMASK_marc.f90:11983
discretization_marc::discretization_marc_init
subroutine, public discretization_marc_init(ip, el)
initializes the mesh by calling all necessary private routines the mesh module Order and routines str...
Definition: DAMASK_marc.f90:10093
results::results_writescalardataset_rotation
subroutine results_writescalardataset_rotation(group, dataset, label, description, lattice_structure)
stores a scalar dataset in a group
Definition: DAMASK_marc.f90:9229
io::io_floatvalue
real(preal) function, public io_floatvalue(string, chunkPos, myChunk)
reads float value at myChunk from string
Definition: DAMASK_marc.f90:702
kinetics_slip
pure subroutine kinetics_slip(Mp, instance, of, gdot_slip_pos, gdot_slip_neg, dgdot_dtau_slip_pos, dgdot_dtau_slip_neg)
module initialization
Definition: DAMASK_marc.f90:17490
material::thermal_conduction_id
@, public thermal_conduction_id
Definition: DAMASK_marc.f90:11252
source_damage_anisobrittle::source_damage_anisobrittle_results
subroutine, public source_damage_anisobrittle_results(phase, group)
writes results to HDF5 output file
Definition: DAMASK_marc.f90:15115
lattice::bcc_systemtwin
real(preal), dimension(3+3, bcc_ntwin), parameter bcc_systemtwin
Definition: DAMASK_marc.f90:12113
list::getfloat
real(preal) function getfloat(this, key, defaultVal)
gets float value of for a given key from a linked list
Definition: DAMASK_marc.f90:1837
source_damage_isobrittle::param
type(tparameters), dimension(:), allocatable param
containers of constitutive parameters (len Ninstance)
Definition: DAMASK_marc.f90:14558
math::mapvoigt
integer, dimension(2, 6), parameter, private mapvoigt
arrangement in Voigt notation
Definition: DAMASK_marc.f90:2519
damage_nonlocal::damage_nonlocal_getsourceanditstangent
subroutine, public damage_nonlocal_getsourceanditstangent(phiDot, dPhiDot_dPhi, phi, ip, el)
calculates homogenized damage driving forces
Definition: DAMASK_marc.f90:24128
statejump
logical function statejump(ipc, ip, el)
calculates a jump in the state according to the current state and the current stress returns true,...
Definition: DAMASK_marc.f90:23103
material::material_parsephase
subroutine material_parsephase
parses the phase part in the material configuration file
Definition: DAMASK_marc.f90:11687
hdf5_utilities::hdf5_read_real7
subroutine hdf5_read_real7(loc_id, dataset, datasetName, parallel)
read dataset of type real with 7 dimensions
Definition: DAMASK_marc.f90:7625
quaternions::pow_scal__
type(quaternion) elemental pure function pow_scal__(self, expon)
raise to the power of a scalar
Definition: DAMASK_marc.f90:4127
prec::preal_min
real(preal), parameter, private preal_min
smallest normalized floating point number
Definition: DAMASK_marc.f90:111
hdf5_utilities::hdf5_write
writes integer or real data of defined shape to file ! ToDo: order of arguments wrong
Definition: DAMASK_marc.f90:6906
homogenization::materialpoint_stressanditstangent
subroutine, public materialpoint_stressanditstangent(updateJaco, dt)
parallelized calculation of stress and corresponding tangent at material points
Definition: DAMASK_marc.f90:24482
source_thermal_externalheat::param
type(tparameters), dimension(:), allocatable param
containers of constitutive parameters (len Ninstance)
Definition: DAMASK_marc.f90:14412
cpfem_general
subroutine cpfem_general(mode, parallelExecution, ffn, ffn1, temperature_inp, dt, elFE, ip, cauchyStress, jacobian)
perform initialization at first call, update variables and call the actual material model
Definition: DAMASK_marc.f90:26246
math::math_exp33
pure real(preal) function, dimension(3, 3) math_exp33(A, n)
3x3 matrix exponential up to series approximation order n (default 5)
Definition: DAMASK_marc.f90:2864
material::homogenization_isostrain_label
character(len= *), parameter, public homogenization_isostrain_label
Definition: DAMASK_marc.f90:11190
math::math_i3
real(preal), dimension(3, 3), parameter math_i3
3x3 Identity
Definition: DAMASK_marc.f90:2494
math::math_identity4th
pure real(preal) function, dimension(d, d, d, d) math_identity4th(d)
symmetric fourth rank identity tensor of specified dimension
Definition: DAMASK_marc.f90:2720
rotations::eu2qu
pure real(preal) function, dimension(4) eu2qu(eu)
Euler angles to unit quaternion.
Definition: DAMASK_marc.f90:5228
quaternions::div_quat__
type(quaternion) elemental pure function div_quat__(self, other)
divide by a quaternion
Definition: DAMASK_marc.f90:4064
material::source_thermal_dissipation_label
character(len= *), parameter, public source_thermal_dissipation_label
Definition: DAMASK_marc.f90:11190