1102
1104 IMPLICIT NONE
1105 INTEGER(8) :: POSELT, LA
1106 INTEGER NFRONT,NASS,LIW,INODE,IFLAG,INOPV,
1107 & IOLDPS
1108 INTEGER, intent(inout) :: NNEGW, NB22T1W, NBTINYW
1109 INTEGER, intent(inout) :: DET_EXPW, DET_SIGNW
1110 COMPLEX(kind=8), intent(inout) :: DET_MANTW
1111 INTEGER, intent(in) :: IBEG_BLOCK, IEND_BLOCK
1112 INTEGER, intent(in) :: PIVOT_OPTION,IEND_BLR
1113 INTEGER, intent(inout) :: Inextpiv
1114 LOGICAL, intent(in) :: OOC_EFFECTIVE_ON_FRONT
1115 INTEGER PIVSIZ,LPIV, XSIZE
1116 COMPLEX(kind=8) A(LA)
1117 DOUBLE PRECISION UU, UULOC, SEUIL
1118 INTEGER IW(LIW)
1119 INTEGER KEEP(500)
1120 INTEGER(8) KEEP8(150)
1121 INTEGER LPN_LIST
1122 INTEGER PIVNUL_LIST(LPN_LIST)
1123 DOUBLE PRECISION DKEEP(230)
1124 INTEGER PP_FIRST2SWAP_L, PP_LastPanelonDisk
1125 INTEGER PP_LastPIVRPTRIndexFilled
1126 DOUBLE PRECISION, intent(in) :: MAXFROMM
1127 LOGICAL, intent(inout) :: IS_MAXFROMM_AVAIL
1128 INTEGER, intent(in) :: NVSCHUR
1129 INTEGER, intent(in) :: PARPIV_T1
1130 LOGICAL, intent(in) :: LR_ACTIVATED
1131 include 'mpif.h'
1132 INTEGER (8) :: POSPV1,POSPV2,OFFDAG,APOSJ
1133 INTEGER JMAX, LIM, LIM_SWAP
1134 DOUBLE PRECISION RMAX,AMAX,TMAX, MAX_PREV_in_PARPIV, ABS_PIVOT
1135 DOUBLE PRECISION RMAX_NORELAX, TMAX_NORELAX, UULOCM1
1136 INTEGER(8) :: APOSMAX, APOSROW
1137 DOUBLE PRECISION MAXPIV
1138 DOUBLE PRECISION PIVNUL
1139 DOUBLE PRECISION MAXFROMM_UPDATED
1140 COMPLEX(kind=8) FIXA, CSEUIL
1141 COMPLEX(kind=8) PIVOT,DETPIV
1142 DOUBLE PRECISION ABSDETPIV
1143 include 'mumps_headers.h'
1144 INTEGER :: HF, IPIVNUL
1145 INTEGER :: J
1146 INTEGER(8) :: APOS, J1, J2, JJ, NFRONT8, KK, J1_ini, JJ_ini
1147 INTEGER :: LDA
1148 INTEGER(8) :: LDA8
1149 INTEGER NPIV,IPIV
1150 INTEGER NPIVP1,K
1151 INTEGER :: ISHIFT, K206, IPIV_SHIFT, IPIV_END
1153 COMPLEX(kind=8) ZERO, ONE
1154 parameter( zero = (0.0d0,0.0d0) )
1155 parameter( one = (1.0d0,1.0d0) )
1156 DOUBLE PRECISION RZERO,RONE
1157 parameter(rzero=0.0d0, rone=1.0d0)
1158#if defined(_OPENMP)
1159 LOGICAL :: OMP_FLAG
1160 INTEGER :: NOMP, CHUNK, J1_end
1161#endif
1162 INTEGER I_PIVRPTR, I_PIVR, NBPANELS_L
1163
1164 pivnul = dkeep(1)
1165 fixa =
cmplx(dkeep(2),kind=kind(fixa))
1166 cseuil =
cmplx(seuil,kind=kind(cseuil))
1167 lda = nfront
1168 lda8 = int(lda,8)
1169 nfront8 = int(nfront,8)
1170 k206 = keep(206)
1171 uuloc = uu
1172 IF (uuloc.GT.rzero) THEN
1173 uulocm1 = rone/uuloc
1174 ELSE
1175 uulocm1 = rone
1176 ENDIF
1177 hf = 6 + xsize
1178 IF (keep(50).NE.1 .AND. ooc_effective_on_front) THEN
1180 & i_pivrptr, i_pivr, ioldps+2*nfront+6+keep(ixsz),
1181 & iw, liw)
1182 ENDIF
1183 pivsiz = 1
1184 npiv = iw(ioldps+1+xsize)
1185 npivp1 = npiv + 1
1186 aposmax = poselt+lda8*lda8-1_8
1187 IF(inopv .EQ. -1) THEN
1188 apos = poselt + (lda8+1_8) * int(npiv,8)
1189 pospv1 = apos
1190 CALL zmumps_update_minmax_pivot
1191 & ( abs(a(apos)), dkeep, keep, .true.)
1192 IF(abs(a(apos)).LT.seuil) THEN
1193 IF(dble(a(apos)) .GE. rzero) THEN
1194 a(apos) = cseuil
1195 ELSE
1196 a(apos) = -cseuil
1197 ENDIF
1198 nbtinyw = nbtinyw + 1
1199 ELSE
1200 IF (keep(258) .NE. 0) THEN
1202 ENDIF
1203 ENDIF
1204 IF (keep(50).NE.1 .AND. ooc_effective_on_front) THEN
1205 CALL zmumps_store_perminfo( iw(i_pivrptr), nbpanels_l,
1206 & iw(i_pivr), nass, npivp1, npivp1,
1207 & pp_lastpanelondisk,
1208 & pp_lastpivrptrindexfilled)
1209 ENDIF
1210 GO TO 420
1211 ENDIF
1212 inopv = 0
1213 ishift = 0
1214 ipiv_end = iend_block
1215 IF (k206.GE.1) THEN
1216 IF (inextpiv.GT.npivp1.AND.inextpiv.LE.iend_block) THEN
1217 ishift = inextpiv - npivp1
1218 ENDIF
1219 IF ( k206.EQ.1
1220 & .OR. (k206 .GT.1 .AND. iend_block.EQ.iend_blr) ) THEN
1221 ipiv_end = iend_block + ishift
1222 ENDIF
1223 IF (ishift.GT.0.AND.is_maxfromm_avail) THEN
1224 ipiv = npivp1
1225 apos = poselt + lda8*int(ipiv-1,8) + int(npiv,8)
1226 pospv1 = apos + int(ipiv - npivp1,8)
1227 pivot = a(pospv1)
1228 IF ( maxfromm .GT. pivnul ) THEN
1229 IF (parpiv_t1.NE.0) THEN
1230 maxfromm_updated =
max
1231 & ( maxfromm,
1232 & abs(dble(a(aposmax+int(ipiv,8))))
1233 & )
1234 ELSE
1235 maxfromm_updated = maxfromm
1236 ENDIF
1237 IF ( (abs(pivot) .GE. uuloc*maxfromm_updated).AND.
1238 & abs(pivot) .GT.
max(seuil,tiny(maxfromm_updated))
1239 & ) THEN
1240 ishift = 0
1241 ENDIF
1242 ENDIF
1243 ENDIF
1244 IF ( ishift .GT. 0) THEN
1245 is_maxfromm_avail = .false.
1246 ENDIF
1247 ENDIF
1248 DO 460 ipiv_shift = npivp1+ishift, ipiv_end
1249 IF (ipiv_shift .LE. iend_block) THEN
1250 ipiv=ipiv_shift
1251 ELSE
1252 ipiv = ipiv_shift-iend_block-1+npivp1
1253 IF (ibeg_block.EQ.npivp1) THEN
1254 EXIT
1255 ENDIF
1256 ENDIF
1257 apos = poselt + lda8*int(ipiv-1,8) + int(npiv,8)
1258 pospv1 = apos + int(ipiv - npivp1,8)
1259 pivot = a(pospv1)
1260 abs_pivot = abs(pivot)
1261 IF (uuloc.EQ.rzero.OR.pivot_option.EQ.0) THEN
1262 IF(abs_pivot.LT.seuil) THEN
1263 CALL zmumps_update_minmax_pivot
1264 & ( abs_pivot, dkeep, keep, .true.)
1265 IF(dble(pivot) .GE. rzero) THEN
1266 a(pospv1) = cseuil
1267 ELSE
1268 a(pospv1) = -cseuil
1269 ENDIF
1270 nbtinyw = nbtinyw + 1
1271 ELSE IF (abs_pivot.EQ.rzero) THEN
1272 GO TO 630
1273 ELSE
1274 CALL zmumps_update_minmax_pivot
1275 & ( abs_pivot, dkeep, keep, .false.)
1276 IF (keep(258) .NE. 0) THEN
1278 ENDIF
1279 ENDIF
1280 GO TO 420
1281 ENDIF
1282 IF ( is_maxfromm_avail ) THEN
1283 IF ( maxfromm .GT. pivnul ) THEN
1284 IF (parpiv_t1.NE.0) THEN
1285 maxfromm_updated =
max
1286 & ( maxfromm,
1287 & abs(dble(a(aposmax+int(ipiv,8))))
1288 & )
1289 ELSE
1290 maxfromm_updated = maxfromm
1291 ENDIF
1292 IF ( (abs_pivot .GE. uuloc*maxfromm_updated).AND.
1293 & (abs_pivot .GT.
max(seuil,tiny(maxfromm_updated)))
1294 & ) THEN
1295 CALL zmumps_update_minmax_pivot
1296 & ( abs_pivot,
1297 & dkeep, keep, .false.)
1298 IF (keep(258) .NE. 0) THEN
1300 ENDIF
1301 GOTO 415
1302 ENDIF
1303 ENDIF
1304 is_maxfromm_avail = .false.
1305 ENDIF
1306 amax = -rone
1307 jmax = 0
1308 IF (pivot_option.EQ.3
1309 & ) THEN
1310 lim = nfront - keep(253)-nvschur
1311 ELSEIF (pivot_option.GE.2
1312 & ) THEN
1313 lim = nass
1314 ELSEIF (pivot_option.GE.1) THEN
1315 lim = iend_blr
1316 ELSE
1317 write(*,*) 'Internal error in FAC_I_LDLT 1x1:',
1318 & pivot_option
1320 ENDIF
1321 j1 = apos
1322 j2 = pospv1 - 1_8
1323 DO jj=j1,j2
1324 IF(abs(a(jj)) .GT. amax) THEN
1325 amax = abs(a(jj))
1326 jmax = ipiv - int(pospv1-jj)
1327 ENDIF
1328 ENDDO
1329 j1 = pospv1 + lda8
1330 DO j=1, iend_block - ipiv
1331 IF(abs(a(j1)) .GT. amax) THEN
1332 amax = abs(a(j1))
1333 jmax = ipiv + j
1334 ENDIF
1335 j1 = j1 + lda8
1336 ENDDO
1337 rmax = rzero
1338 j1_ini = j1
1339#if defined(_OPENMP)
1340 j1_end = lim - iend_block
1341 chunk =
max(j1_end,1)
1342 IF ( j1_end.GE.keep(360)) THEN
1343 omp_flag = .true.
1344 chunk =
max(keep(360)/2,(j1_end+nomp-1)/nomp)
1345 ELSE
1346 omp_flag = .false.
1347 ENDIF
1348#endif
1349
1350
1351 DO j=1, lim - iend_block
1352 j1 = j1_ini + int(j-1,8) * lda8
1353 rmax =
max(abs(a(j1)),rmax)
1354 ENDDO
1355
1356 IF (parpiv_t1.NE.0) THEN
1357 rmax_norelax = dble(a(aposmax+int(ipiv,8)))
1358 ELSE
1359 rmax_norelax = rzero
1360 ENDIF
1361 rmax =
max(rmax,rmax_norelax)
1362 IF (
max(amax,rmax,abs(pivot)).LE.pivnul)
THEN
1363 IF ((parpiv_t1.NE.0)
1364 & .AND.(parpiv_t1.NE.-1)
1365 & .AND.(rmax_norelax.LT.0)
1366 & .AND.(ipiv.GT.1)) THEN
1367 max_prev_in_parpiv = rzero
1368 DO jj=1,ipiv-1
1369 max_prev_in_parpiv=
max( max_prev_in_parpiv,
1370 & dble(a(aposmax+int(jj,8))) )
1371 ENDDO
1372 IF (max_prev_in_parpiv.GT.pivnul) THEN
1373 aposrow = poselt + nfront8*int(ipiv-1,8)
1374 DO jj=1,ipiv-1
1375 IF (abs(a(aposrow+jj-1)).GT.pivnul) THEN
1376 GOTO 460
1377 ENDIF
1378 ENDDO
1379 ENDIF
1380 ENDIF
1381 CALL zmumps_update_minmax_pivot
1382 & ( abs(a(pospv1)), dkeep, keep, .true.)
1383
1384 keep(109) = keep(109) + 1
1385 ipivnul = keep(109)
1386
1387 pivnul_list(ipivnul) = iw( ioldps+hf+npiv+ipiv-npivp1 )
1388 IF(dble(fixa).GT.rzero) THEN
1389 IF(dble(pivot) .GE. rzero) THEN
1390 a(pospv1) = fixa
1391 ELSE
1392 a(pospv1) = -fixa
1393 ENDIF
1394 ELSE
1395 j1 = apos
1396 j2 = pospv1 - 1_8
1397 DO jj=j1,j2
1398 a(jj) = zero
1399 ENDDO
1400 j1 = pospv1 + lda8
1401 DO j=1, iend_block - ipiv
1402 a(j1) = zero
1403 j1 = j1 + lda8
1404 ENDDO
1405 DO j=1,lim - iend_block
1406 a(j1) = zero
1407 j1 = j1 + lda8
1408 ENDDO
1409 a(pospv1) = one
1410 ENDIF
1411 pivot = a(pospv1)
1412 GO TO 415
1413 ENDIF
1414 rmax =
max(rmax,abs(rmax_norelax))
1415 IF ( abs(pivot).GE.uuloc*
max(rmax,amax)
1416 & .AND. abs(pivot) .GT.
max(seuil,tiny(rmax)) )
THEN
1417 CALL zmumps_update_minmax_pivot
1418 & ( abs(pivot),
1419 & dkeep, keep, .false.)
1420 IF (keep(258) .NE.0 ) THEN
1422 ENDIF
1423 GO TO 415
1424 END IF
1425 IF (npivp1.EQ.iend_block) THEN
1426 GOTO 460
1427 ELSE IF (jmax.EQ.0) THEN
1428 GOTO 460
1429 ENDIF
1430 IF (
max(abs(pivot),rmax,amax).LE.tiny(rmax))
THEN
1431 GOTO 460
1432 ENDIF
1433 IF (
1434 & (keep(19).NE.0).AND.(
max(amax,rmax,abs(pivot)).LE.seuil)
1435 & )
1436 & THEN
1437 GO TO 460
1438 ENDIF
1439 IF (rmax.LT.amax) THEN
1440 j1 = apos
1441 j2 = pospv1 - 1_8
1442 DO jj=j1,j2
1443 IF(int(pospv1-jj) .NE. ipiv-jmax) THEN
1444 rmax =
max(rmax,abs(a(jj)))
1445 ENDIF
1446 ENDDO
1447 j1 = pospv1 + lda8
1448 DO j=1,iend_block-ipiv
1449 IF(ipiv+j .NE. jmax) THEN
1450 rmax =
max(abs(a(j1)),rmax)
1451 ENDIF
1452 j1 = j1 + lda8
1453 ENDDO
1454 ENDIF
1455 aposj = poselt + int(jmax-1,8)*lda8 + int(npiv,8)
1456 pospv2 = aposj + int(jmax - npivp1,8)
1457 IF (ipiv.LT.jmax) THEN
1458 offdag = aposj + int(ipiv - npivp1,8)
1459 ELSE
1460 offdag = apos + int(jmax - npivp1,8)
1461 END IF
1462 tmax = rzero
1463#if defined(_OPENMP)
1464 j1_end = lim-jmax
1465 chunk =
max(j1_end,1)
1466 IF (j1_end.GE.keep(360)) THEN
1467 omp_flag = .true.
1468 chunk =
max(keep(360)/2,(j1_end+nomp-1)/nomp)
1469 ELSE
1470 omp_flag = .false.
1471 ENDIF
1472#endif
1473 IF (jmax .LT. ipiv) THEN
1474 jj_ini = pospv2
1475
1476
1477 DO k = 1, lim - jmax
1478 jj = jj_ini+ int(k,8)*nfront8
1479 IF (jmax+k.NE.ipiv) THEN
1480 tmax=
max(tmax,abs(a(jj)))
1481 ENDIF
1482 ENDDO
1483
1484 DO kk = aposj, pospv2-1_8
1485 tmax =
max(tmax,abs(a(kk)))
1486 ENDDO
1487 ELSE
1488 jj_ini = pospv2
1489
1490
1491 DO k = 1, lim-jmax
1492 jj = jj_ini + int(k,8)*nfront8
1493 tmax=
max(tmax,abs(a(jj)))
1494 ENDDO
1495
1496 DO kk = aposj, pospv2 - 1_8
1497 IF (kk.NE.offdag) THEN
1498 tmax =
max(tmax,abs(a(kk)))
1499 ENDIF
1500 ENDDO
1501 ENDIF
1502 IF (parpiv_t1.NE.0) THEN
1503 tmax_norelax =
max(seuil*uulocm1,
1504 & abs(dble(a(aposmax+int(jmax,8))))
1505 & )
1506 ELSE
1507 tmax_norelax = seuil*uulocm1
1508 ENDIF
1509 tmax =
max(tmax,tmax_norelax)
1510 detpiv = a(pospv1)*a(pospv2) - a(offdag)**2
1511 absdetpiv = abs(detpiv)
1512 IF (seuil.GT.rzero) THEN
1513 IF (sqrt(absdetpiv) .LE. seuil ) THEN
1514 GOTO 460
1515 ENDIF
1516 ENDIF
1517 maxpiv =
max(abs(a(pospv1)),abs(a(pospv2)))
1518 IF (maxpiv.EQ.rzero) maxpiv = rone
1519 IF ((abs(a(pospv2))*rmax+amax*tmax)*uuloc.GT.
1520 & absdetpiv .OR. (absdetpiv .EQ. rzero) ) THEN
1521 GO TO 460
1522 ENDIF
1523 IF ((abs(a(pospv1))*tmax+amax*rmax)*uuloc.GT.
1524 & absdetpiv .OR. (absdetpiv.EQ. rzero) ) THEN
1525 GO TO 460
1526 ENDIF
1527 CALL zmumps_update_minmax_pivot
1528 & ( sqrt(absdetpiv),
1529 & dkeep, keep, .false.)
1530 IF (keep(258) .NE.0 ) THEN
1532 ENDIF
1533 pivsiz = 2
1534 nb22t1w = nb22t1w + 1
1535 415 CONTINUE
1536 IF (k206.GE.1) THEN
1537 inextpiv =
max(npivp1+pivsiz, ipiv+1)
1538 ENDIF
1539 DO k=1,pivsiz
1540 IF (pivsiz .EQ. 2) THEN
1541 IF (k==1) THEN
1542 lpiv =
min(ipiv,jmax)
1543 ELSE
1544 lpiv =
max(ipiv,jmax)
1545 ENDIF
1546 ELSE
1547 lpiv = ipiv
1548 ENDIF
1549 IF (lpiv.EQ.npivp1) GOTO 416
1550 IF (keep(405) .EQ. 0) THEN
1551 keep8(80) = keep8(80)+1
1552 ELSE
1553
1554 keep8(80) = keep8(80)+1
1555
1556 ENDIF
1557 lim_swap = nfront
1558 CALL zmumps_swap_ldlt( a, la, iw, liw,
1559 & ioldps, npivp1, lpiv, poselt, lim_swap,
1560 & lda, nfront, 1, parpiv_t1, keep(50),
1561 & keep(ixsz), -9999)
1562 416 CONTINUE
1563 IF (keep(50).NE.1 .AND. ooc_effective_on_front) THEN
1564 CALL zmumps_store_perminfo( iw(i_pivrptr), nbpanels_l,
1565 & iw(i_pivr), nass, npivp1, lpiv, pp_lastpanelondisk,
1566 & pp_lastpivrptrindexfilled)
1567 ENDIF
1568 npivp1 = npivp1 + 1
1569 ENDDO
1570 IF(pivsiz .EQ. 2) THEN
1571 a(poselt+(lda8+1_8)*int(npiv,8)+1_8) = detpiv
1572 ENDIF
1573 GOTO 420
1574 460 CONTINUE
1575 IF (k206 .GE. 1) THEN
1576 inextpiv=iend_block+1
1577 ENDIF
1578 IF (iend_block.EQ.nass) THEN
1579 inopv = 1
1580 ELSE
1581 inopv = 2
1582 ENDIF
1583 GO TO 420
1584 630 CONTINUE
1585 pivsiz = 0
1586 iflag = -10
1587 420 CONTINUE
1588 is_maxfromm_avail = .false.
1589 RETURN