-
Notifications
You must be signed in to change notification settings - Fork 19
/
example_mat_mod.F90
57 lines (39 loc) · 1.66 KB
/
example_mat_mod.F90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
module example_mat_mod
implicit none
private
public :: matrix3x3_inverse
public operator(.cross.)
interface operator(.cross.)
module procedure cross_product
end interface
contains
!% Return the scalar triple product $\mathbf{x} \cdot \mathbf{y} \times \mathbf{z}$
!% of the 3-vectors 'x', 'y' and 'z'.
pure function scalar_triple_product(x,y,z) ! [x,y,z]
double precision, dimension(3), intent(in) :: x,y,z
double precision :: scalar_triple_product
scalar_triple_product = + x(1) * ( y(2)*z(3) - y(3)*z(2) ) &
- x(2) * ( y(1)*z(3) - y(3)*z(1) ) &
+ x(3) * ( y(1)*z(2) - y(2)*z(1) )
end function scalar_triple_product
pure function cross_product(x,y) ! x ^ y
double precision, dimension(3), intent(in):: x,y
double precision, dimension(3) :: cross_product
cross_product(1) = + ( x(2)*y(3) - x(3)*y(2) )
cross_product(2) = - ( x(1)*y(3) - x(3)*y(1) )
cross_product(3) = + ( x(1)*y(2) - x(2)*y(1) )
end function cross_product
! Matrix3x3_Inverse
!
!% Calculate $3\times3$ matrix inverse of 'lattice' and store result in 'g'.
!% Avoids overhead of calling \textsc{lapack} for simple case of $3\times3$ matrix.
subroutine matrix3x3_inverse(matrix, g)
double precision, intent(in) :: matrix(3,3)
double precision, intent(out) :: g(3,3)
double precision :: stp
stp = scalar_triple_product(matrix(:,1), matrix(:,2), matrix(:,3))
g(1,:) = (matrix(:,2) .cross. matrix(:,3))/stp
g(2,:) = (matrix(:,3) .cross. matrix(:,1))/stp
g(3,:) = (matrix(:,1) .cross. matrix(:,2))/stp
end subroutine matrix3x3_inverse
end module example_mat_mod