33 IMPLICIT NONE
34 INTEGER SIZEDIAG_ORIG
35 REAL DIAG_ORIG(SIZEDIAG_ORIG)
36 REAL GW_FACTCUMUL
37 INTEGER NFRONT,NASS,N,LIW,INODE,IFLAG,INOPV
38 INTEGER NASS2, IBEG_BLOCK_TO_SEND, IBEG_BLOCK, IEND_BLOCK
39 INTEGER, intent(inout) :: NNEGW, NB22T2W, NBTINYW
40 INTEGER, intent(inout) :: DET_EXPW, DET_SIGNW
41 COMPLEX, intent(inout) :: DET_MANTW
42 INTEGER TIPIV( NASS2 )
43 INTEGER PIVSIZ,LPIV
44 INTEGER, intent(in) :: PIVOT_OPTION, IEND_BLR
45 LOGICAL, intent(in) :: LR_ACTIVATED
46 INTEGER, intent(inout) :: Inextpiv
47 LOGICAL, intent(in) :: OOC_EFFECTIVE_ON_FRONT
48 INTEGER(8) :: LA
49 COMPLEX A(LA)
50 REAL UU, UULOC, SEUIL
51 COMPLEX CSEUIL
52 INTEGER IW(LIW)
53 INTEGER IOLDPS
54 INTEGER(8) :: POSELT
55 INTEGER KEEP(500)
56 INTEGER(8) KEEP8(150)
57 INTEGER LPN_LIST
58 INTEGER PIVNUL_LIST(LPN_LIST)
59 REAL DKEEP(230)
60 INTEGER PP_FIRST2SWAP_L, PP_LastPanelonDisk
61 INTEGER PP_LastPIVRPTRIndexFilled
62 include 'mpif.h'
63 INTEGER(8) :: POSPV1,POSPV2,OFFDAG,APOSJ
64 INTEGER JMAX
65 INTEGER :: IPIVNUL, HF
66 REAL RMAX,AMAX,TMAX,RMAX_NORELAX,MAX_PREV_in_PARPIV
67 REAL MAXPIV, ABS_PIVOT
68 REAL RMAX_NOSLAVE, TMAX_NOSLAVE
69 COMPLEX PIVOT,DETPIV
70 REAL ABSDETPIV
71 include 'mumps_headers.h'
72 INTEGER(8) :: APOSMAX, APOSROW
73 INTEGER(8) :: APOS
74 INTEGER(8) :: J1, J2, JJ, KK
75 REAL :: GROWTH, RSWOP
76 REAL :: UULOCM1
77 INTEGER :: LDAFS
78 INTEGER(8) :: LDAFS8
79 REAL, PARAMETER :: RZERO = 0.0e0
80 REAL, PARAMETER :: RONE = 1.0e0
81 COMPLEX ZERO, ONE
82 parameter( zero = (0.0e0,0.0e0) )
83 parameter( one = (1.0e0,0.0e0) )
84 REAL PIVNUL, VALTMP
85 COMPLEX FIXA
86 INTEGER NPIV,IPIV,K219
87 INTEGER NPIVP1,ILOC,K,J
88 INTEGER ISHIFT, K206, IPIV_END, IPIV_SHIFT
90 INTEGER I_PIVRPTR, I_PIVR, NBPANELS_L
91 REAL GW_FACT
92 gw_fact = rone
93 amax = rzero
94 rmax = rzero
95 tmax = rzero
96 rmax_noslave = rzero
97 pivot = one
98 hf = 6 + iw(ioldps+5+keep(ixsz)) + keep(ixsz)
99 k206 = keep(206)
100 pivnul = dkeep(1)
101 fixa =
cmplx(dkeep(2),kind=kind(fixa))
102 cseuil =
cmplx(seuil,kind=kind(cseuil))
103 ldafs = nass
104 ldafs8 = int(ldafs,8)
105 IF ((keep(50).NE.1) .AND. ooc_effective_on_front) THEN
107 & i_pivrptr, i_pivr,
108 & ioldps+2*nfront+6+iw(ioldps+5+keep(ixsz))
109 & +keep(ixsz),
110 & iw, liw)
111 ENDIF
112 uuloc = uu
113 k219 = keep(219)
114 IF (uuloc.GT.rzero) THEN
115 uulocm1 = rone/uuloc
116 ELSE
117 k219=0
118 uulocm1 = rone
119 ENDIF
120 IF (k219.LT.2) gw_factcumul = rone
121 pivsiz = 1
122 npiv = iw(ioldps+1+keep(ixsz))
123 npivp1 = npiv + 1
124 iloc = npivp1 - ibeg_block_to_send + 1
125 tipiv( iloc ) = iloc
126 aposmax = poselt+ldafs8*ldafs8-1_8
127 IF(inopv .EQ. -1) THEN
128 apos = poselt + ldafs8*int(npivp1-1,8) + int(npiv,8)
129 pospv1 = apos
130 abs_pivot = abs(pivot)
132 & ( abs_pivot,
133 & dkeep, keep, .true.)
134 IF(abs_pivot.LT.seuil) THEN
135 IF(real(a(apos)) .GE. rzero) THEN
136 a(apos) = cseuil
137 ELSE
138 a(apos) = -cseuil
139 ENDIF
140 nbtinyw = nbtinyw + 1
141 ELSE IF (keep(258) .NE.0 ) THEN
143 ENDIF
144 IF ((keep(50).NE.1) .AND. ooc_effective_on_front) THEN
146 & iw(i_pivr), nass, npivp1, npivp1,
147 & pp_lastpanelondisk,
148 & pp_lastpivrptrindexfilled)
149 ENDIF
150 GO TO 420
151 ENDIF
152 inopv = 0
153 IF ((k219.GE.2).AND.(npivp1.EQ.1)) THEN
154 gw_factcumul = rone
155 IF (k219.EQ.3) THEN
156 DO ipiv=1,nass
157 diag_orig(ipiv) = abs(a(poselt +
158 & (ldafs8+1_8)*int(ipiv-1,8)))
159 ENDDO
160 ELSE IF (k219.GE.4) THEN
161 diag_orig = rzero
162 DO ipiv=1,nass
163 apos = poselt + ldafs8*int(ipiv-1,8)
164 pospv1 = apos + int(ipiv - 1,8)
165 diag_orig(ipiv) =
max( abs(a(pospv1)), diag_orig(ipiv) )
166 DO j=ipiv+1,nass
167 diag_orig(ipiv) =
max( abs(a(pospv1)), diag_orig(ipiv) )
168 diag_orig(ipiv+j-ipiv) =
max( abs(a(pospv1)),
169 & diag_orig(ipiv+j-ipiv) )
170 pospv1 = pospv1 + ldafs8
171 ENDDO
172 ENDDO
173 ENDIF
174 ENDIF
175 ishift = 0
176 ipiv_end = iend_block
177 IF (k206.GE.1) THEN
178 IF (inextpiv.GT.npivp1.AND.inextpiv.LE.iend_block) THEN
179 ishift = inextpiv - npivp1
180 ENDIF
181 IF ( k206.EQ.1
182 & .OR. (k206 .GT.1 .AND. iend_block.EQ.iend_blr) ) THEN
183 ipiv_end = iend_block + ishift
184 ENDIF
185 ENDIF
186 DO 460 ipiv_shift = npivp1+ishift, ipiv_end
187 IF (ipiv_shift .LE. iend_block) THEN
188 ipiv=ipiv_shift
189 ELSE
190 ipiv = ipiv_shift-iend_block-1+npivp1
191 IF (ibeg_block.EQ.npivp1) THEN
192 EXIT
193 ENDIF
194 ENDIF
195 apos = poselt + ldafs8*int(ipiv-1,8) + int(npiv,8)
196 pospv1 = apos + int(ipiv - npivp1,8)
197 pivot = a(pospv1)
198 abs_pivot = abs(pivot)
199 IF (uuloc.EQ.rzero.OR.pivot_option.EQ.0) THEN
200 IF(abs_pivot.LT.seuil) THEN
202 & ( abs_pivot,
203 & dkeep, keep, .true.)
204 IF(real(pivot) .GE. rzero) THEN
205 a(pospv1) = cseuil
206 ELSE
207 a(pospv1) = -cseuil
208 ENDIF
209 nbtinyw = nbtinyw + 1
210 ELSE IF (abs_pivot.EQ.rzero) THEN
211 GO TO 630
212 ELSE
214 & ( abs_pivot, dkeep, keep, .false.)
215 IF (keep(258) .NE. 0) THEN
217 ENDIF
218 ENDIF
219 GO TO 420
220 ENDIF
221 amax = -rone
222 jmax = 0
223 j1 = apos
224 j2 = pospv1 - 1_8
225 DO jj=j1,j2
226 IF(abs(a(jj)) .GT. amax) THEN
227 amax = abs(a(jj))
228 jmax = ipiv - int(pospv1-jj)
229 ENDIF
230 ENDDO
231 j1 = pospv1 + ldafs8
232 DO j=1, iend_block - ipiv
233 IF(abs(a(j1)) .GT. amax) THEN
234 amax = abs(a(j1))
235 jmax = ipiv + j
236 ENDIF
237 j1 = j1 + ldafs8
238 ENDDO
239 rmax_noslave = rzero
240 IF (pivot_option.EQ.2) THEN
241 DO j=1,nass - iend_block
242 rmax_noslave =
max(abs(a(j1+ldafs8*int(j-1,8))),
243 & rmax_noslave)
244 ENDDO
245 ENDIF
246 IF (k219.NE.0) THEN
247 rmax_norelax = real(a(aposmax+int(ipiv,8)))
248 rmax = rmax_norelax
249 IF (k219.GE.2) THEN
250 IF (abs_pivot.NE.rzero.AND.
251 & abs_pivot.GE.uuloc*
max(rmax,rmax_noslave,amax))
252 & THEN
253 growth = rone
254 IF (k219.EQ.3) THEN
255 IF (diag_orig(ipiv).EQ.rzero) THEN
256 diag_orig(ipiv) = abs_pivot
257 ELSE
258 growth = abs_pivot / diag_orig(ipiv)
259 ENDIF
260 ELSE IF (k219.GE.4) THEN
261 IF (diag_orig(ipiv).EQ.rzero) THEN
262 diag_orig(ipiv) =
max(amax,rmax_noslave)
263 ELSE
264 growth =
max(abs_pivot,amax,rmax_noslave)/
265 & diag_orig(ipiv)
266 ENDIF
267 ENDIF
268 rmax = rmax*
max(growth,gw_factcumul)
269 ENDIF
270 ENDIF
271 ELSE
272 rmax = rzero
273 rmax_norelax = rzero
274 ENDIF
275 rmax_noslave =
max(rmax_norelax,rmax_noslave)
276 rmax =
max(rmax,rmax_noslave)
277 IF (
max(amax,rmax,abs_pivot).LE.pivnul)
THEN
278 IF ((k219.NE.0)
279 & .AND.(k219.NE.-1)
280 & .AND.(rmax_norelax.LT.0)
281 & .AND.(ipiv.GT.1)) THEN
282 max_prev_in_parpiv = rzero
283 DO jj=1,ipiv-1
284 max_prev_in_parpiv=
max( max_prev_in_parpiv,
285 & real(a(aposmax+int(jj,8))) )
286 ENDDO
287 IF (max_prev_in_parpiv.GT.pivnul) THEN
288 aposrow = poselt + ldafs8*int(ipiv-1,8)
289 DO jj=1,ipiv-1
290 IF (abs(a(aposrow+jj-1)).GT.pivnul) THEN
291 GOTO 460
292 ENDIF
293 ENDDO
294 ENDIF
295 ENDIF
297 & ( abs(a(pospv1)), dkeep, keep, .true.)
298 keep(109) = keep(109) + 1
299 ipivnul = keep(109)
300 pivnul_list(ipivnul) = iw( ioldps+hf+npiv+ipiv-npivp1 )
301 IF (real(fixa).GT.rzero) THEN
302 IF(real(pivot) .GE. rzero) THEN
303 a(pospv1) = fixa
304 ELSE
305 a(pospv1) = -fixa
306 ENDIF
307 ELSE
308 j1 = apos
309 j2 = pospv1 - 1_8
310 DO jj=j1,j2
311 a(jj) = zero
312 ENDDO
313 DO j=1, nass-ipiv
314 a(pospv1+int(j,8)*ldafs8) = zero
315 ENDDO
316 valtmp =
max(1.0e10*rmax, sqrt(huge(rmax))/1.0e8)
317 a(pospv1) =
cmplx(valtmp,kind=kind(a))
318 ENDIF
319 pivot = a(pospv1)
320 abs_pivot = abs(pivot)
321 GO TO 415
322 ENDIF
323 rmax =
max(rmax,abs(rmax_norelax))
324 IF (abs_pivot.GE.uuloc*
max(rmax,amax)
325 & .AND. abs_pivot .GT.
max(seuil, tiny(rmax)))
THEN
327 & ( abs_pivot, dkeep, keep, .false.)
328 IF (keep(258) .NE.0 ) THEN
330 ENDIF
331 GO TO 415
332 END IF
333 IF (npivp1.EQ.iend_block) THEN
334 GOTO 460
335 ELSE IF (jmax .EQ.0) THEN
336 GOTO 460
337 ENDIF
338 IF (
max(abs(pivot),rmax,amax).LE.tiny(rmax))
THEN
339 GOTO 460
340 ENDIF
341 IF (rmax_noslave.LT.amax) THEN
342 j1 = apos
343 j2 = pospv1 - 1_8
344 DO jj=j1,j2
345 IF(int(pospv1-jj) .NE. ipiv-jmax) THEN
346 rmax_noslave =
max(rmax_noslave,abs(a(jj)))
347 ENDIF
348 ENDDO
349 DO j=1,nass-ipiv
350 IF(ipiv+j .NE. jmax) THEN
351 rmax_noslave =
max(abs(a(pospv1+ldafs8*int(j,8))),
352 & rmax_noslave)
353 ENDIF
354 ENDDO
355 rmax =
max(rmax, rmax_noslave)
356 ENDIF
357 aposj = poselt + int(jmax-1,8)*ldafs8 + int(npiv,8)
358 pospv2 = aposj + int(jmax - npivp1,8)
359 IF (ipiv.LT.jmax) THEN
360 offdag = aposj + int(ipiv - npivp1,8)
361 ELSE
362 offdag = apos + int(jmax - npivp1,8)
363 END IF
364 tmax_noslave = rzero
365 IF(jmax .LT. ipiv) THEN
366 jj = pospv2
367 DO k = 1, nass-jmax
368 jj = jj+ldafs8
369 IF (jmax+k.NE.ipiv) THEN
370 tmax_noslave=
max(tmax_noslave,abs(a(jj)))
371 ENDIF
372 ENDDO
373 DO kk = aposj, pospv2-1_8
374 tmax_noslave =
max(tmax_noslave,abs(a(kk)))
375 ENDDO
376 ELSE
377 jj = pospv2
378 DO k = 1, nass-jmax
379 jj = jj+ldafs8
380 tmax_noslave=
max(tmax_noslave,abs(a(jj)))
381 ENDDO
382 DO kk = aposj, pospv2 - 1_8
383 IF (kk.NE.offdag) THEN
384 tmax_noslave =
max(tmax_noslave,abs(a(kk)))
385 ENDIF
386 ENDDO
387 ENDIF
388 IF (k219.NE.0) THEN
389 tmax =
max(seuil*uulocm1,
390 & abs(real(a(aposmax+int(jmax,8))))
391 & )
392 ELSE
393 tmax = seuil*uulocm1
394 ENDIF
395 IF (k219.GE.2) THEN
396 growth = rone
397 IF (k219.EQ.3) THEN
398 IF (diag_orig(jmax).EQ.rzero) THEN
399 diag_orig(jmax) = abs(a(pospv2))
400 ELSE
401 growth = abs(a(pospv2))/diag_orig(jmax)
402 ENDIF
403 ELSE IF (k219.EQ.4) THEN
404 IF (diag_orig(jmax).EQ.rzero) THEN
405 diag_orig(jmax)=
max(abs(a(pospv2)),amax,tmax_noslave)
406 ELSE
407 growth =
max(abs(a(pospv2)),amax,tmax_noslave)
408 & / diag_orig(jmax)
409 ENDIF
410 ENDIF
411 tmax = tmax*
max(growth,gw_factcumul)
412 ENDIF
413 tmax =
max(tmax,tmax_noslave)
414 detpiv = a(pospv1)*a(pospv2) - a(offdag)*a(offdag)
415 absdetpiv = abs(detpiv)
416 IF (seuil.GT.rzero) THEN
417 IF (sqrt(absdetpiv) .LE. seuil ) THEN
418 GOTO 460
419 ENDIF
420 ENDIF
421 maxpiv =
max(abs(a(pospv1)),abs(a(pospv2)))
422 IF (maxpiv.EQ.rzero) maxpiv = rone
423 IF ((abs(a(pospv2))*rmax+amax*tmax)*uuloc.GT.
424 & absdetpiv .OR. absdetpiv .EQ. rzero) THEN
425 GO TO 460
426 ENDIF
427 IF ((abs(a(pospv1))*tmax+amax*rmax)*uuloc.GT.
428 & absdetpiv .OR. absdetpiv .EQ. rzero) THEN
429 GO TO 460
430 ENDIF
432 & ( sqrt(abs(detpiv)),
433 & dkeep, keep, .false.)
434 IF (keep(258).NE.0) THEN
436 ENDIF
437 pivsiz = 2
438 nb22t2w = nb22t2w+1
439 415 CONTINUE
440 IF (k206.GE.1) THEN
441 inextpiv =
max(npivp1+pivsiz, ipiv+1)
442 ENDIF
443 DO k=1,pivsiz
444 IF (pivsiz .EQ. 2 ) THEN
445 IF (k==1) THEN
446 lpiv =
min(ipiv, jmax)
447 tipiv(iloc) = -(lpiv - ibeg_block_to_send + 1)
448 ELSE
449 lpiv =
max(ipiv, jmax)
450 tipiv(iloc+1) = -(lpiv - ibeg_block_to_send + 1)
451 ENDIF
452 ELSE
453 lpiv = ipiv
454 tipiv(iloc) = ipiv - ibeg_block_to_send + 1
455 ENDIF
456 IF (lpiv.EQ.npivp1) THEN
457 GOTO 416
458 ENDIF
459 keep8(80) = keep8(80)+1
461 & ioldps, npivp1, lpiv, poselt, nass,
462 & ldafs, nfront, 2, k219, keep(50),
463 & keep(ixsz), ibeg_block_to_send )
464 IF (k219.GE.3) THEN
465 rswop = diag_orig(lpiv)
466 diag_orig(lpiv) = diag_orig(npivp1)
467 diag_orig(npivp1) = rswop
468 ENDIF
469 416 CONTINUE
470 IF ((keep(50).NE.1) .AND. ooc_effective_on_front) THEN
472 & iw(i_pivrptr), nbpanels_l,
473 & iw(i_pivr), nass, npivp1, lpiv, pp_lastpanelondisk,
474 & pp_lastpivrptrindexfilled)
475 ENDIF
476 npivp1 = npivp1+1
477 ENDDO
478 IF(pivsiz .EQ. 2) THEN
479 a(poselt+ldafs8*int(npiv,8)+int(npiv+1,8)) = detpiv
480 ENDIF
481 GOTO 420
482 460 CONTINUE
483 IF (k206 .GE. 1) THEN
484 inextpiv=iend_block+1
485 ENDIF
486 IF (iend_block.EQ.nass) THEN
487 inopv = 1
488 ELSE
489 inopv = 2
490 ENDIF
491 GO TO 420
492 630 CONTINUE
493 iflag = -10
494 420 CONTINUE
495 IF (k219.GE.2) THEN
496 IF(inopv .EQ. 0) THEN
497 IF(pivsiz .EQ. 1) THEN
498 gw_fact =
max(amax,rmax_noslave)/abs_pivot
499 ELSE IF(pivsiz .EQ. 2) THEN
501 & (abs(a(pospv2))*rmax_noslave+amax*tmax_noslave)
502 & / absdetpiv ,
503 & (abs(a(pospv1))*tmax_noslave+amax*rmax_noslave)
504 & / absdetpiv
505 & )
506 ENDIF
507 gw_fact =
min(gw_fact, uulocm1)
508 gw_factcumul =
max(gw_fact,gw_factcumul)
509 ENDIF
510 ENDIF
511 RETURN
subroutine cmumps_updatedeter(piv, deter, nexp)
subroutine cmumps_get_ooc_perm_ptr(typef, nbpanels, i_pivptr, i_piv, ipos, iw, liw)
subroutine cmumps_store_perminfo(pivrptr, nbpanels, pivr, nass, k, p, lastpanelondisk, lastpivrptrindexfilled)
subroutine cmumps_swap_ldlt(a, la, iw, liw, ioldps, npivp1, ipiv, poselt, lastrow2swap, lda, nfront, level, parpiv, k50, xsize, ibeg_block_to_send)
subroutine cmumps_update_minmax_pivot(diag, dkeep, keep, nullpivot)