summaryrefslogtreecommitdiff
path: root/Utilib/src/ALTERI.f
blob: 8d3a246fd69f57daecdab57339c5b5460e3a5de0 (plain)
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
*DECK ALTERI
      SUBROUTINE ALTERI(LCUBIC,N,X,VAL0,VAL1,TERP)
*
*-----------------------------------------------------------------------
*
*Purpose:
* determination of the TERP integration components using the order 4
* Ceschino method with cubic Hermite polynomials.
*
*Copyright:
* Copyright (C) 2006 Ecole Polytechnique de Montreal
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version
*
*Author(s): A. Hebert
*
*Parameters: input
* LCUBIC  =.TRUE.: cubic Ceschino interpolation; =.FALSE: linear
*         Lagrange interpolation.
* N       number of points.
* X       abscissas
* VAL0    left integration limit.
* VAL1    right integration limit.
*
*Parameters: output
* TERP    integration components.
*
*-----------------------------------------------------------------------
*
*----
*  SUBROUTINE ARGUMENTS
*----
      LOGICAL LCUBIC
      INTEGER N
      REAL X(N),VAL0,VAL1,TERP(N)
*----
*  LOCAL VARIABLES
*----
      REAL UU(2)
      REAL, ALLOCATABLE, DIMENSION(:,:) :: WK
*
      IF(N.LE.1) CALL XABORT('ALTERI: INVALID NUMBER OF POINTS.')
      IF(VAL1.LE.VAL0) CALL XABORT('ALTERI: INVALID LIMITS.')
      IF((VAL0.LT.X(1)).OR.(VAL1.GT.X(N))) CALL XABORT('ALTERI: UNABLE'
     1 //' TO INTEGRATE.')
      IF(N.EQ.2) GO TO 110
      DO 10 I=1,N
      TERP(I)=0.0
   10 CONTINUE
*----
*  LINEAR LAGRANGE POLYNOMIALS.
*----
      IF(.NOT.LCUBIC) THEN
         DO 15 I0=1,N-1
         IF((VAL0.LT.X(I0+1)).AND.(VAL1.GT.X(I0))) THEN
            A=MAX(VAL0,X(I0))
            B=MIN(VAL1,X(I0+1))
            DX=X(I0+1)-X(I0)
            TERP(I0)=TERP(I0)+(X(I0+1)-0.5*(A+B))*(B-A)/DX
            TERP(I0+1)=TERP(I0+1)+(0.5*(A+B)-X(I0))*(B-A)/DX
         ENDIF
   15    CONTINUE
         RETURN
      ENDIF
*----
*  CESCHINO CUBIC POLYNOMIALS.
*----
      ALLOCATE(WK(3,N))
      DO 16 I=1,N
      WK(3,I)=0.0
   16 CONTINUE
      DO 30 I0=1,N-1
      IF((VAL0.LT.X(I0+1)).AND.(VAL1.GT.X(I0))) THEN
         A=MAX(VAL0,X(I0))
         B=MIN(VAL1,X(I0+1))
         CC=0.5*(B-A)
         DX=X(I0+1)-X(I0)
         U1=(A-0.5*(X(I0)+X(I0+1)))/DX
         U2=(B-0.5*(X(I0)+X(I0+1)))/DX
         UU(1)=0.5*(-(U2-U1)*0.577350269189626+U1+U2)
         UU(2)=0.5*((U2-U1)*0.577350269189626+U1+U2)
         DO 20 JS=1,2
         H1=(3.0*(0.5-UU(JS))**2-2.0*(0.5-UU(JS))**3)*CC
         H2=((0.5-UU(JS))**2-(0.5-UU(JS))**3)*CC
         H3=(3.0*(0.5+UU(JS))**2-2.0*(0.5+UU(JS))**3)*CC
         H4=(-(0.5+UU(JS))**2+(0.5+UU(JS))**3)*CC
         TERP(I0)=TERP(I0)+H1
         TERP(I0+1)=TERP(I0+1)+H3
         WK(3,I0)=WK(3,I0)+H2*DX
         WK(3,I0+1)=WK(3,I0+1)+H4*DX
   20    CONTINUE
      ENDIF
   30 CONTINUE
*----
*  COMPUTE THE COEFFICIENT MATRIX.
*----
      HP=1.0/(X(2)-X(1))
      WK(1,1)=HP
      WK(2,1)=HP
      DO 40 I=2,N-1
      HM=HP
      HP=1.0/(X(I+1)-X(I))
      WK(1,I)=2.0*(HM+HP)
      WK(2,I)=HP
   40 CONTINUE
      WK(1,N)=HP
      WK(2,N)=HP
*----
*  FORWARD ELIMINATION.
*----
      PMX=WK(1,1)
      WK(3,1)=WK(3,1)/PMX
      DO 50 I=2,N
      GAR=WK(2,I-1)
      WK(2,I-1)=WK(2,I-1)/PMX
      PMX=WK(1,I)-GAR*WK(2,I-1)
      WK(3,I)=(WK(3,I)-GAR*WK(3,I-1))/PMX
   50 CONTINUE
*----
*  BACK SUBSTITUTION.
*----
      DO 60 I=N-1,1,-1
      WK(3,I)=WK(3,I)-WK(2,I)*WK(3,I+1)
   60 CONTINUE
*----
*  COMPUTE THE INTERPOLATION FACTORS.
*----
      TEST=1.0
      DO 100 J=1,N
      IMIN=MAX(2,J-1)
      IMAX=MIN(N-1,J+1)
      DO 70 I=1,N
      WK(1,I)=0.0
   70 CONTINUE
      WK(1,J)=1.0
      HP=1.0/(X(2)-X(1))
      YLAST=WK(1,IMIN-1)
      WK(1,IMIN-1)=2.0*HP*HP*(WK(1,IMIN)-WK(1,IMIN-1))
      DO 80 I=IMIN,IMAX
      HM=HP
      HP=1.0/(X(I+1)-X(I))
      PMX=3.0*(HM*HM*(WK(1,I)-YLAST)+HP*HP*(WK(1,I+1)-WK(1,I)))
      YLAST=WK(1,I)
      WK(1,I)=PMX
   80 CONTINUE
      WK(1,IMAX+1)=2.0*HP*HP*(WK(1,IMAX+1)-YLAST)
      DO 90 I=IMIN-1,IMAX+1
      TERP(J)=TERP(J)+WK(1,I)*WK(3,I)
   90 CONTINUE
      IF(ABS(TERP(J)).LE.1.0E-7) TERP(J)=0.0
      TEST=TEST-TERP(J)/(VAL1-VAL0)
  100 CONTINUE
      IF(ABS(TEST).GT.1.0E-5) CALL XABORT('ALTERI: WRONG TERP FACTORS.')
      DEALLOCATE(WK)
      RETURN
*
  110 TERP(1)=(X(2)-0.5*(VAL0+VAL1))*(VAL1-VAL0)/(X(2)-X(1))
      TERP(2)=(0.5*(VAL0+VAL1)-X(1))*(VAL1-VAL0)/(X(2)-X(1))
      RETURN
      END