1 |
jahn |
1.1 |
C $Header$ |
2 |
|
|
C $Name$ |
3 |
|
|
|
4 |
|
|
#include "CPP_OPTIONS.h" |
5 |
|
|
|
6 |
|
|
CBOP |
7 |
|
|
C !ROUTINE: SOLVE_TRIDIAGONAL_PIVOT |
8 |
|
|
C !INTERFACE: |
9 |
|
|
SUBROUTINE SOLVE_TRIDIAGONAL_PIVOT( |
10 |
|
|
U a3d, b3d, c3d, |
11 |
|
|
U y3d, |
12 |
|
|
I n, myThid ) |
13 |
|
|
C !DESCRIPTION: \bv |
14 |
|
|
C *==========================================================* |
15 |
|
|
C | S/R SOLVE_TRIDIAGONAL_PIVOT |
16 |
|
|
C | o Solve a tri-diagonal system A*X=Y (dimension n) |
17 |
|
|
C | by Gaussian elimination with pivoting |
18 |
|
|
C *==========================================================* |
19 |
|
|
C | o input arrays are overwritten |
20 |
|
|
C | o result is returned in y3d |
21 |
|
|
C *==========================================================* |
22 |
|
|
C \ev |
23 |
|
|
|
24 |
|
|
C !USES: |
25 |
|
|
IMPLICIT NONE |
26 |
|
|
C == Global data == |
27 |
|
|
#include "SIZE.h" |
28 |
|
|
|
29 |
|
|
C !INPUT/OUTPUT PARAMETERS: |
30 |
|
|
C == Routine Arguments == |
31 |
|
|
C a3d(2:n) :: matrix lower diagnonal |
32 |
|
|
C b3d(1:n) :: matrix main diagnonal |
33 |
|
|
C c3d(1:n-1) :: matrix upper diagnonal |
34 |
|
|
C y3d(1:n) :: Input = Y vector ; Output = X = solution of A*X=Y |
35 |
|
|
_RL a3d(2*Nr) |
36 |
|
|
_RL b3d(2*Nr) |
37 |
|
|
_RL c3d(2*Nr) |
38 |
|
|
_RL y3d(2*Nr) |
39 |
|
|
INTEGER n,myThid |
40 |
|
|
CEOP |
41 |
|
|
|
42 |
|
|
C !LOCAL VARIABLES: |
43 |
|
|
C == Local variables == |
44 |
|
|
INTEGER k |
45 |
|
|
_RL tmpc, tmpy |
46 |
|
|
_RL recVar |
47 |
|
|
C d3d(1:Nr-2) :: second upper diagnonal, generated by pivoting |
48 |
|
|
_RL d3d(2*Nr) |
49 |
|
|
|
50 |
|
|
c3d(n) = 0. |
51 |
|
|
|
52 |
|
|
c eliminate lower diagonal |
53 |
|
|
c only c3d, d3d and y3d are modified and will be used later |
54 |
|
|
DO k=1,n-1 |
55 |
|
|
IF(ABS(b3d(k)).GE.ABS(a3d(k+1)))THEN |
56 |
|
|
c scale current row, subtract from next |
57 |
|
|
recVar = 1. / b3d(k) |
58 |
|
|
c3d(k) = c3d(k)*recVar |
59 |
|
|
y3d(k) = y3d(k)*recVar |
60 |
|
|
b3d(k+1) = b3d(k+1) - a3d(k+1)*c3d(k) |
61 |
|
|
y3d(k+1) = y3d(k+1) - a3d(k+1)*y3d(k) |
62 |
|
|
d3d(k) = 0. |
63 |
|
|
ELSE |
64 |
|
|
c swap rows, then scale current and subtract from next |
65 |
|
|
recVar = 1. / a3d(k+1) |
66 |
|
|
tmpc = c3d(k) |
67 |
|
|
tmpy = y3d(k) |
68 |
|
|
c3d(k) = b3d(k+1)*recVar |
69 |
|
|
d3d(k) = c3d(k+1)*recVar |
70 |
|
|
y3d(k) = y3d(k+1)*recVar |
71 |
|
|
b3d(k+1) = tmpc - b3d(k)*c3d(k) |
72 |
|
|
c3d(k+1) = - b3d(k)*d3d(k) |
73 |
|
|
y3d(k+1) = tmpy - b3d(k)*y3d(k) |
74 |
|
|
ENDIF |
75 |
|
|
ENDDO |
76 |
|
|
recVar = 1. / b3d(n) |
77 |
|
|
y3d(n) = y3d(n)*recVar |
78 |
|
|
|
79 |
|
|
c backsubstitute |
80 |
|
|
c y3d(n) is already good |
81 |
|
|
y3d(n-1) = y3d(n-1) - c3d(n-1)*y3d(n) |
82 |
|
|
DO k=n-2,1,-1 |
83 |
|
|
y3d(k) = y3d(k) - c3d(k)*y3d(k+1) - d3d(k)*y3d(k+2) |
84 |
|
|
ENDDO |
85 |
|
|
|
86 |
|
|
RETURN |
87 |
|
|
END |
88 |
|
|
|