1 | |
---|
2 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
3 | SUBROUTINE KppDecomp( JVS, IER ) |
---|
4 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
5 | ! Sparse LU factorization |
---|
6 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
7 | |
---|
8 | USE KPP_ROOT_Parameters |
---|
9 | USE KPP_ROOT_JacobianSP |
---|
10 | |
---|
11 | INTEGER :: IER |
---|
12 | KPP_REAL :: JVS(LU_NONZERO), W(NVAR), a |
---|
13 | INTEGER :: k, kk, j, jj |
---|
14 | |
---|
15 | a = 0. ! mz_rs_20050606 |
---|
16 | IER = 0 |
---|
17 | DO k=1,NVAR |
---|
18 | ! mz_rs_20050606: don't check if real value == 0 |
---|
19 | ! IF ( JVS( LU_DIAG(k) ) .EQ. 0. ) THEN |
---|
20 | IF ( ABS(JVS(LU_DIAG(k))) < TINY(a) ) THEN |
---|
21 | IER = k |
---|
22 | RETURN |
---|
23 | END IF |
---|
24 | DO kk = LU_CROW(k), LU_CROW(k+1)-1 |
---|
25 | W( LU_ICOL(kk) ) = JVS(kk) |
---|
26 | END DO |
---|
27 | DO kk = LU_CROW(k), LU_DIAG(k)-1 |
---|
28 | j = LU_ICOL(kk) |
---|
29 | a = -W(j) / JVS( LU_DIAG(j) ) |
---|
30 | W(j) = -a |
---|
31 | DO jj = LU_DIAG(j)+1, LU_CROW(j+1)-1 |
---|
32 | W( LU_ICOL(jj) ) = W( LU_ICOL(jj) ) + a*JVS(jj) |
---|
33 | END DO |
---|
34 | END DO |
---|
35 | DO kk = LU_CROW(k), LU_CROW(k+1)-1 |
---|
36 | JVS(kk) = W( LU_ICOL(kk) ) |
---|
37 | END DO |
---|
38 | END DO |
---|
39 | |
---|
40 | END SUBROUTINE KppDecomp |
---|
41 | |
---|
42 | |
---|
43 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
44 | SUBROUTINE KppDecompCmplx( JVS, IER ) |
---|
45 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
46 | ! Sparse LU factorization, complex |
---|
47 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
48 | |
---|
49 | USE KPP_ROOT_Parameters |
---|
50 | USE KPP_ROOT_JacobianSP |
---|
51 | |
---|
52 | INTEGER :: IER |
---|
53 | DOUBLE COMPLEX :: JVS(LU_NONZERO), W(NVAR), a |
---|
54 | KPP_REAL :: b = 0.0 |
---|
55 | INTEGER :: k, kk, j, jj |
---|
56 | |
---|
57 | IER = 0 |
---|
58 | DO k=1,NVAR |
---|
59 | IF ( ABS(JVS(LU_DIAG(k))) < TINY(b) ) THEN |
---|
60 | IER = k |
---|
61 | RETURN |
---|
62 | END IF |
---|
63 | DO kk = LU_CROW(k), LU_CROW(k+1)-1 |
---|
64 | W( LU_ICOL(kk) ) = JVS(kk) |
---|
65 | END DO |
---|
66 | DO kk = LU_CROW(k), LU_DIAG(k)-1 |
---|
67 | j = LU_ICOL(kk) |
---|
68 | a = -W(j) / JVS( LU_DIAG(j) ) |
---|
69 | W(j) = -a |
---|
70 | DO jj = LU_DIAG(j)+1, LU_CROW(j+1)-1 |
---|
71 | W( LU_ICOL(jj) ) = W( LU_ICOL(jj) ) + a*JVS(jj) |
---|
72 | END DO |
---|
73 | END DO |
---|
74 | DO kk = LU_CROW(k), LU_CROW(k+1)-1 |
---|
75 | JVS(kk) = W( LU_ICOL(kk) ) |
---|
76 | END DO |
---|
77 | END DO |
---|
78 | |
---|
79 | END SUBROUTINE KppDecompCmplx |
---|
80 | |
---|
81 | |
---|
82 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
83 | SUBROUTINE KppDecompCmplxR( JVSR, JVSI, IER ) |
---|
84 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
85 | ! Sparse LU factorization, complex |
---|
86 | ! (Real and Imaginary parts are used instead of complex data type) |
---|
87 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
88 | |
---|
89 | USE KPP_ROOT_Parameters |
---|
90 | USE KPP_ROOT_JacobianSP |
---|
91 | |
---|
92 | INTEGER :: IER |
---|
93 | KPP_REAL :: JVSR(LU_NONZERO), JVSI(LU_NONZERO) |
---|
94 | KPP_REAL :: WR(NVAR), WI(NVAR), ar, ai, den |
---|
95 | INTEGER :: k, kk, j, jj |
---|
96 | |
---|
97 | IER = 0 |
---|
98 | ar = 0.0 |
---|
99 | DO k=1,NVAR |
---|
100 | IF ( ( ABS(JVSR(LU_DIAG(k))) < TINY(ar) ) .AND. & |
---|
101 | ( ABS(JVSI(LU_DIAG(k))) < TINY(ar) ) ) THEN |
---|
102 | IER = k |
---|
103 | RETURN |
---|
104 | END IF |
---|
105 | DO kk = LU_CROW(k), LU_CROW(k+1)-1 |
---|
106 | WR( LU_ICOL(kk) ) = JVSR(kk) |
---|
107 | WI( LU_ICOL(kk) ) = JVSI(kk) |
---|
108 | END DO |
---|
109 | DO kk = LU_CROW(k), LU_DIAG(k)-1 |
---|
110 | j = LU_ICOL(kk) |
---|
111 | den = JVSR(LU_DIAG(j))**2 + JVSI(LU_DIAG(j))**2 |
---|
112 | ar = -(WR(j)*JVSR(LU_DIAG(j)) + WI(j)*JVSI(LU_DIAG(j)))/den |
---|
113 | ai = -(WI(j)*JVSR(LU_DIAG(j)) - WR(j)*JVSI(LU_DIAG(j)))/den |
---|
114 | WR(j) = -ar |
---|
115 | WI(j) = -ai |
---|
116 | DO jj = LU_DIAG(j)+1, LU_CROW(j+1)-1 |
---|
117 | WR( LU_ICOL(jj) ) = WR( LU_ICOL(jj) ) + ar*JVSR(jj) - ai*JVSI(jj) |
---|
118 | WI( LU_ICOL(jj) ) = WI( LU_ICOL(jj) ) + ar*JVSI(jj) + ai*JVSR(jj) |
---|
119 | END DO |
---|
120 | END DO |
---|
121 | DO kk = LU_CROW(k), LU_CROW(k+1)-1 |
---|
122 | JVSR(kk) = WR( LU_ICOL(kk) ) |
---|
123 | JVSI(kk) = WI( LU_ICOL(kk) ) |
---|
124 | END DO |
---|
125 | END DO |
---|
126 | |
---|
127 | END SUBROUTINE KppDecompCmplxR |
---|
128 | |
---|
129 | |
---|
130 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
131 | SUBROUTINE KppSolveIndirect( JVS, X ) |
---|
132 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
133 | ! Sparse solve subroutine using indirect addressing |
---|
134 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
135 | |
---|
136 | USE KPP_ROOT_Parameters |
---|
137 | USE KPP_ROOT_JacobianSP |
---|
138 | |
---|
139 | INTEGER :: i, j |
---|
140 | KPP_REAL :: JVS(LU_NONZERO), X(NVAR), sum |
---|
141 | |
---|
142 | DO i=1,NVAR |
---|
143 | DO j = LU_CROW(i), LU_DIAG(i)-1 |
---|
144 | X(i) = X(i) - JVS(j)*X(LU_ICOL(j)); |
---|
145 | END DO |
---|
146 | END DO |
---|
147 | |
---|
148 | DO i=NVAR,1,-1 |
---|
149 | sum = X(i); |
---|
150 | DO j = LU_DIAG(i)+1, LU_CROW(i+1)-1 |
---|
151 | sum = sum - JVS(j)*X(LU_ICOL(j)); |
---|
152 | END DO |
---|
153 | X(i) = sum/JVS(LU_DIAG(i)); |
---|
154 | END DO |
---|
155 | |
---|
156 | END SUBROUTINE KppSolveIndirect |
---|
157 | |
---|
158 | |
---|
159 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
160 | SUBROUTINE KppSolveTRIndirect( JVS, X ) |
---|
161 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
162 | ! Complex sparse solve transpose subroutine using indirect addressing |
---|
163 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
164 | |
---|
165 | USE KPP_ROOT_Parameters |
---|
166 | USE KPP_ROOT_JacobianSP |
---|
167 | |
---|
168 | INTEGER :: i, j |
---|
169 | KPP_REAL :: JVS(LU_NONZERO), X(NVAR) |
---|
170 | |
---|
171 | DO i=1,NVAR |
---|
172 | X(i) = X(i)/JVS(LU_DIAG(i)) |
---|
173 | ! subtract all nonzero elements in row i of JVS from X |
---|
174 | DO j=LU_DIAG(i)+1,LU_CROW(i+1)-1 |
---|
175 | X(LU_ICOL(j)) = X(LU_ICOL(j))-JVS(j)*X(i) |
---|
176 | END DO |
---|
177 | END DO |
---|
178 | |
---|
179 | DO i=NVAR, 1, -1 |
---|
180 | ! subtract all nonzero elements in row i of JVS from X |
---|
181 | DO j=LU_CROW(i),LU_DIAG(i)-1 |
---|
182 | X(LU_ICOL(j)) = X(LU_ICOL(j))-JVS(j)*X(i) |
---|
183 | END DO |
---|
184 | END DO |
---|
185 | |
---|
186 | END SUBROUTINE KppSolveTRIndirect |
---|
187 | |
---|
188 | |
---|
189 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
190 | SUBROUTINE KppSolveCmplx( JVS, X ) |
---|
191 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
192 | ! Complex sparse solve subroutine using indirect addressing |
---|
193 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
194 | |
---|
195 | USE KPP_ROOT_Parameters |
---|
196 | USE KPP_ROOT_JacobianSP |
---|
197 | |
---|
198 | INTEGER :: i, j |
---|
199 | DOUBLE COMPLEX :: JVS(LU_NONZERO), X(NVAR), sum |
---|
200 | |
---|
201 | DO i=1,NVAR |
---|
202 | DO j = LU_CROW(i), LU_DIAG(i)-1 |
---|
203 | X(i) = X(i) - JVS(j)*X(LU_ICOL(j)); |
---|
204 | END DO |
---|
205 | END DO |
---|
206 | |
---|
207 | DO i=NVAR,1,-1 |
---|
208 | sum = X(i); |
---|
209 | DO j = LU_DIAG(i)+1, LU_CROW(i+1)-1 |
---|
210 | sum = sum - JVS(j)*X(LU_ICOL(j)); |
---|
211 | END DO |
---|
212 | X(i) = sum/JVS(LU_DIAG(i)); |
---|
213 | END DO |
---|
214 | |
---|
215 | END SUBROUTINE KppSolveCmplx |
---|
216 | |
---|
217 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
218 | SUBROUTINE KppSolveCmplxR( JVSR, JVSI, XR, XI ) |
---|
219 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
220 | ! Complex sparse solve subroutine using indirect addressing |
---|
221 | ! (Real and Imaginary parts are used instead of complex data type) |
---|
222 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
223 | |
---|
224 | USE KPP_ROOT_Parameters |
---|
225 | USE KPP_ROOT_JacobianSP |
---|
226 | |
---|
227 | INTEGER :: i, j |
---|
228 | KPP_REAL :: JVSR(LU_NONZERO), JVSI(LU_NONZERO), XR(NVAR), XI(NVAR), sumr, sumi, den |
---|
229 | |
---|
230 | DO i=1,NVAR |
---|
231 | DO j = LU_CROW(i), LU_DIAG(i)-1 |
---|
232 | XR(i) = XR(i) - (JVSR(j)*XR(LU_ICOL(j)) - JVSI(j)*XI(LU_ICOL(j))) |
---|
233 | XI(i) = XI(i) - (JVSR(j)*XI(LU_ICOL(j)) + JVSI(j)*XR(LU_ICOL(j))) |
---|
234 | END DO |
---|
235 | END DO |
---|
236 | |
---|
237 | DO i=NVAR,1,-1 |
---|
238 | sumr = XR(i); sumi = XI(i) |
---|
239 | DO j = LU_DIAG(i)+1, LU_CROW(i+1)-1 |
---|
240 | sumr = sumr - (JVSR(j)*XR(LU_ICOL(j)) - JVSI(j)*XI(LU_ICOL(j))) |
---|
241 | sumi = sumi - (JVSR(j)*XI(LU_ICOL(j)) + JVSI(j)*XR(LU_ICOL(j))) |
---|
242 | END DO |
---|
243 | den = JVSR(LU_DIAG(i))**2 + JVSI(LU_DIAG(i))**2 |
---|
244 | XR(i) = (sumr*JVSR(LU_DIAG(i)) + sumi*JVSI(LU_DIAG(i)))/den |
---|
245 | XI(i) = (sumi*JVSR(LU_DIAG(i)) - sumr*JVSI(LU_DIAG(i)))/den |
---|
246 | END DO |
---|
247 | |
---|
248 | END SUBROUTINE KppSolveCmplxR |
---|
249 | |
---|
250 | |
---|
251 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
252 | SUBROUTINE KppSolveTRCmplx( JVS, X ) |
---|
253 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
254 | ! Complex sparse solve transpose subroutine using indirect addressing |
---|
255 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
256 | |
---|
257 | USE KPP_ROOT_Parameters |
---|
258 | USE KPP_ROOT_JacobianSP |
---|
259 | |
---|
260 | INTEGER :: i, j |
---|
261 | DOUBLE COMPLEX :: JVS(LU_NONZERO), X(NVAR) |
---|
262 | |
---|
263 | DO i=1,NVAR |
---|
264 | X(i) = X(i)/JVS(LU_DIAG(i)) |
---|
265 | ! subtract all nonzero elements in row i of JVS from X |
---|
266 | DO j=LU_DIAG(i)+1,LU_CROW(i+1)-1 |
---|
267 | X(LU_ICOL(j)) = X(LU_ICOL(j))-JVS(j)*X(i) |
---|
268 | END DO |
---|
269 | END DO |
---|
270 | |
---|
271 | DO i=NVAR, 1, -1 |
---|
272 | ! subtract all nonzero elements in row i of JVS from X |
---|
273 | DO j=LU_CROW(i),LU_DIAG(i)-1 |
---|
274 | X(LU_ICOL(j)) = X(LU_ICOL(j))-JVS(j)*X(i) |
---|
275 | END DO |
---|
276 | END DO |
---|
277 | |
---|
278 | END SUBROUTINE KppSolveTRCmplx |
---|
279 | |
---|
280 | |
---|
281 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
282 | SUBROUTINE KppSolveTRCmplxR( JVSR, JVSI, XR, XI ) |
---|
283 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
284 | ! Complex sparse solve transpose subroutine using indirect addressing |
---|
285 | ! (Real and Imaginary parts are used instead of complex data type) |
---|
286 | ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
287 | |
---|
288 | USE KPP_ROOT_Parameters |
---|
289 | USE KPP_ROOT_JacobianSP |
---|
290 | |
---|
291 | INTEGER :: i, j |
---|
292 | KPP_REAL :: JVSR(LU_NONZERO), JVSI(LU_NONZERO), XR(NVAR), XI(NVAR), den |
---|
293 | |
---|
294 | DO i=1,NVAR |
---|
295 | den = JVSR(LU_DIAG(i))**2 + JVSI(LU_DIAG(i))**2 |
---|
296 | XR(i) = (XR(i)*JVSR(LU_DIAG(i)) + XI(i)*JVSI(LU_DIAG(i)))/den |
---|
297 | XI(i) = (XI(i)*JVSR(LU_DIAG(i)) - XR(i)*JVSI(LU_DIAG(i)))/den |
---|
298 | ! subtract all nonzero elements in row i of JVS from X |
---|
299 | DO j=LU_DIAG(i)+1,LU_CROW(i+1)-1 |
---|
300 | XR(LU_ICOL(j)) = XR(LU_ICOL(j))-(JVSR(j)*XR(i) - JVSI(j)*XI(i)) |
---|
301 | XI(LU_ICOL(j)) = XI(LU_ICOL(j))-(JVSI(j)*XR(i) + JVSR(j)*XI(i)) |
---|
302 | END DO |
---|
303 | END DO |
---|
304 | |
---|
305 | DO i=NVAR, 1, -1 |
---|
306 | ! subtract all nonzero elements in row i of JVS from X |
---|
307 | DO j=LU_CROW(i),LU_DIAG(i)-1 |
---|
308 | XR(LU_ICOL(j)) = XR(LU_ICOL(j))-(JVSR(j)*XR(i) - JVSI(j)*XI(i)) |
---|
309 | XI(LU_ICOL(j)) = XI(LU_ICOL(j))-(JVSI(j)*XR(i) + JVSR(j)*XI(i)) |
---|
310 | END DO |
---|
311 | END DO |
---|
312 | |
---|
313 | END SUBROUTINE KppSolveTRCmplxR |
---|
314 | |
---|
315 | |
---|
316 | ! |
---|
317 | ! Next few commented subroutines perform sparse big linear algebra |
---|
318 | ! |
---|
319 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
320 | !SUBROUTINE KppDecompBig( JVS, IP, IER ) |
---|
321 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
322 | !! Sparse LU factorization |
---|
323 | !! for the Runge Kutta (3n)x(3n) linear system |
---|
324 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
325 | ! |
---|
326 | ! USE KPP_ROOT_Parameters |
---|
327 | ! USE KPP_ROOT_JacobianSP |
---|
328 | ! |
---|
329 | ! INTEGER :: IP3(3), IER, IP(3,NVAR) |
---|
330 | ! KPP_REAL :: JVS(3,3,LU_NONZERO), W(3,3,NVAR), a(3,3), E(3,3) |
---|
331 | ! INTEGER :: k, kk, j, jj |
---|
332 | ! |
---|
333 | ! a = 0.0d0 |
---|
334 | ! IER = 0 |
---|
335 | ! DO k=1,NVAR |
---|
336 | ! DO kk = LU_CROW(k), LU_CROW(k+1)-1 |
---|
337 | ! W( 1:3,1:3,LU_ICOL(kk) ) = JVS(1:3,1:3,kk) |
---|
338 | ! END DO |
---|
339 | ! DO kk = LU_CROW(k), LU_DIAG(k)-1 |
---|
340 | ! j = LU_ICOL(kk) |
---|
341 | ! E(1:3,1:3) = JVS( 1:3,1:3,LU_DIAG(j) ) |
---|
342 | ! ! CALL DGETRF(3,3,E,3,IP3,IER) |
---|
343 | ! CALL FAC3(E,IP3,IER) |
---|
344 | ! IF ( IER /= 0 ) RETURN |
---|
345 | ! ! a = W(j) / JVS( LU_DIAG(j) ) |
---|
346 | ! a(1:3,1:3) = W( 1:3,1:3,j ) |
---|
347 | ! ! CALL DGETRS ('N',3,3,E,3,IP3,a,3,IER) |
---|
348 | ! CALL SOL3('N',E,IP3,a(1,1)) |
---|
349 | ! CALL SOL3('N',E,IP3,a(1,2)) |
---|
350 | ! CALL SOL3('N',E,IP3,a(1,3)) |
---|
351 | ! W(1:3,1:3,j) = a(1:3,1:3) |
---|
352 | ! DO jj = LU_DIAG(j)+1, LU_CROW(j+1)-1 |
---|
353 | ! W( 1:3,1:3,LU_ICOL(jj) ) = W( 1:3,1:3,LU_ICOL(jj) ) & |
---|
354 | ! - MATMUL( a(1:3,1:3) , JVS(1:3,1:3,jj) ) |
---|
355 | ! END DO |
---|
356 | ! END DO |
---|
357 | ! DO kk = LU_CROW(k), LU_CROW(k+1)-1 |
---|
358 | ! JVS(1:3,1:3,kk) = W( 1:3,1:3,LU_ICOL(kk) ) |
---|
359 | ! END DO |
---|
360 | ! END DO |
---|
361 | ! |
---|
362 | ! DO k=1,NVAR |
---|
363 | ! ! CALL WGEFA(JVS(1,1,LU_DIAG(k)),3,3,IP(1,k),IER) |
---|
364 | ! ! CALL DGETRF(3,3,JVS(1,1,LU_DIAG(k)),3,IP(1,k),IER) |
---|
365 | ! CALL FAC3(JVS(1,1,LU_DIAG(k)),IP(1,k),IER) |
---|
366 | ! IF ( IER /= 0 ) RETURN |
---|
367 | ! END DO |
---|
368 | ! |
---|
369 | !END SUBROUTINE KppDecompBig |
---|
370 | ! |
---|
371 | ! |
---|
372 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
373 | !SUBROUTINE KppSolveBig( JVS, IP, X ) |
---|
374 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
375 | !! Sparse solve subroutine using indirect addressing |
---|
376 | !! for the Runge Kutta (3n)x(3n) linear system |
---|
377 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
378 | ! |
---|
379 | ! USE KPP_ROOT_Parameters |
---|
380 | ! USE KPP_ROOT_JacobianSP |
---|
381 | ! |
---|
382 | ! INTEGER :: i, j, k, m, IP3(3), IP(3,NVAR), IER |
---|
383 | ! KPP_REAL :: JVS(3,3,LU_NONZERO), X(3,NVAR), sum(3) |
---|
384 | ! |
---|
385 | ! DO i=1,NVAR |
---|
386 | ! DO j = LU_CROW(i), LU_DIAG(i)-1 |
---|
387 | ! !X(1:3,i) = X(1:3,i) - MATMUL(JVS(1:3,1:3,j),X(1:3,LU_ICOL(j))); |
---|
388 | ! DO k=1,3 |
---|
389 | ! DO m=1,3 |
---|
390 | ! X(k,i) = X(k,i) - JVS(k,m,j)*X(m,LU_ICOL(j)) |
---|
391 | ! END DO |
---|
392 | ! END DO |
---|
393 | ! END DO |
---|
394 | ! END DO |
---|
395 | ! |
---|
396 | ! DO i=NVAR,1,-1 |
---|
397 | ! sum(1:3) = X(1:3,i); |
---|
398 | ! DO j = LU_DIAG(i)+1, LU_CROW(i+1)-1 |
---|
399 | ! !sum(1:3) = sum(1:3) - MATMUL(JVS(1:3,1:3,j),X(1:3,LU_ICOL(j))); |
---|
400 | ! DO k=1,3 |
---|
401 | ! DO m=1,3 |
---|
402 | ! sum(k) = sum(k) - JVS(k,m,j)*X(m,LU_ICOL(j)) |
---|
403 | ! END DO |
---|
404 | ! END DO |
---|
405 | ! END DO |
---|
406 | ! ! X(i) = sum/JVS(LU_DIAG(i)); |
---|
407 | ! ! CALL DGETRS ('N',3,1,JVS(1:3,1:3,LU_DIAG(i)),3,IP(1,i),sum,3,0) |
---|
408 | ! ! CALL WGESL('N',JVS(1,1,LU_DIAG(i)),3,3,IP(1,i),sum) |
---|
409 | ! CALL SOL3('N',JVS(1,1,LU_DIAG(i)),IP(1,i),sum) |
---|
410 | ! X(1:3,i) = sum(1:3) |
---|
411 | ! END DO |
---|
412 | ! |
---|
413 | !END SUBROUTINE KppSolveBig |
---|
414 | ! |
---|
415 | ! |
---|
416 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
417 | !SUBROUTINE KppSolveBigTR( JVS, IP, X ) |
---|
418 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
419 | !! Big sparse transpose solve using indirect addressing |
---|
420 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
421 | ! |
---|
422 | ! USE KPP_ROOT_Parameters |
---|
423 | ! USE KPP_ROOT_JacobianSP |
---|
424 | ! |
---|
425 | ! INTEGER :: i, j, k, m, IP(3,NVAR) |
---|
426 | ! KPP_REAL :: JVS(3,3,LU_NONZERO), X(3,NVAR) |
---|
427 | ! |
---|
428 | ! DO i=1,NVAR |
---|
429 | ! ! X(i) = X(i)/JVS(LU_DIAG(i)) |
---|
430 | ! CALL SOL3('T',JVS(1,1,LU_DIAG(i)),IP(1,i),X(1,i)) |
---|
431 | ! DO j=LU_DIAG(i)+1,LU_CROW(i+1)-1 |
---|
432 | ! !X(1:3,LU_ICOL(j)) = X(1:3,LU_ICOL(j)) & |
---|
433 | ! ! - MATMUL( TRANSPOSE(JVS(1:3,1:3,j)), X(1:3,i) ) |
---|
434 | ! DO k=1,3 |
---|
435 | ! DO m=1,3 |
---|
436 | ! X(k,LU_ICOL(j)) = X(k,LU_ICOL(j)) - JVS(m,k,j)*X(m,i) |
---|
437 | ! END DO |
---|
438 | ! END DO |
---|
439 | ! END DO |
---|
440 | ! END DO |
---|
441 | ! |
---|
442 | ! DO i=NVAR, 1, -1 |
---|
443 | ! DO j=LU_CROW(i),LU_DIAG(i)-1 |
---|
444 | ! !X(1:3,LU_ICOL(j)) = X(1:3,LU_ICOL(j)) & |
---|
445 | ! ! - MATMUL( TRANSPOSE(JVS(1:3,1:3,j)), X(1:3,i) ) |
---|
446 | ! DO k=1,3 |
---|
447 | ! DO m=1,3 |
---|
448 | ! X(k,LU_ICOL(j)) = X(k,LU_ICOL(j)) - JVS(m,k,j)*X(m,i) |
---|
449 | ! END DO |
---|
450 | ! END DO |
---|
451 | ! END DO |
---|
452 | ! END DO |
---|
453 | ! |
---|
454 | !END SUBROUTINE KppSolveBigTR |
---|
455 | ! |
---|
456 | ! |
---|
457 | ! |
---|
458 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
459 | !SUBROUTINE FAC3(A,IPVT,INFO) |
---|
460 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
461 | !! FAC3 FACTORS THE MATRIX A (3,3) BY |
---|
462 | !! GAUSS ELIMINATION WITH PARTIAL PIVOTING |
---|
463 | !! LINPACK - LIKE |
---|
464 | !! |
---|
465 | !! Remove comments to perform pivoting |
---|
466 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
467 | !! |
---|
468 | ! KPP_REAL :: A(3,3) |
---|
469 | ! INTEGER :: IPVT(3),INFO |
---|
470 | !! INTEGER :: L |
---|
471 | !! KPP_REAL :: t, dmax, da, TMP(3) |
---|
472 | ! KPP_REAL, PARAMETER :: ZERO = 0.0, ONE = 1.0 |
---|
473 | ! |
---|
474 | ! info = 0 |
---|
475 | !! t = TINY(da) |
---|
476 | !! |
---|
477 | !! da = ABS(A(1,1)); L = 1 |
---|
478 | !! IF ( ABS(A(2,1))>da ) THEN |
---|
479 | !! da = ABS(A(2,1)); L = 2 |
---|
480 | !! IF ( ABS(A(3,1))>da ) THEN |
---|
481 | !! L = 3 |
---|
482 | !! END IF |
---|
483 | !! END IF |
---|
484 | !! IPVT(1) = L |
---|
485 | !! IF (L /=1 ) THEN |
---|
486 | !! TMP(1:3) = A(L,1:3) |
---|
487 | !! A(L,1:3) = A(1,1:3) |
---|
488 | !! A(1,1:3) = TMP(1:3) |
---|
489 | !! END IF |
---|
490 | !! IF (ABS(A(1,1)) < t) THEN |
---|
491 | !! info = 1 |
---|
492 | !! return |
---|
493 | !! END IF |
---|
494 | !! |
---|
495 | ! A(2,1) = A(2,1)/A(1,1) |
---|
496 | ! A(2,2) = A(2,2) - A(2,1)*A(1,2) |
---|
497 | ! A(2,3) = A(2,3) - A(2,1)*A(1,3) |
---|
498 | ! A(3,1) = A(3,1)/A(1,1) |
---|
499 | ! A(3,2) = A(3,2) - A(3,1)*A(1,2) |
---|
500 | ! A(3,3) = A(3,3) - A(3,1)*A(1,3) |
---|
501 | ! |
---|
502 | !! IPVT(2) = 2 |
---|
503 | !! IF (ABS(A(3,2))>ABS(A(2,2))) THEN |
---|
504 | !! IPVT(2) = 3 |
---|
505 | !! TMP(2:3) = A(3,2:3) |
---|
506 | !! A(3,2:3) = A(2,2:3) |
---|
507 | !! A(2,2:3) = TMP(2:3) |
---|
508 | !! END IF |
---|
509 | !! IF (ABS(A(2,2)) < t) THEN |
---|
510 | !! info = 1 |
---|
511 | !! return |
---|
512 | !! END IF |
---|
513 | !! |
---|
514 | ! A(3,2) = A(3,2)/A(2,2) |
---|
515 | ! A(3,3) = A(3,3) - A(3,2)*A(2,3) |
---|
516 | ! IPVT(3) = 3 |
---|
517 | ! |
---|
518 | !END SUBROUTINE FAC3 |
---|
519 | ! |
---|
520 | ! |
---|
521 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
522 | !SUBROUTINE SOL3(Trans,A,IPVT,b) |
---|
523 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
524 | !! SOL3 solves the system 3x3 |
---|
525 | !! A * x = b or trans(a) * x = b |
---|
526 | !! using the factors computed by WGEFA. |
---|
527 | !! |
---|
528 | !! Trans = 'N' to solve A*x = b , |
---|
529 | !! = 'T' to solve transpose(A)*x = b |
---|
530 | !! LINPACK - LIKE |
---|
531 | !! |
---|
532 | !! Remove comments to use pivoting |
---|
533 | !! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
534 | ! |
---|
535 | ! CHARACTER :: Trans |
---|
536 | ! KPP_REAL :: a(3,3),b(3) |
---|
537 | ! INTEGER :: IPVT(3) |
---|
538 | !! INTEGER :: L |
---|
539 | !! KPP_REAL :: TMP |
---|
540 | ! |
---|
541 | ! SELECT CASE (Trans) |
---|
542 | ! |
---|
543 | ! CASE ('n','N') ! Solve A * x = b |
---|
544 | ! |
---|
545 | !! Solve L*y = b |
---|
546 | !! L = IPVT(1) |
---|
547 | !! IF (L /= 1) THEN |
---|
548 | !! TMP = B(1); B(1) = B(L); B(L) = TMP |
---|
549 | !! END IF |
---|
550 | ! b(2) = b(2)-A(2,1)*b(1) |
---|
551 | ! b(3) = b(3)-A(3,1)*b(1) |
---|
552 | ! |
---|
553 | !! L = IPVT(2) |
---|
554 | !! IF (L /= 2) THEN |
---|
555 | !! TMP = B(2); B(2) = B(L); B(L) = TMP |
---|
556 | !! END IF |
---|
557 | ! b(3) = b(3)-A(3,2)*b(2) |
---|
558 | ! |
---|
559 | !! Solve U*x = y |
---|
560 | ! b(3) = b(3)/A(3,3) |
---|
561 | ! b(2) = (b(2)-A(2,3)*b(3))/A(2,2) |
---|
562 | ! b(1) = (b(1)-A(1,3)*b(3)-A(1,2)*b(2))/A(1,1) |
---|
563 | ! |
---|
564 | ! |
---|
565 | ! CASE ('t','T') ! Solve transpose(A) * x = b |
---|
566 | ! |
---|
567 | !! Solve transpose(U)*y = b |
---|
568 | ! b(1) = b(1)/A(1,1) |
---|
569 | ! b(2) = (b(2)-A(1,2)*b(1))/A(2,2) |
---|
570 | ! b(3) = (b(3)-A(1,3)*b(1)-A(2,3)*b(2))/A(3,3) |
---|
571 | ! |
---|
572 | !! Solve transpose(L)*x = y |
---|
573 | ! b(2) = b(2)-A(3,2)*b(3) |
---|
574 | !! L = ipvt(2) |
---|
575 | !! IF (L /= 2) THEN |
---|
576 | !! TMP = B(2); B(2) = B(L); B(L) = TMP |
---|
577 | !! END IF |
---|
578 | ! b(1) = b(1)-A(3,1)*b(3)-A(2,1)*b(2) |
---|
579 | !! L = ipvt(1) |
---|
580 | !! IF (L /= 1) THEN |
---|
581 | !! TMP = B(1); B(1) = B(L); B(L) = TMP |
---|
582 | !! END IF |
---|
583 | ! |
---|
584 | ! END SELECT |
---|
585 | ! |
---|
586 | !END SUBROUTINE SOL3 |
---|
587 | |
---|