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 |
|