1 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/math.f90"
4 # 1 "/home/damask_user/GitLabCI_Pipeline_4301/DAMASK/src/math.f90"
27 real(
preal),
parameter ::
pi = acos(-1.0_preal)
30 complex(pReal),
parameter ::
twopiimg = cmplx(0.0_preal,2.0_preal*
pi)
32 real(
preal),
dimension(3,3),
parameter :: &
34 1.0_preal,0.0_preal,0.0_preal, &
35 0.0_preal,1.0_preal,0.0_preal, &
36 0.0_preal,0.0_preal,1.0_preal &
39 real(
preal),
dimension(6),
parameter,
private :: &
41 1.0_preal, 1.0_preal, 1.0_preal, &
42 sqrt(2.0_preal), sqrt(2.0_preal), sqrt(2.0_preal) ]
44 real(
preal),
dimension(6),
parameter,
private :: &
47 integer,
dimension (2,6),
parameter,
private :: &
57 integer,
dimension (2,6),
parameter,
private :: &
67 integer,
dimension (2,9),
parameter,
private :: &
96 real(pReal),
dimension(4) :: randTest
98 integer,
dimension(:),
allocatable :: randInit
100 write(6,
'(/,a)')
' <<<+- math init -+>>>';
flush(6)
102 call random_seed(size=randsize)
103 allocate(randinit(randsize))
108 call random_seed(get = randinit)
109 randinit(2:randsize) = randinit(1)
112 call random_seed(put = randinit)
113 call random_number(randtest)
115 write(6,
'(a,i2)')
' size of random seed: ', randsize
116 write(6,
'(a,i0)')
' value of random seed: ', randinit(1)
117 write(6,
'(a,4(/,26x,f17.14),/)')
' start of random sequence: ', randtest
119 call random_seed(put = randinit)
131 recursive subroutine math_sort(a, istart, iend, sortDim)
133 integer,
dimension(:,:),
intent(inout) :: a
134 integer,
intent(in),
optional :: istart,iend, sortdim
135 integer :: ipivot,s,e,d
137 if(
present(istart))
then
143 if(
present(iend))
then
149 if(
present(sortdim))
then
169 integer,
dimension(:,:),
intent(inout) :: a
170 integer,
intent(in) :: istart,iend,sort
171 integer,
dimension(size(a,1)) :: tmp
176 do j = iend, istart, -1
177 if (a(sort,j) <= a(sort,istart))
exit
181 if (a(sort,i) > a(sort,istart))
exit
183 cross:
if (i >= j)
then
208 real(
preal),
dimension(:),
intent(in) :: what
209 integer,
dimension(:),
intent(in) :: how
213 if (sum(how) == 0)
return
216 math_expand(sum(how(1:i-1))+1:sum(how(1:i))) = what(mod(i-1,
size(what))+1)
227 integer,
intent(in) :: n
241 integer,
intent(in) :: d
259 integer,
intent(in) :: d
262 real(
preal),
dimension(d,d) :: identity2nd
265 do i=1,d;
do j=1,d;
do k=1,d;
do l=1,d
267 *(identity2nd(i,k)*identity2nd(j,l)+identity2nd(i,l)*identity2nd(j,k))
268 enddo; enddo; enddo;
enddo
281 integer,
intent(in) :: i,j,k
283 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
285 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
301 integer,
intent (in) :: i,j
303 math_delta = merge(0.0_preal, 1.0_preal, i /= j)
313 real(preal),
dimension(3),
intent(in) :: a,b
317 a(3)*b(1) -a(1)*b(3), &
318 a(1)*b(2) -a(2)*b(1) ]
328 real(preal),
dimension(:),
intent(in) :: a,b
329 real(preal),
dimension(size(A,1),size(B,1)) ::
math_outer
332 do i=1,
size(a,1);
do j=1,
size(b,1)
344 real(preal),
dimension(:),
intent(in) :: a
345 real(preal),
dimension(size(A,1)),
intent(in) :: b
357 real(preal),
dimension(3,3),
intent(in) :: a,b
369 real(preal),
dimension(3,3,3,3),
intent(in) :: a
370 real(preal),
dimension(3,3),
intent(in) :: b
387 real(preal),
dimension(3,3,3,3),
intent(in) :: a
388 real(preal),
dimension(3,3,3,3),
intent(in) :: b
391 do i=1,3;
do j=1,3;
do k=1,3;
do l=1,3
393 enddo; enddo; enddo;
enddo
403 real(preal),
dimension(3,3),
intent(in) :: a
404 integer,
intent(in),
optional :: n
407 real(preal) :: invfac
421 invfac = invfac/real(i,preal)
436 real(preal),
dimension(3,3),
intent(in) :: a
455 real(preal),
dimension(3,3),
intent(out) :: inva
456 real(preal),
intent(out) :: deta
457 logical,
intent(out) :: error
458 real(preal),
dimension(3,3),
intent(in) :: a
460 inva(1,1) = a(2,2) * a(3,3) - a(2,3) * a(3,2)
461 inva(2,1) = -a(2,1) * a(3,3) + a(2,3) * a(3,1)
462 inva(3,1) = a(2,1) * a(3,2) - a(2,2) * a(3,1)
464 deta = a(1,1) * inva(1,1) + a(1,2) * inva(2,1) + a(1,3) * inva(3,1)
470 inva(1,2) = -a(1,2) * a(3,3) + a(1,3) * a(3,2)
471 inva(2,2) = a(1,1) * a(3,3) - a(1,3) * a(3,1)
472 inva(3,2) = -a(1,1) * a(3,2) + a(1,2) * a(3,1)
474 inva(1,3) = a(1,2) * a(2,3) - a(1,3) * a(2,2)
475 inva(2,3) = -a(1,1) * a(2,3) + a(1,3) * a(2,1)
476 inva(3,3) = a(1,1) * a(2,2) - a(1,2) * a(2,1)
492 real(preal),
dimension(3,3,3,3),
intent(in) :: a
495 integer,
dimension(6) :: ipiv6
496 real(preal),
dimension(6,6) :: temp66
497 real(preal),
dimension(6*(64+2)) :: work
504 call dgetrf(6,6,temp66,6,ipiv6,ierr)
506 call dgetri(6,temp66,6,ipiv6,work,
size(work,1),ierr)
507 error = error .or. (ierr /= 0)
509 call io_error(400, ext_msg =
'math_invSym3333')
522 real(pReal),
dimension(:,:),
intent(in) :: A
523 real(pReal),
dimension(size(A,1),size(A,1)),
intent(out) :: invA
524 logical,
intent(out) :: error
526 integer,
dimension(size(A,1)) :: ipiv
527 real(pReal),
dimension(size(A,1)*(64+2)) :: work
534 call dgetrf(
size(a,1),
size(a,1),inva,
size(a,1),ipiv,ierr)
536 call dgetri(
size(a,1),inva,
size(a,1),ipiv,work,
size(work,1),ierr)
537 error = error .or. (ierr /= 0)
548 real(preal),
dimension(3,3),
intent(in) :: m
561 real(preal),
dimension(6,6),
intent(in) :: m
574 real(preal),
dimension(3,3),
intent(in) :: m
587 real(preal),
dimension(3,3),
intent(in) :: m
600 real(preal),
dimension(3,3),
intent(in) :: m
612 real(preal),
dimension(3,3),
intent(in) :: m
624 real(preal),
dimension(3,3),
intent(in) :: m
626 math_det33 = m(1,1)* (m(2,2)*m(3,3)-m(2,3)*m(3,2)) &
627 - m(1,2)* (m(2,1)*m(3,3)-m(2,3)*m(3,1)) &
628 + m(1,3)* (m(2,1)*m(3,2)-m(2,2)*m(3,1))
638 real(preal),
dimension(3,3),
intent(in) :: m
640 math_detsym33 = -(m(1,1)*m(2,3)**2 + m(2,2)*m(1,3)**2 + m(3,3)*m(1,2)**2) &
641 + m(1,1)*m(2,2)*m(3,3) + 2.0_preal * m(1,2)*m(1,3)*m(2,3)
652 real(preal),
dimension(3,3),
intent(in) :: m33
669 real(preal),
dimension(9),
intent(in) :: v9
689 real(preal),
dimension(3,3),
intent(in) :: m33
690 logical,
optional,
intent(in) :: weighted
692 real(preal),
dimension(6) :: w
695 if(
present(weighted))
then
717 real(preal),
dimension(6),
intent(in) :: v6
718 logical,
optional,
intent(in) :: weighted
720 real(preal),
dimension(6) :: w
723 if(
present(weighted))
then
743 real(preal),
dimension(3,3,3,3),
intent(in) :: m3333
760 real(preal),
dimension(9,9),
intent(in) :: m99
780 real(preal),
dimension(3,3,3,3),
intent(in) :: m3333
781 logical,
optional,
intent(in) :: weighted
783 real(preal),
dimension(6) :: w
786 if(
present(weighted))
then
808 real(preal),
dimension(6,6),
intent(in) :: m66
809 logical,
optional,
intent(in) :: weighted
811 real(preal),
dimension(6) :: w
814 if(
present(weighted))
then
836 real(preal),
dimension(6,6),
intent(in) :: m66
854 real(preal),
intent(in) :: meanvalue, & !< meanvalue of gauss distribution
856 real(preal),
intent(in),
optional :: width
858 real(preal),
dimension(2) :: rnd
859 real(preal) :: scatter, &
862 if (abs(stddev) < tol_math_check)
then
865 if (
present(width))
then
872 call random_number(rnd)
873 scatter = width_ * (2.0_preal * rnd(1) - 1.0_preal)
874 if (rnd(2) <= exp(-0.5_preal * scatter ** 2.0_preal))
exit
889 real(pReal),
dimension(:,:),
intent(in) :: m
890 real(pReal),
dimension(size(m,1)),
intent(out) :: w
891 real(pReal),
dimension(size(m,1),size(m,1)),
intent(out) :: v
893 logical,
intent(out) :: error
895 real(pReal),
dimension((64+2)*size(m,1)) :: work
900 call dsyev(
'V',
'U',
size(m,1),v,
size(m,1),w,work,
size(work,1),ierr)
916 real(pReal),
dimension(3,3),
intent(in) :: m
917 real(pReal),
dimension(3),
intent(out) :: w
918 real(pReal),
dimension(3,3),
intent(out) :: v
920 real(pReal) :: T, U, norm, threshold
925 v(1:3,2) = [ m(1, 2) * m(2, 3) - m(1, 3) * m(2, 2), &
926 m(1, 3) * m(1, 2) - m(2, 3) * m(1, 1), &
931 threshold = sqrt(5.68e-14_preal * u**2)
933 v(1:3,1) = [ v(1,2) + m(1, 3) * w(1), &
934 v(2,2) + m(2, 3) * w(1), &
935 (m(1,1) - w(1)) * (m(2,2) - w(1)) - v(3,2)]
936 norm = norm2(v(1:3, 1))
937 fallback1:
if(norm < threshold)
then
940 v(1:3,1) = v(1:3, 1) / norm
941 v(1:3,2) = [ v(1,2) + m(1, 3) * w(2), &
942 v(2,2) + m(2, 3) * w(2), &
943 (m(1,1) - w(2)) * (m(2,2) - w(2)) - v(3,2)]
944 norm = norm2(v(1:3, 2))
945 fallback2:
if(norm < threshold)
then
948 v(1:3,2) = v(1:3, 2) / norm
963 real(preal),
intent(in),
dimension(3,3) :: m
965 real(preal),
dimension(3,3) :: u , uinv
970 inversionfailed:
if (all(deq0(uinv)))
then
975 endif inversionfailed
984 real(preal),
dimension(3,3),
intent(in) :: m
986 real(preal),
dimension(3) :: i, v
987 real(preal) :: p, q, rho, phi
988 real(preal),
parameter :: tol=1.e-14_preal
989 real(preal),
dimension(3,3,3) :: n, eb
993 p = i(2)-i(1)**2.0_preal/3.0_preal
994 q = -2.0_preal/27.0_preal*i(1)**3.0_preal+product(i(1:2))/3.0_preal-i(3)
996 threesimilareigvals:
if(all(abs([p,q]) < tol))
then
1003 else threesimilareigvals
1004 rho=sqrt(-3.0_preal*p**3.0_preal)/9.0_preal
1005 phi=acos(
math_clip(-q/rho*0.5_preal,-1.0_preal,1.0_preal))
1006 v = 2.0_preal*rho**(1.0_preal/3.0_preal)* [cos((phi )/3.0_preal), &
1007 cos((phi+2.0_preal*
pi)/3.0_preal), &
1008 cos((phi+4.0_preal*
pi)/3.0_preal) &
1013 twosimilareigvals:
if(abs(v(1)-v(2)) < tol)
then
1014 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)))
1015 eb(1:3,1:3,1) =
math_i3-eb(1:3,1:3,3)
1016 eb(1:3,1:3,2) = 0.0_preal
1017 elseif (abs(v(2)-v(3)) < tol)
then twosimilareigvals
1018 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)))
1019 eb(1:3,1:3,2) =
math_i3-eb(1:3,1:3,1)
1020 eb(1:3,1:3,3) = 0.0_preal
1021 elseif (abs(v(3)-v(1)) < tol)
then twosimilareigvals
1022 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)))
1023 eb(1:3,1:3,3) =
math_i3-eb(1:3,1:3,2)
1024 eb(1:3,1:3,1) = 0.0_preal
1025 else twosimilareigvals
1026 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)))
1027 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)))
1028 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)))
1029 endif twosimilareigvals
1030 endif threesimilareigvals
1033 + sqrt(v(2)) * eb(1:3,1:3,2) &
1034 + sqrt(v(3)) * eb(1:3,1:3,3)
1047 real(preal),
dimension(:,:),
intent(in) :: m
1050 real(preal),
dimension(size(m,1),size(m,1)) :: m_
1052 real(preal),
dimension((64+2)*size(m,1)) :: work
1057 call dsyev(
'N',
'U',
size(m,1),m_,
size(m,1),
math_eigvalsh,work,
size(work,1),ierr)
1058 if (ierr /= 0)
math_eigvalsh = ieee_value(1.0_preal,ieee_quiet_nan)
1072 real(preal),
intent(in),
dimension(3,3) :: m
1074 real(preal) :: p, q, rho, phi
1075 real(preal),
parameter :: tol=1.e-14_preal
1079 p = i(2)-i(1)**2.0_preal/3.0_preal
1080 q = product(i(1:2))/3.0_preal &
1081 - 2.0_preal/27.0_preal*i(1)**3.0_preal &
1084 if(all(abs([p,q]) < tol))
then
1087 rho=sqrt(-3.0_preal*p**3.0_preal)/9.0_preal
1088 phi=acos(
math_clip(-q/rho*0.5_preal,-1.0_preal,1.0_preal))
1090 [cos(phi/3.0_preal), &
1091 cos((phi+2.0_preal*
pi)/3.0_preal), &
1092 cos((phi+4.0_preal*
pi)/3.0_preal) &
1105 real(preal),
dimension(3,3),
intent(in) :: m
1110 -(m(1,2)**2 + m(1,3)**2 + m(2,3)**2)
1121 integer,
intent(in) :: n
1133 integer,
intent(in) :: n, k
1134 integer :: i, k_, n_
1152 integer,
intent(in),
dimension(:) :: alpha
1156 do i = 1,
size(alpha)
1168 real(preal),
dimension (3),
intent(in) :: v1,v2,v3,v4
1169 real(preal),
dimension (3,3) :: m
1185 real(preal),
dimension (3),
intent(in) :: v1,v2,v3
1196 real(preal)
pure elemental function
math_clip(a, left, right)
1198 real(preal),
intent(in) :: a
1199 real(preal),
intent(in),
optional :: left, right
1204 if (
present(left) .and.
present(right)) &
1215 integer,
dimension(2,4) :: &
1216 sort_in_ = reshape([+1,+5, +5,+6, -1,-1, +3,-2],[2,4])
1217 integer,
dimension(2,4),
parameter :: &
1218 sort_out_ = reshape([-1,-1, +1,+5, +5,+6, +3,-2],[2,4])
1220 integer,
dimension(5) :: range_out_ = [1,2,3,4,5]
1221 integer,
dimension(3) :: ijk
1224 real(preal),
dimension(3) :: v3_1,v3_2,v3_3,v3_4
1225 real(preal),
dimension(6) :: v6
1226 real(preal),
dimension(9) :: v9
1227 real(preal),
dimension(3,3) :: t33,t33_2
1228 real(preal),
dimension(6,6) :: t66
1229 real(preal),
dimension(9,9) :: t99,t99_2
1230 real(preal),
dimension(:,:), &
1231 allocatable :: txx,txx_2
1236 if (any(abs([1.0_preal,2.0_preal,2.0_preal,3.0_preal,3.0_preal,3.0_preal] - &
1237 math_expand([1.0_preal,2.0_preal,3.0_preal],[1,2,3,0])) > tol_math_check)) &
1238 call io_error(0,ext_msg=
'math_expand [1,2,3] by [1,2,3,0] => [1,2,2,3,3,3]')
1240 if (any(abs([1.0_preal,2.0_preal,2.0_preal] - &
1241 math_expand([1.0_preal,2.0_preal,3.0_preal],[1,2])) > tol_math_check)) &
1242 call io_error(0,ext_msg=
'math_expand [1,2,3] by [1,2] => [1,2,2]')
1244 if (any(abs([1.0_preal,2.0_preal,2.0_preal,1.0_preal,1.0_preal,1.0_preal] - &
1245 math_expand([1.0_preal,2.0_preal],[1,2,3])) > tol_math_check)) &
1246 call io_error(0,ext_msg=
'math_expand [1,2] by [1,2,3] => [1,2,2,1,1,1]')
1249 if(any(sort_in_ /= sort_out_)) &
1250 call io_error(0,ext_msg=
'math_sort')
1253 call io_error(0,ext_msg=
'math_range')
1256 call io_error(0,ext_msg=
'math_exp33(math_I3,1)')
1258 call io_error(0,ext_msg=
'math_exp33(math_I3,256)')
1260 call random_number(v9)
1262 call io_error(0,ext_msg=
'math_33to9/math_9to33')
1264 call random_number(t99)
1266 call io_error(0,ext_msg=
'math_3333to99/math_99to3333')
1268 call random_number(v6)
1270 call io_error(0,ext_msg=
'math_sym33to6/math_6toSym33')
1272 call random_number(t66)
1274 call io_error(0,ext_msg=
'math_sym3333to66/math_66toSym3333')
1276 call random_number(v6)
1278 call io_error(0,ext_msg=
'math_symmetric33')
1280 call random_number(v3_1)
1281 call random_number(v3_2)
1282 call random_number(v3_3)
1283 call random_number(v3_4)
1285 if(dneq(abs(dot_product(
math_cross(v3_1-v3_4,v3_2-v3_4),v3_3-v3_4))/6.0, &
1287 call io_error(0,ext_msg=
'math_volTetrahedron')
1289 call random_number(t33)
1291 call io_error(0,ext_msg=
'math_det33/math_detSym33')
1294 call io_error(0,ext_msg=
'math_inv33(math_I3)')
1297 call random_number(t33)
1300 call io_error(0,ext_msg=
'math_inv33')
1303 if(any(dneq0(matmul(t33,t33_2) -
math_identity2nd(3),tol=1.0e-9_preal)) .or. e) &
1304 call io_error(0,ext_msg=
'math_invert33: T:T^-1 != I')
1305 if(dneq(det,
math_det33(t33),tol=1.0e-12_preal)) &
1306 call io_error(0,ext_msg=
'math_invert33 (determinant)')
1309 if(any(dneq0(matmul(t33,t33_2) -
math_identity2nd(3),tol=1.0e-9_preal)) .or. e) &
1310 call io_error(0,ext_msg=
'math_invert t33')
1313 call random_number(t33)
1317 if(any(dneq0(matmul(t33_2,t33) -
math_i3,tol=1.0e-10_preal))) &
1318 call io_error(0,ext_msg=
'math_rotationalPart')
1320 call random_number(r)
1321 d = int(r*5.0_preal) + 1
1323 allocate(txx_2(d,d))
1325 if(any(dneq0(txx_2,txx) .or. e)) &
1326 call io_error(0,ext_msg=
'math_invert(txx)/math_identity2nd')
1329 if(any(dneq0(matmul(t99_2,t99)-
math_identity2nd(9),tol=1.0e-9_preal)) .or. e) &
1330 call io_error(0,ext_msg=
'math_invert(t99)')
1332 if(any(dneq(
math_clip([4.0_preal,9.0_preal],5.0_preal,6.5_preal),[5.0_preal,6.5_preal]))) &
1333 call io_error(0,ext_msg=
'math_clip')
1336 call io_error(0,ext_msg=
'math_factorial')
1339 call io_error(0,ext_msg=
'math_binomial')
1341 ijk = cshift([1,2,3],int(r*1.0e2_preal))
1343 call io_error(0,ext_msg=
'math_LeviCivita(even)')
1344 ijk = cshift([3,2,1],int(r*2.0e2_preal))
1346 call io_error(0,ext_msg=
'math_LeviCivita(odd)')
1347 ijk = cshift([2,2,1],int(r*2.0e2_preal))
1349 call io_error(0,ext_msg=
'math_LeviCivita')