exchanged TINY (from prec) with intrinsic "tiny" function (Fortran90)

This commit is contained in:
Philip Eisenlohr 2008-02-15 12:42:27 +00:00
parent a41a4a75ef
commit cfaa0e696d
1 changed files with 484 additions and 374 deletions

View File

@ -3,6 +3,7 @@
MODULE math MODULE math
!############################################################## !##############################################################
use prec, only: pReal,pInt use prec, only: pReal,pInt
implicit none implicit none
@ -15,6 +16,7 @@
1.0_pReal,0.0_pReal,0.0_pReal, & 1.0_pReal,0.0_pReal,0.0_pReal, &
0.0_pReal,1.0_pReal,0.0_pReal, & 0.0_pReal,1.0_pReal,0.0_pReal, &
0.0_pReal,0.0_pReal,1.0_pReal /),(/3,3/)) 0.0_pReal,0.0_pReal,1.0_pReal /),(/3,3/))
! *** Mandel notation *** ! *** Mandel notation ***
integer(pInt), dimension (2,6), parameter :: mapMandel = & integer(pInt), dimension (2,6), parameter :: mapMandel = &
reshape((/& reshape((/&
@ -25,10 +27,12 @@
2,3, & 2,3, &
1,3 & 1,3 &
/),(/2,6/)) /),(/2,6/))
real(pReal), dimension(6), parameter :: nrmMandel = & real(pReal), dimension(6), parameter :: nrmMandel = &
(/1.0_pReal,1.0_pReal,1.0_pReal, 1.414213562373095_pReal, 1.414213562373095_pReal, 1.414213562373095_pReal/) (/1.0_pReal,1.0_pReal,1.0_pReal, 1.414213562373095_pReal, 1.414213562373095_pReal, 1.414213562373095_pReal/)
real(pReal), dimension(6), parameter :: invnrmMandel = & real(pReal), dimension(6), parameter :: invnrmMandel = &
(/1.0_pReal,1.0_pReal,1.0_pReal,0.7071067811865476_pReal,0.7071067811865476_pReal,0.7071067811865476_pReal/) (/1.0_pReal,1.0_pReal,1.0_pReal,0.7071067811865476_pReal,0.7071067811865476_pReal,0.7071067811865476_pReal/)
! *** Voigt notation *** ! *** Voigt notation ***
integer(pInt), dimension (2,6), parameter :: mapVoigt = & integer(pInt), dimension (2,6), parameter :: mapVoigt = &
reshape((/& reshape((/&
@ -39,11 +43,27 @@
1,3, & 1,3, &
1,2 & 1,2 &
/),(/2,6/)) /),(/2,6/))
real(pReal), dimension(6), parameter :: nrmVoigt = & real(pReal), dimension(6), parameter :: nrmVoigt = &
(/1.0_pReal,1.0_pReal,1.0_pReal, 1.0_pReal, 1.0_pReal, 1.0_pReal/) (/1.0_pReal,1.0_pReal,1.0_pReal, 1.0_pReal, 1.0_pReal, 1.0_pReal/)
real(pReal), dimension(6), parameter :: invnrmVoigt = & real(pReal), dimension(6), parameter :: invnrmVoigt = &
(/1.0_pReal,1.0_pReal,1.0_pReal, 1.0_pReal, 1.0_pReal, 1.0_pReal/) (/1.0_pReal,1.0_pReal,1.0_pReal, 1.0_pReal, 1.0_pReal, 1.0_pReal/)
! *** Plain notation ***
integer(pInt), dimension (2,9), parameter :: mapPlain = &
reshape((/&
1,1, &
1,2, &
1,3, &
2,1, &
2,2, &
2,3, &
3,1, &
3,2, &
3,3 &
/),(/2,9/))
CONTAINS CONTAINS
@ -96,7 +116,9 @@
d = size(a,1) ! number of linked data d = size(a,1) ! number of linked data
! set the starting and ending points, and the pivot point ! set the starting and ending points, and the pivot point
i = istart i = istart
j = iend j = iend
x = a(1,istart) x = a(1,istart)
do do
@ -164,13 +186,13 @@
END FUNCTION END FUNCTION
!************************************************************************** !**************************************************************************
! Cramer inversion of 3x3 matrix ! Cramer inversion of 3x3 matrix
!************************************************************************** !**************************************************************************
SUBROUTINE math_invert3x3(A, InvA, DetA, error) SUBROUTINE math_invert3x3(A, InvA, DetA, error)
! Bestimmung der Determinanten und Inversen einer 3x3-Matrix ! Bestimmung der Determinanten und Inversen einer 3x3-Matrix
! A = Matrix A ! A = Matrix A
! InvA = Inverse of A ! InvA = Inverse of A
! DetA = Determinant of A ! DetA = Determinant of A
@ -180,6 +202,7 @@
implicit none implicit none
logical, intent(out) :: error logical, intent(out) :: error
real(pReal),dimension(3,3),intent(in) :: A real(pReal),dimension(3,3),intent(in) :: A
real(pReal),dimension(3,3),intent(out) :: InvA real(pReal),dimension(3,3),intent(out) :: InvA
real(pReal), intent(out) :: DetA real(pReal), intent(out) :: DetA
@ -188,7 +211,7 @@
- A(1,2) * ( A(2,1) * A(3,3) - A(2,3) * A(3,1) )& - A(1,2) * ( A(2,1) * A(3,3) - A(2,3) * A(3,1) )&
+ A(1,3) * ( A(2,1) * A(3,2) - A(2,2) * A(3,1) ) + A(1,3) * ( A(2,1) * A(3,2) - A(2,2) * A(3,1) )
if (DetA <= 0.0000001) then if (DetA <= tiny(DetA)) then
error = .true. error = .true.
else else
InvA(1,1) = ( A(2,2) * A(3,3) - A(2,3) * A(3,2) ) / DetA InvA(1,1) = ( A(2,2) * A(3,3) - A(2,3) * A(3,2) ) / DetA
@ -210,13 +233,13 @@
END SUBROUTINE END SUBROUTINE
!************************************************************************** !**************************************************************************
! Gauss elimination to invert 6x6 matrix ! Gauss elimination to invert 6x6 matrix
!************************************************************************** !**************************************************************************
SUBROUTINE math_invert6x6(A, InvA, AnzNegEW, error) SUBROUTINE math_invert(dimen,A, InvA, AnzNegEW, error)
! Invertieren einer 6x6-Matrix
! Invertieren einer dimen x dimen - Matrix
! A = Matrix A ! A = Matrix A
! InvA = Inverse von A ! InvA = Inverse von A
! AnzNegEW = Anzahl der negativen Eigenwerte von A ! AnzNegEW = Anzahl der negativen Eigenwerte von A
@ -228,44 +251,42 @@
use prec, only: pReal,pInt use prec, only: pReal,pInt
implicit none implicit none
real(pReal),dimension(6,6), intent(in) :: A integer(pInt), intent(in) :: dimen
real(pReal),dimension(6,6), intent(out) :: InvA real(pReal),dimension(dimen,dimen), intent(in) :: A
real(pReal),dimension(dimen,dimen), intent(out) :: InvA
integer(pInt), intent(out) :: AnzNegEW integer(pInt), intent(out) :: AnzNegEW
logical, intent(out) :: error logical, intent(out) :: error
integer(pInt) i integer(pInt) i
real(pReal) LogAbsDetA real(pReal) LogAbsDetA
real(pReal),dimension(6,6) :: B real(pReal),dimension(dimen,dimen) :: B
InvA = 0.0_pReal InvA = math_identity2nd(dimen)
forall(i = 1:6) InvA(i,i) = 1.0_pReal
B = A B = A
CALL Gauss (B,InvA,LogAbsDetA,AnzNegEW,error) CALL Gauss(dimen,B,InvA,LogAbsDetA,AnzNegEW,error)
RETURN RETURN
END SUBROUTINE math_invert6x6 END SUBROUTINE math_invert
! ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
! ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SUBROUTINE Gauss (dimen,A,B,LogAbsDetA,NegHDK,error)
SUBROUTINE Gauss (A,B,LogAbsDetA,NegHDK,error)
! Loesung eines linearen Gleichungsssystem A * X = B mit Hilfe des ! Loesung eines linearen Gleichungsssystem A * X = B mit Hilfe des
! GAUSS-Algorithmusses ! GAUSS-Algorithmus
! Zur numerischen Stabilisierung wird eine Zeilen- und Spaltenpivotsuche ! Zur numerischen Stabilisierung wird eine Zeilen- und Spaltenpivotsuche
! durchgefuehrt. ! durchgefuehrt.
! Eingabeparameter: ! Eingabeparameter:
! !
! A(6,6) = Koeffizientenmatrix A ! A(dimen,dimen) = Koeffizientenmatrix A
! B(6,6) = rechte Seiten B ! B(dimen,dimen) = rechte Seiten B
! !
! Ausgabeparameter: ! Ausgabeparameter:
! !
! B(6,6) = Matrix der Unbekanntenvektoren X ! B(dimen,dimen) = Matrix der Unbekanntenvektoren X
! LogAbsDetA = 10-Logarithmus des Betrages der Determinanten von A ! LogAbsDetA = 10-Logarithmus des Betrages der Determinanten von A
! NegHDK = Anzahl der negativen Hauptdiagonalkoeffizienten nach der ! NegHDK = Anzahl der negativen Hauptdiagonalkoeffizienten nach der
! Vorwaertszerlegung ! Vorwaertszerlegung
@ -279,18 +300,19 @@
implicit none implicit none
logical error logical error
integer (pInt) NegHDK integer (pInt) dimen,NegHDK
real(pReal) LogAbsDetA real(pReal) LogAbsDetA
real(pReal) A(6,6), B(6,6) real(pReal) A(dimen,dimen), B(dimen,dimen)
INTENT (IN) dimen
INTENT (OUT) LogAbsDetA, NegHDK, error INTENT (OUT) LogAbsDetA, NegHDK, error
INTENT (INOUT) A, B INTENT (INOUT) A, B
LOGICAL SortX LOGICAL SortX
integer (pInt) PivotZeile, PivotSpalte, StoreI, I, IP1, J, K, L integer (pInt) PivotZeile, PivotSpalte, StoreI, I, IP1, J, K, L
integer (pInt) XNr(6) integer (pInt) XNr(dimen)
real(pReal) AbsA, PivotWert, EpsAbs, Quote real(pReal) AbsA, PivotWert, EpsAbs, Quote
real(pReal) StoreA(6), StoreB(6) real(pReal) StoreA(dimen), StoreB(dimen)
error = .true. error = .true.
NegHDK = 1 NegHDK = 1
@ -298,7 +320,7 @@
! Unbekanntennumerierung ! Unbekanntennumerierung
DO I = 1, 6 DO I = 1, dimen
XNr(I) = I XNr(I) = I
END DO END DO
@ -308,8 +330,8 @@
PivotZeile = 1 PivotZeile = 1
PivotSpalte = 1 PivotSpalte = 1
DO I = 1, 6 DO I = 1, dimen
DO J = 1, 6 DO J = 1, dimen
AbsA = ABS(A(I,J)) AbsA = ABS(A(I,J))
IF (AbsA .GT. PivotWert) THEN IF (AbsA .GT. PivotWert) THEN
PivotWert = AbsA PivotWert = AbsA
@ -325,61 +347,44 @@
! V O R W A E R T S T R I A N G U L A T I O N ! V O R W A E R T S T R I A N G U L A T I O N
DO I = 1, 6 - 1 DO I = 1, dimen - 1
! Zeilentausch? ! Zeilentausch?
IF (PivotZeile .NE. I) THEN IF (PivotZeile .NE. I) THEN
StoreA(I:dimen) = A(I,I:dimen)
StoreA(I:6) = A(I,I:6) A(I,I:dimen) = A(PivotZeile,I:dimen)
A(I,I:6) = A(PivotZeile,I:6) A(PivotZeile,I:dimen) = StoreA(I:dimen)
A(PivotZeile,I:6) = StoreA(I:6) StoreB(1:dimen) = B(I,1:dimen)
B(I,1:dimen) = B(PivotZeile,1:dimen)
StoreB(1:6) = B(I,1:6) B(PivotZeile,1:dimen) = StoreB(1:dimen)
B(I,1:6) = B(PivotZeile,1:6)
B(PivotZeile,1:6) = StoreB(1:6)
SortX = .TRUE. SortX = .TRUE.
END IF END IF
! Spaltentausch? ! Spaltentausch?
IF (PivotSpalte .NE. I) THEN IF (PivotSpalte .NE. I) THEN
StoreA(1:dimen) = A(1:dimen,I)
StoreA(1:6) = A(1:6,I) A(1:dimen,I) = A(1:dimen,PivotSpalte)
A(1:6,I) = A(1:6,PivotSpalte) A(1:dimen,PivotSpalte) = StoreA(1:dimen)
A(1:6,PivotSpalte) = StoreA(1:6)
StoreI = XNr(I) StoreI = XNr(I)
XNr(I) = XNr(PivotSpalte) XNr(I) = XNr(PivotSpalte)
XNr(PivotSpalte) = StoreI XNr(PivotSpalte) = StoreI
SortX = .TRUE. SortX = .TRUE.
END IF END IF
! Triangulation ! Triangulation
DO J = I + 1, dimen
DO J = I + 1, 6
Quote = A(J,I) / A(I,I) Quote = A(J,I) / A(I,I)
DO K = I + 1, 6 DO K = I + 1, dimen
A(J,K) = A(J,K) - Quote * A(I,K) A(J,K) = A(J,K) - Quote * A(I,K)
END DO END DO
DO K = 1, 6 DO K = 1, dimen
B(J,K) = B(J,K) - Quote * B(I,K) B(J,K) = B(J,K) - Quote * B(I,K)
END DO END DO
END DO END DO
! Bestimmung des groessten Pivotelementes ! Bestimmung des groessten Pivotelementes
IP1 = I + 1 IP1 = I + 1
PivotWert = ABS(A(IP1,IP1)) PivotWert = ABS(A(IP1,IP1))
PivotZeile = IP1 PivotZeile = IP1
PivotSpalte = IP1 PivotSpalte = IP1
DO J = IP1, dimen
DO J = IP1, 6 DO K = IP1, dimen
DO K = IP1, 6
AbsA = ABS(A(J,K)) AbsA = ABS(A(J,K))
IF (AbsA .GT. PivotWert) THEN IF (AbsA .GT. PivotWert) THEN
PivotWert = AbsA PivotWert = AbsA
@ -395,9 +400,9 @@
! R U E C K W A E R T S A U F L O E S U N G ! R U E C K W A E R T S A U F L O E S U N G
DO I = 6, 1, -1 DO I = dimen, 1, -1
DO L = 1, 6 DO L = 1, dimen
DO J = I + 1, 6 DO J = I + 1, dimen
B(I,L) = B(I,L) - A(I,J) * B(J,L) B(I,L) = B(I,L) - A(I,J) * B(J,L)
END DO END DO
B(I,L) = B(I,L) / A(I,I) B(I,L) = B(I,L) / A(I,I)
@ -407,10 +412,9 @@
! Sortieren der Unbekanntenvektoren? ! Sortieren der Unbekanntenvektoren?
IF (SortX) THEN IF (SortX) THEN
DO L = 1, dimen
DO L = 1, 6 StoreA(1:dimen) = B(1:dimen,L)
StoreA(1:6) = B(1:6,L) DO I = 1, dimen
DO I = 1, 6
J = XNr(I) J = XNr(I)
B(J,L) = StoreA(I) B(J,L) = StoreA(I)
END DO END DO
@ -422,7 +426,7 @@
LogAbsDetA = 0.0_pReal LogAbsDetA = 0.0_pReal
NegHDK = 0 NegHDK = 0
DO I = 1, 6 DO I = 1, dimen
IF (A(I,I) .LT. 0.0_pReal) NegHDK = NegHDK + 1 IF (A(I,I) .LT. 0.0_pReal) NegHDK = NegHDK + 1
AbsA = ABS(A(I,I)) AbsA = ABS(A(I,I))
LogAbsDetA = LogAbsDetA + LOG10(AbsA) LogAbsDetA = LogAbsDetA + LOG10(AbsA)
@ -435,6 +439,41 @@
END SUBROUTINE Gauss END SUBROUTINE Gauss
!********************************************************************
! symmetrize a 3x3 matrix
!********************************************************************
FUNCTION math_symmetric3x3(m)
use prec, only: pReal,pInt
implicit none
real(pReal), dimension(3,3) :: math_symmetric3x3,m
integer(pInt) i,j
forall (i=1:3,j=1:3) math_symmetric3x3(i,j) = 1.0_pReal/2.0_pReal * &
(m(i,j) + m(j,i))
END FUNCTION
!********************************************************************
! symmetrize a 6x6 matrix
!********************************************************************
FUNCTION math_symmetric6x6(m)
use prec, only: pReal,pInt
implicit none
real(pReal), dimension(6,6) :: math_symmetric6x6,m
integer(pInt) i,j
forall (i=1:6,j=1:6) math_symmetric6x6(i,j) = 1.0_pReal/2.0_pReal * &
(m(i,j) + m(j,i))
END FUNCTION
!******************************************************************** !********************************************************************
! determinant of a 3x3 matrix ! determinant of a 3x3 matrix
!******************************************************************** !********************************************************************
@ -453,6 +492,42 @@
END FUNCTION END FUNCTION
!********************************************************************
! convert 3x3 matrix into vector 9x1
!********************************************************************
FUNCTION math_Plain33to9(m33)
use prec, only: pReal,pInt
implicit none
real(pReal), dimension(3,3) :: m33
real(pReal), dimension(9) :: math_Plain33to9
integer(pInt) i
forall (i=1:9) math_Plain33to9(i) = m33(mapPlain(1,i),mapPlain(2,i))
return
END FUNCTION
!********************************************************************
! convert Plain 9x1 back to 3x3 matrix
!********************************************************************
FUNCTION math_Plain9to33(v9)
use prec, only: pReal,pInt
implicit none
real(pReal), dimension(9) :: v9
real(pReal), dimension(3,3) :: math_Plain9to33
integer(pInt) i
forall (i=1:9) math_Plain9to33(mapPlain(1,i),mapPlain(2,i)) = v9(i)
return
END FUNCTION
!******************************************************************** !********************************************************************
! convert symmetric 3x3 matrix into Mandel vector 6x1 ! convert symmetric 3x3 matrix into Mandel vector 6x1
!******************************************************************** !********************************************************************
@ -492,6 +567,25 @@
END FUNCTION END FUNCTION
!********************************************************************
! convert 3x3x3x3 tensor into plain matrix 9x9
!********************************************************************
FUNCTION math_Plain3333to99(m3333)
use prec, only: pReal,pInt
implicit none
real(pReal), dimension(3,3,3,3) :: m3333
real(pReal), dimension(9,9) :: math_Plain3333to99
integer(pInt) i,j
forall (i=1:9,j=1:9) math_Plain3333to99(i,j) = &
m3333(mapPlain(1,i),mapPlain(2,i),mapPlain(1,j),mapPlain(2,j))
return
END FUNCTION
!******************************************************************** !********************************************************************
! convert symmetric 3x3x3x3 tensor into Mandel matrix 6x6 ! convert symmetric 3x3x3x3 tensor into Mandel matrix 6x6
!******************************************************************** !********************************************************************
@ -534,6 +628,7 @@
END FUNCTION END FUNCTION
!******************************************************************** !********************************************************************
! convert Voigt matrix 6x6 back to symmetric 3x3x3x3 tensor ! convert Voigt matrix 6x6 back to symmetric 3x3x3x3 tensor
!******************************************************************** !********************************************************************
@ -557,6 +652,7 @@
END FUNCTION END FUNCTION
!******************************************************************** !********************************************************************
! Euler angles from orientation matrix ! Euler angles from orientation matrix
!******************************************************************** !********************************************************************
@ -726,11 +822,16 @@
real(pReal) noise,scatter,cosScatter real(pReal) noise,scatter,cosScatter
integer(pInt) i integer(pInt) i
if (noise==0.0) then if (noise==0.0) then
math_sampleGaussOri = center math_sampleGaussOri = center
return return
endif endif
! Helming uses different distribution with Bessel functions ! Helming uses different distribution with Bessel functions
! therefore the gauss scatter width has to be scaled differently ! therefore the gauss scatter width has to be scaled differently
scatter = 0.95_pReal * noise scatter = 0.95_pReal * noise
@ -824,10 +925,16 @@ endif
END FUNCTION END FUNCTION
!******************************************************************** !********************************************************************
! symmetric Euler angles for given symmetry string ! symmetric Euler angles for given symmetry string
! 'triclinic' or '', 'monoclinic', 'orthotropic' ! 'triclinic' or '', 'monoclinic', 'orthotropic'
!******************************************************************** !********************************************************************
PURE FUNCTION math_symmetricEulers(sym,Euler) PURE FUNCTION math_symmetricEulers(sym,Euler)
use prec, only: pReal, pInt use prec, only: pReal, pInt
@ -857,14 +964,17 @@ endif
case ('monoclinic') ! return only first case ('monoclinic') ! return only first
math_symmetricEulers(:,2:3) = 0.0_pReal math_symmetricEulers(:,2:3) = 0.0_pReal
case default ! return blank case default ! return blank
math_symmetricEulers = 0.0_pReal math_symmetricEulers = 0.0_pReal
end select end select
return return
END FUNCTION END FUNCTION
!**************************************************************** !****************************************************************
subroutine math_pDecomposition(FE,U,R,error) subroutine math_pDecomposition(FE,U,R,error)
!-----FE=RU !-----FE=RU