Files
sics/difrac/matrix.f
2000-02-18 15:54:23 +00:00

235 lines
8.6 KiB
Fortran

C-----------------------------------------------------------------------
C Library of matrix operations for crystal geometry
C-----------------------------------------------------------------------
SUBROUTINE MATRIX(A,B,C,D,IWHAT)
COMMON /IOUASS/ IOUNIT(12)
CHARACTER COUT*132
COMMON /IOUASC/ COUT(20)
CHARACTER*6 IWHAT
DIMENSION A(3,3),B(3,3),C(3,3),D(3,3),E(3,3),V(3)
DATA RA/57.29578/
IF (IWHAT .EQ. 'INVERT') GO TO 100
IF (IWHAT .EQ. 'MATMUL') GO TO 120
IF (IWHAT .EQ. 'MATVEC') GO TO 150
IF (IWHAT .EQ. 'VECMAT') GO TO 180
IF (IWHAT .EQ. 'SCALPR') GO TO 210
IF (IWHAT .EQ. 'LENGTH') GO TO 230
IF (IWHAT .EQ. 'ORTHOG') GO TO 250
IF (IWHAT .EQ. 'DETERM') GO TO 270
IF (IWHAT .EQ. 'MVMULT') GO TO 290
IF (IWHAT .EQ. 'VMMULT') GO TO 320
IF (IWHAT .EQ. 'TRNSPS') GO TO 340
IF (IWHAT .EQ. 'SYMOPR') GO TO 370
IF (IWHAT .EQ. 'VECPRD') GO TO 400
IF (IWHAT .EQ. 'COPRIM') GO TO 410
IF (IWHAT .EQ. 'INTRCH') GO TO 440
IF (IWHAT .EQ. 'SUMVEC') GO TO 460
IF (IWHAT .EQ. 'DIFVEC') GO TO 480
IF (IWHAT .EQ. 'COPVEC') GO TO 500
ITP = IOUNIT(6)
WRITE (COUT,10000) IWHAT
CALL GWRITE (ITP,' ')
STOP
C-----------------------------------------------------------------------
C Invert 3x3 matrix A, put the result in B
C-----------------------------------------------------------------------
100 E(1,1) = A(2,2)*A(3,3) - A(2,3)*A(3,2)
E(2,1) = -(A(2,1)*A(3,3) - A(2,3)*A(3,1))
E(3,1) = A(2,1)*A(3,2) - A(2,2)*A(3,1)
E(1,2) = -(A(1,2)*A(3,3) - A(1,3)*A(3,2))
E(2,2) = A(1,1)*A(3,3) - A(1,3)*A(3,1)
E(3,2) = -(A(1,1)*A(3,2) - A(1,2)*A(3,1))
E(1,3) = A(1,2)*A(2,3) - A(1,3)*A(2,2)
E(2,3) = -(A(1,1)*A(2,3) - A(1,3)*A(2,1))
E(3,3) = A(1,1)*A(2,2) - A(1,2)*A(2,1)
DMAT = A(1,1)*E(1,1) + A(1,2)*E(2,1) + A(1,3)*E(3,1)
DO 115 I=1,3
DO 110 J = 1,3
110 B(I,J) = E(I,J)/DMAT
115 CONTINUE
GO TO 520
C-----------------------------------------------------------------------
C Multiply 3x3 matrices A and B, store result in C
C-----------------------------------------------------------------------
120 DO 135 I = 1,3
DO 132 J = 1,3
E(I,J) = 0.0
DO 130 K = 1,3
130 E(I,J) = E(I,J) + A(I,K)*B(K,J)
132 CONTINUE
135 CONTINUE
DO 145 I = 1,3
DO 140 J = 1,3
140 C(I,J) = E(I,J)
145 CONTINUE
GO TO 520
C-----------------------------------------------------------------------
C Multiply matrix A by vector B, store dir. cosines of result in C
C-----------------------------------------------------------------------
150 DO 165 I = 1,3
V(I) = 0.
DO 160 J = 1,3
160 V(I) = V(I) + A(I,J)*B(J,1)
165 CONTINUE
IF(V(1)**2 + V(2)**2 +V(3)**2 .GT. 0) THEN
VMOD = SQRT(V(1)**2 + V(2)**2 + V(3)**2)
ELSE
VMOD = 1
ENDIF
DO 170 I = 1,3
170 C(I,1) = V(I)/VMOD
GO TO 520
C-----------------------------------------------------------------------
C Multiply vector A by matrix B, store dir. cosines of result in C
C-----------------------------------------------------------------------
180 DO 195 I = 1,3
V(I) = 0.
DO 190 J = 1,3
190 V(I) = V(I) + B(J,I)*A(J,1)
195 CONTINUE
VMOD = SQRT(V(1)**2 + V(2)**2 + V(3)**2)
DO 200 I = 1,3
200 C(I,1) = V(I)/VMOD
GO TO 520
C-----------------------------------------------------------------------
C Scalar product of vectors A and B
C-----------------------------------------------------------------------
210 S = 0
DO 220 I = 1,3
220 S = S + A(I,1)*B(I,1)
C(1,1) = S
GO TO 520
C-----------------------------------------------------------------------
C length of vector B when A is the metric matrix
C-----------------------------------------------------------------------
230 DO 245 I = 1,3
V(I) = 0.
DO 240 J = 1,3
240 V(I) = V(I) + A(I,J)*B(J,1)
245 CONTINUE
C(1,1) = SQRT(V(1)**2 + V(2)**2 + V(3)**2)
GO TO 520
C-----------------------------------------------------------------------
C Get the metric matrix C corresponding to cell edges A & angles B
C-----------------------------------------------------------------------
250 COSGAS = (COS(B(1,1)/RA)*COS(B(2,1)/RA) - COS(B(3,1)/RA))
COSGAS = COSGAS/(SIN(B(1,1)/RA)*SIN(B(2,1)/RA))
SINGAS = SQRT(1.0 - COSGAS**2)
E(1,1) = A(1,1)*SIN(B(2,1)/RA)*SINGAS
E(1,2) = 0
E(1,3) = 0
E(2,1) = -A(1,1)*SIN(B(2,1)/RA)*COSGAS
E(2,2) = A(2,1)*SIN(B(1,1)/RA)
E(2,3) = 0
E(3,1) = A(1,1)*COS(B(2,1)/RA)
E(3,2) = A(2,1)*COS(B(1,1)/RA)
E(3,3) = A(3,1)
DO 265 I = 1,3
DO 260 J = 1,3
260 C(I,J) = E(I,J)
265 CONTINUE
GO TO 520
C-----------------------------------------------------------------------
C Calculate the determinant D of the vectors A,B,C
C-----------------------------------------------------------------------
270 DET = 0.
DO 280 I = 1,3
J = I + 1
IF (J .EQ. 4) J = 1
K = 6 - I - J
280 DET = DET + A(I,1)*(B(J,1)*C(K,1) - B(K,1)*C(J,1))
D(1,1) = DET
GO TO 520
C-----------------------------------------------------------------------
C Multiply matrix A by vector B, store result in C
C-----------------------------------------------------------------------
290 DO 305 I = 1,3
E(I,1) = 0
DO 300 J = 1,3
300 E(I,1) = E(I,1) + A(I,J)*B(J,1)
305 CONTINUE
DO 310 I = 1,3
310 C(I,1) = E(I,1)
GO TO 520
C-----------------------------------------------------------------------
C Multiply vector A by matrix B, store result in C
C-----------------------------------------------------------------------
320 DO 335 I = 1,3
C(I,1) = 0.
DO 330 J = 1,3
330 C(I,1) = C(I,1) + A(J,1)*B(J,I)
335 CONTINUE
GO TO 520
C-----------------------------------------------------------------------
Ctranspose matrix A and put it in B
C-----------------------------------------------------------------------
340 DO 355 I = 1,3
DO 350 J = 1,3
350 E(I,J) = A(J,I)
355 CONTINUE
DO 365 I = 1,3
DO 360 J = 1,3
360 B(I,J) = E(I,J)
365 CONTINUE
GO TO 520
C-----------------------------------------------------------------------
C Get the symmetry-equivalent of an atom
C-----------------------------------------------------------------------
370 DO 390 I = 1,3
C(I,1) = 0.
DO 380 J = 1,3
380 C(I,1) = C(I,1) + A(I,J)*B(J,1)
J = 4
390 C(I,1) = C(I,1) + A(I,J)/12.
GO TO 520
C-----------------------------------------------------------------------
C Vector product C = A x B
C-----------------------------------------------------------------------
400 C(1,1) = A(2,1)*B(3,1) - A(3,1)*B(2,1)
C(2,1) = A(3,1)*B(1,1) - A(1,1)*B(3,1)
C(3,1) = A(1,1)*B(2,1) - A(2,1)*B(1,1)
GO TO 520
C-----------------------------------------------------------------------
C Make coprime integers (the smallest non-zero integer will be 1)
C-----------------------------------------------------------------------
410 SMALL = 2.
DO 420 I = 1,3
IF (ABS(A(I,1)) .LE. 0.1 .OR. ABS(A(I,1)) .GE. SMALL) GO TO 420
SMALL = ABS(A(I,1))
420 CONTINUE
DO 430 I = 1,3
INDEX = A(I,1)/SMALL + 0.5
IF (A(I,1) .LT. 0.) INDEX = A(I,1)/SMALL - 0.5
430 B(I,1) = INDEX
GO TO 520
C-----------------------------------------------------------------------
C Interchange two vectors A and B
C-----------------------------------------------------------------------
440 DO 450 I = 1,3
SAVE = A(I,1)
A(I,1) = B(I,1)
450 B(I,1) = SAVE
GO TO 520
C-----------------------------------------------------------------------
C Sum of vectors C = A + B
C-----------------------------------------------------------------------
460 DO 470 I = 1,3
470 C(I,1) = A(I,1) + B(I,1)
GO TO 520
C-----------------------------------------------------------------------
C Vector difference C = A - B
C-----------------------------------------------------------------------
480 DO 490 I = 1,3
490 C(I,1) = A(I,1) - B(I,1)
GO TO 520
C-----------------------------------------------------------------------
C Vector copy B = A
C-----------------------------------------------------------------------
500 DO 510 I = 1,3
510 B(I,1) = A(I,1)
GO TO 520
520 RETURN
10000 FORMAT(' Matrix operation ',A6,' is not programmed')
END