C
C  This file is part of MUMPS 5.5.1, released
C  on Tue Jul 12 13:17:24 UTC 2022
C
C
C  Copyright 1991-2022 CERFACS, CNRS, ENS Lyon, INP Toulouse, Inria,
C  Mumps Technologies, University of Bordeaux.
C
C  This version of MUMPS is provided to you free of charge. It is
C  released under the CeCILL-C license 
C  (see doc/CeCILL-C_V1-en.txt, doc/CeCILL-C_V1-fr.txt, and
C  https://cecill.info/licences/Licence_CeCILL-C_V1-en.html)
C
      SUBROUTINE ZMUMPS_FAC_B( N, S_IS_POINTERS, LA, LIW, SYM_PERM,
     & NA, LNA, NE_STEPS, NFSIZ, FILS, STEP, FRERE, DAD, CAND, 
     & ISTEP_TO_INIV2, TAB_POS_IN_PERE, PTRAR, LDPTRAR, PTRIST,
     & PTLUST_S, PTRFAC, IW1, IW2, ITLOC, RHS_MUMPS, POOL, LPOOL,
     &  CNTL1, ICNTL, INFO, RINFO, KEEP, KEEP8, PROCNODE_STEPS, SLAVEF,
     & COMM_NODES, MYID, MYID_NODES, BUFR, LBUFR, LBUFR_BYTES,
     & ZMUMPS_LBUF, INTARR, DBLARR, root, NELT, FRTPTR, FRTELT,
     & COMM_LOAD, ASS_IRECV, SEUIL, SEUIL_LDLT_NIV2, MEM_DISTRIB,
     & DKEEP, PIVNUL_LIST, LPN_LIST, LRGROUPS
     & ,IPOOL_B_L0_OMP, LPOOL_B_L0_OMP, IPOOL_A_L0_OMP,
     & LPOOL_A_L0_OMP, L_VIRT_L0_OMP, VIRT_L0_OMP,
     & VIRT_L0_OMP_MAPPING, L_PHYS_L0_OMP, PHYS_L0_OMP, PERM_L0_OMP,
     & PTR_LEAFS_L0_OMP, L0_OMP_MAPPING, LL0_OMP_MAPPING, THREAD_LA,
     & L0_OMP_FACTORS, LL0_OMP_FACTORS, I4_L0_OMP, NBSTATS_I4,
     & NBCOLS_I4, I8_L0_OMP, NBSTATS_I8, NBCOLS_I8
     &     )
      USE ZMUMPS_LOAD 
      USE ZMUMPS_BUF, ONLY : ZMUMPS_BUF_ALLOC_CB, ZMUMPS_BUF_DEALL_CB
      USE ZMUMPS_FAC_S_IS_POINTERS_M, ONLY : S_IS_POINTERS_T
      USE OMP_LIB
      USE MUMPS_TPS_M
      USE ZMUMPS_TPS_M
      USE ZMUMPS_FAC_OMP_M
      USE ZMUMPS_STRUC_DEF, ONLY : ZMUMPS_ROOT_STRUC
     &                           , ZMUMPS_L0OMPFAC_T
      IMPLICIT NONE
      INCLUDE 'mpif.h'
      TYPE (ZMUMPS_ROOT_STRUC) :: root
      INTEGER(8) :: LA
      INTEGER N,LIW,LPOOL,SLAVEF,COMM_NODES
      INTEGER MYID, MYID_NODES,LNA
      TYPE (S_IS_POINTERS_T) :: S_IS_POINTERS
      DOUBLE PRECISION RINFO(40)
      INTEGER, INTENT( IN ) :: LBUFR, LBUFR_BYTES
      INTEGER :: BUFR( LBUFR )
      INTEGER, INTENT( IN ) :: ZMUMPS_LBUF
      INTEGER, DIMENSION(0:SLAVEF - 1) :: MEM_DISTRIB
      INTEGER NELT, LDPTRAR
      INTEGER FRTPTR(*), FRTELT(*)
      INTEGER LRGROUPS(N)
      DOUBLE PRECISION CNTL1
      INTEGER   ICNTL(60)
      INTEGER   INFO(80), KEEP(500)
      INTEGER(8) KEEP8(150)
      INTEGER   SYM_PERM(N), NA(LNA),
     &          NE_STEPS(KEEP(28)), FILS(N),
     &          FRERE(KEEP(28)), NFSIZ(KEEP(28)), 
     &          DAD(KEEP(28))
      INTEGER   CAND(SLAVEF+1, max(1,KEEP(56)))
      INTEGER   STEP(N)
      INTEGER(8), INTENT(IN) :: PTRAR(LDPTRAR,2)
      INTEGER(8) :: PTRFAC(KEEP(28))
      INTEGER   PTRIST(KEEP(28)), PTLUST_S(KEEP(28))
      INTEGER   IW1(2*KEEP(28)), ITLOC(N+KEEP(253)), POOL(LPOOL)
      COMPLEX(kind=8) :: RHS_MUMPS(KEEP(255))
      INTEGER(8) :: IW2(2*KEEP(28))
      INTEGER   PROCNODE_STEPS(KEEP(28))
      INTEGER   COMM_LOAD, ASS_IRECV
      INTEGER   ISTEP_TO_INIV2(KEEP(71)), 
     &          TAB_POS_IN_PERE(SLAVEF+2,max(1,KEEP(56)))
      COMPLEX(kind=8)   DBLARR(KEEP8(26))
      INTEGER   INTARR(KEEP8(27))
      DOUBLE PRECISION SEUIL, SEUIL_LDLT_NIV2
      INTEGER LPN_LIST
      INTEGER PIVNUL_LIST(LPN_LIST)
      DOUBLE PRECISION DKEEP(230)
      INTEGER, INTENT (IN) :: LPOOL_B_L0_OMP
      INTEGER, INTENT (IN) :: IPOOL_B_L0_OMP( LPOOL_B_L0_OMP )
      INTEGER, INTENT (IN) :: LPOOL_A_L0_OMP
      INTEGER, INTENT (IN) :: IPOOL_A_L0_OMP( LPOOL_A_L0_OMP )
      INTEGER, INTENT (IN) :: L_PHYS_L0_OMP
      INTEGER, INTENT (IN) :: PHYS_L0_OMP( L_PHYS_L0_OMP )
      INTEGER, INTENT (IN) :: L_VIRT_L0_OMP
      INTEGER, INTENT (IN) :: VIRT_L0_OMP( L_VIRT_L0_OMP )
      INTEGER, INTENT (IN) :: VIRT_L0_OMP_MAPPING( L_VIRT_L0_OMP )
      INTEGER, INTENT (IN) :: PERM_L0_OMP( L_PHYS_L0_OMP )
      INTEGER, INTENT (IN) :: PTR_LEAFS_L0_OMP( L_PHYS_L0_OMP + 1)
      INTEGER, INTENT (IN) :: LL0_OMP_MAPPING
      INTEGER, INTENT (OUT):: L0_OMP_MAPPING( LL0_OMP_MAPPING )
      INTEGER, INTENT (IN) :: LL0_OMP_FACTORS
      TYPE(ZMUMPS_L0OMPFAC_T), INTENT (OUT) :: L0_OMP_FACTORS(
     &                                         LL0_OMP_FACTORS )
      INTEGER, INTENT (IN) :: NBSTATS_I4, NBSTATS_I8
      INTEGER, INTENT (IN) :: NBCOLS_I4, NBCOLS_I8
      INTEGER, INTENT (IN) :: I4_L0_OMP(NBSTATS_I4, NBCOLS_I4)
      INTEGER(8), INTENT (IN) :: I8_L0_OMP(NBSTATS_I8, NBCOLS_I8)
      INTEGER(8), INTENT ( IN ) :: THREAD_LA
       INTEGER, EXTERNAL :: MUMPS_PROCNODE
      INTEGER allocok
      DOUBLE PRECISION UULOC
      INTEGER IERR
      INTEGER LP, MPRINT
      LOGICAL LPOK
      INTEGER NSTK,PTRAST
      INTEGER PIMASTER, PAMASTER
      LOGICAL PROK
      DOUBLE PRECISION,PARAMETER :: ZERO = 0.0D0
      INTEGER I
      INTEGER LTPS_ARR
      TYPE (MUMPS_TPS_T), DIMENSION(:), ALLOCATABLE :: MUMPS_TPS_ARR
      TYPE (ZMUMPS_TPS_T), DIMENSION(:), ALLOCATABLE :: ZMUMPS_TPS_ARR
      INTEGER NBROOT_UNDER_L0
      INTEGER :: NSTEPSDONE
      DOUBLE PRECISION :: OPASS, OPELI
      INTEGER :: NELVA, COMP
      INTEGER :: MAXFRT, NTOTPV, NMAXNPIV, NOFFNEGPV
      INTEGER :: NB22T1, NB22T2, NBTINY, DET_EXP, DET_SIGN
      COMPLEX(kind=8) :: DET_MANT
      INTEGER :: NTOTPVTOT
      INTEGER(8) :: POSFAC, LRLU, IPTRLU, LRLUS
      INTEGER IWPOS, LEAF, NBROOT, NROOT
      INTEGER    :: LIW_ARG_FAC_PAR
      INTEGER(8) :: LA_ARG_FAC_PAR
      COMPLEX(kind=8), TARGET:: CDUMMY(1)
      INTEGER, TARGET :: IDUMMY(1)
      LOGICAL :: IW_DUMMY, A_DUMMY
      KEEP(41)=0
      KEEP(42)=0
      LP     = ICNTL(1)
      LPOK   = (LP.GT.0) .AND. (ICNTL(4).GE.1)
      MPRINT = ICNTL(2)
      PROK   = (MPRINT.GT.0) .AND. (ICNTL(4).GE.2)
      UULOC = CNTL1
      PIMASTER   = 1
      NSTK       = PIMASTER + KEEP(28)
      PTRAST = 1
      PAMASTER = 1 + KEEP(28)
      IF (KEEP(4).LE.0) KEEP(4)=32
      IF (KEEP(5).LE.0) KEEP(5)=16
      IF (KEEP(5).GT.KEEP(4)) KEEP(5) = KEEP(4)
      IF (KEEP(6).LE.0) KEEP(6)=24
      IF (KEEP(3).LE.KEEP(4)) KEEP(3)=KEEP(4)*2
      IF (KEEP(6).GT.KEEP(3)) KEEP(6) = KEEP(3)
      POSFAC = 1_8
      IWPOS  = 1
      LRLU = LA
      LRLUS = LRLU
      KEEP8(63) = 0_8
      KEEP8(64) = 0_8
      KEEP8(65) = 0_8
      KEEP8(66) = 0_8
      KEEP8(68) = 0_8
      KEEP8(69) = 0_8
      KEEP8(70) = 0_8
      KEEP8(71) = 0_8
      KEEP8(73) = 0_8
      KEEP8(74) = 0_8
      IPTRLU = LRLU
      NSTEPSDONE = 0
      OPASS      = 0.0D0
      OPELI      = 0.0D0
      NELVA      = 0
      COMP       = 0
      MAXFRT     = 0  
      NMAXNPIV   = 0
      NTOTPV     = 0
      NOFFNEGPV  = 0
      NB22T1     = 0  
      NB22T2     = 0  
      NBTINY     = 0  
      DET_EXP    = 0
      DET_SIGN   = 1
      DET_MANT   = cmplx(1.0D0,0.0D0, kind=kind(1.0D0))
      IW1(NSTK:NSTK+KEEP(28)-1) = NE_STEPS(1:KEEP(28))
      CALL MUMPS_INIT_NROOT_DIST(N, NBROOT, NROOT,
     &                     MYID_NODES,
     &                     SLAVEF, NA, LNA,
     &                     KEEP, STEP,
     &                     PROCNODE_STEPS)
      IF (KEEP(400) .GT. 0
     &   ) THEN
         IF (LPOOL .NE. LPOOL_A_L0_OMP) THEN
          WRITE(*,*) "Check LPOOL vs. LPOOL_A_L0_OMP",
     &    LPOOL, LPOOL_A_L0_OMP, KEEP(28)
          CALL MUMPS_ABORT()
        ENDIF
        DO I = 1, LPOOL
          POOL(I) = IPOOL_A_L0_OMP(I)
        ENDDO
      ELSE
        CALL MUMPS_INIT_POOL_DIST(N, LEAF,
     &                     MYID_NODES,
     &                     SLAVEF, NA, LNA,
     &                     KEEP,KEEP8, STEP,
     &                     PROCNODE_STEPS,
     &                     POOL, LPOOL)
        CALL ZMUMPS_INIT_POOL_LAST3(POOL, LPOOL, LEAF)     
      ENDIF  
      CALL ZMUMPS_LOAD_INIT_SBTR_STRUCT(POOL, LPOOL,KEEP,KEEP8)
      IF ( KEEP( 38 ) .NE. 0 ) THEN
        NBROOT = NBROOT + root%NPROW * root%NPCOL - 1
      END IF
      IF ( root%yes )  THEN 
         IF ( MUMPS_PROCNODE( PROCNODE_STEPS(STEP(KEEP(38))),
     &                                       KEEP(199) )
     &         .NE. MYID_NODES ) THEN
             NROOT = NROOT + 1
         END IF
      END IF
      PTRIST(1:KEEP(28))=0
      PTLUST_S(1:KEEP(28))=0
      PTRFAC(1:KEEP(28))=-99999_8
      IW2(PTRAST:PTRAST+KEEP(28)-1)=0_8
      IW1(PIMASTER:PIMASTER+KEEP(28)-1)=-99999_8
      KEEP(405) = 0
      DKEEP(95)=0.0D0 
      DKEEP(96)=0.0D0 
      NBROOT_UNDER_L0 = 0
      IF (KEEP(400).GT.0
     &   ) THEN
        KEEP(405)=1
        ALLOCATE( MUMPS_TPS_ARR( KEEP(400) ), stat=allocok )
        IF (allocok .GT. 0) THEN
          IF (LPOK) THEN
            WRITE(LP,*) "Problem allocating MUMPS_TPS_ARR",
     &                KEEP(400) 
          ENDIF
          CALL MUMPS_ABORT()
        ENDIF
        ALLOCATE( ZMUMPS_TPS_ARR( KEEP(400) ), stat=allocok )
        IF (allocok .GT. 0) THEN
          WRITE(*,*) "Problem allocating ZMUMPS_TPS_ARR", KEEP(400)
          CALL MUMPS_ABORT()
        ENDIF
        CALL ZMUMPS_FAC_L0_OMP(N,LIW, IW1(NSTK), NFSIZ,
     &  FILS,STEP, FRERE, DAD, ISTEP_TO_INIV2, TAB_POS_IN_PERE, PTRIST,
     &  IW2(PTRAST), IW1(PIMASTER), IW2(PAMASTER), PTRAR(1,2), 
     &  PTRAR(1,1), 
     &  ITLOC, RHS_MUMPS, RINFO, NROOT, NBROOT, NBROOT_UNDER_L0,
     &  UULOC, ICNTL, PTLUST_S, PTRFAC, INFO, KEEP, KEEP8,
     &  PROCNODE_STEPS,SLAVEF, COMM_NODES, MYID_NODES, BUFR,
     &  LBUFR,LBUFR_BYTES,INTARR,DBLARR,root, SYM_PERM, NELT, FRTPTR,
     &  FRTELT, LDPTRAR, COMM_LOAD, ASS_IRECV, SEUIL, SEUIL_LDLT_NIV2,
     &  MEM_DISTRIB, NE_STEPS, DKEEP,PIVNUL_LIST,LPN_LIST,
     &  LPOOL_B_L0_OMP, IPOOL_B_L0_OMP, L_VIRT_L0_OMP,
     &  VIRT_L0_OMP, VIRT_L0_OMP_MAPPING, L_PHYS_L0_OMP, PHYS_L0_OMP,
     &  PERM_L0_OMP, PTR_LEAFS_L0_OMP, L0_OMP_MAPPING, LL0_OMP_MAPPING,
     &  THREAD_LA, MUMPS_TPS_ARR, ZMUMPS_TPS_ARR, NSTEPSDONE,
     &  OPASS, OPELI, NELVA, COMP, MAXFRT, NMAXNPIV, NTOTPV, NOFFNEGPV,
     &  NB22T1, NBTINY, DET_EXP, DET_MANT, DET_SIGN,
     &  LRGROUPS(1), L0_OMP_FACTORS, LL0_OMP_FACTORS,
     &  I4_L0_OMP, NBSTATS_I4, NBCOLS_I4,
     &  I8_L0_OMP, NBSTATS_I8, NBCOLS_I8 )
        KEEP(405)=0
        DKEEP(16) = OPELI
        KEEP8(75)=KEEP8(76)
        KEEP8(63)=KEEP8(74)
        KEEP8(62) = KEEP8(74)-KEEP8(62)
        IF (INFO(1) .LT. 0) THEN
          KEEP8(69) = KEEP8(73)
        ENDIF
        KEEP8(74) = KEEP8(73)
        IF ((INFO(1).GE.0).AND.(KEEP8(74).GT.KEEP8(75))) THEN
          INFO(1) = -19
          CALL MUMPS_SET_IERROR (
     &             KEEP8(74)-KEEP8(75), INFO(2))
          IF (LPOK) THEN
            WRITE(LP,'(/A/,A,I8,A,I10/,A/,A/)')
     &     '** ERROR: memory allowed (ICNTL(23)) is not large enough:',
     &     '   INFO(1)=',  INFO(1), ' INFO(2)=',  INFO(2),
     &     '   memory used at the end of the treatment of L0 thread ',
     &     '   does not enable processing nodes above L0 thread '
          ENDIF
        ENDIF
        KEEP8(66) = KEEP8(68)
        KEEP8(65) = KEEP8(64) + KEEP8(71) 
      ENDIF
        KEEP8(67) = LRLUS
      IF (associated(S_IS_POINTERS%IW)) THEN
        WRITE(*,*) " Internal error ZMUMPS_FAC_B IW"
        CALL MUMPS_ABORT()
      ENDIF
      IF (INFO(1) .GE. 0 ) THEN
        ALLOCATE(S_IS_POINTERS%IW(LIW), stat=allocok)
        IF (allocok .GT.0) THEN
          INFO(1) = -13
          INFO(2) = LIW
          IF (LPOK) THEN
            WRITE(LP,*) 
     &     'Allocation error for id%IS(',LIW,') on worker',
     &      MYID_NODES
          ENDIF
        ENDIF
      ENDIF
      IF (INFO(1) .GE. 0) THEN
        IF (.NOT. associated(S_IS_POINTERS%A)) THEN
          ALLOCATE(S_IS_POINTERS%A(LA), stat=allocok)
          IF (allocok .GT. 0) THEN
            INFO(1) = -13
            CALL MUMPS_SETI8TOI4(LA, INFO(2))
            DEALLOCATE(S_IS_POINTERS%IW); NULLIFY(S_IS_POINTERS%IW)
            KEEP8(23)=0_8
          ELSE
            KEEP8(23)=LA
          ENDIF
        ENDIF
      ENDIF
      IF (INFO(1) .GE. 0) THEN
        CALL ZMUMPS_BUF_ALLOC_CB( ZMUMPS_LBUF, IERR )
        IF ( IERR .NE. 0 ) THEN
          INFO(1)= -13
          INFO(2)= (ZMUMPS_LBUF+KEEP(34)-1)/KEEP(34)
          IF (LPOK) THEN
            WRITE(LP,*) 
     &     'Allocation error in ZMUMPS_BUF_ALLOC_CB'
     &     ,INFO(2), ' on worker', MYID_NODES
          ENDIF
          DEALLOCATE(S_IS_POINTERS%IW); NULLIFY(S_IS_POINTERS%IW)
          DEALLOCATE(S_IS_POINTERS%A); NULLIFY(S_IS_POINTERS%A)
        END IF
      ENDIF
      IF ( KEEP(400) .EQ. 0
     &   ) THEN
         LTPS_ARR = 1
         ALLOCATE( MUMPS_TPS_ARR(1))
         ALLOCATE(ZMUMPS_TPS_ARR(1))
      ELSE
         LTPS_ARR = KEEP(400)
      ENDIF
      IW_DUMMY = .FALSE.
      A_DUMMY = .FALSE.
      IF (INFO(1) .GE. 0) THEN
        LIW_ARG_FAC_PAR = LIW
        LA_ARG_FAC_PAR  = LA
      ELSE
        LIW_ARG_FAC_PAR = 1
        LA_ARG_FAC_PAR  = 1_8
        IF (.NOT. associated(S_IS_POINTERS%IW)) THEN
          S_IS_POINTERS%IW => IDUMMY
          IW_DUMMY = .TRUE.
        ENDIF
        IF (.NOT. associated(S_IS_POINTERS%A)) THEN
          S_IS_POINTERS%A  => CDUMMY
          A_DUMMY = .TRUE.
        ENDIF
      ENDIF
      IF ( INFO(1) .LT. 0 ) THEN
        CALL ZMUMPS_BDC_ERROR( MYID_NODES, SLAVEF, COMM_NODES, KEEP )
      ENDIF
      KEEP(398)=NSTEPSDONE
      CALL ZMUMPS_FAC_PAR_I(N,S_IS_POINTERS%IW(1),LIW_ARG_FAC_PAR,
     & S_IS_POINTERS%A(1),LA_ARG_FAC_PAR,IW1(NSTK),
     & NFSIZ,FILS,STEP,FRERE,DAD,CAND,ISTEP_TO_INIV2, TAB_POS_IN_PERE,
     & NSTEPSDONE, OPASS, OPELI, NELVA, COMP, MAXFRT, NMAXNPIV, NTOTPV,
     & NOFFNEGPV, NB22T1, NB22T2, NBTINY, DET_EXP, DET_MANT, DET_SIGN,
     & PTRIST, IW2(PTRAST), IW1(PIMASTER), IW2(PAMASTER),
     & PTRAR(1,2), PTRAR(1,1),          
     & ITLOC, RHS_MUMPS, POOL, LPOOL,
     & L0_OMP_MAPPING, LL0_OMP_MAPPING,
     & MUMPS_TPS_ARR, ZMUMPS_TPS_ARR, LTPS_ARR,
     & RINFO, POSFAC, IWPOS, LRLU, IPTRLU, LRLUS, LEAF, NROOT, NBROOT,
     & NBROOT_UNDER_L0,
     & UULOC, ICNTL, PTLUST_S, PTRFAC, INFO, KEEP, KEEP8,
     & PROCNODE_STEPS,SLAVEF,MYID,COMM_NODES, MYID_NODES, BUFR, LBUFR,
     & LBUFR_BYTES, INTARR, DBLARR, root, SYM_PERM, NELT, FRTPTR,
     & FRTELT, LDPTRAR, COMM_LOAD, ASS_IRECV, SEUIL, SEUIL_LDLT_NIV2,
     & MEM_DISTRIB,NE_STEPS, DKEEP(1),PIVNUL_LIST(1),LPN_LIST,
     & LRGROUPS(1) )
      IF (IW_DUMMY) THEN
        NULLIFY( S_IS_POINTERS%IW )
      ENDIF
      IF (A_DUMMY) THEN
        NULLIFY( S_IS_POINTERS%A )
      ENDIF
      CALL ZMUMPS_BUF_DEALL_CB( IERR )
      RINFO(2)  = dble(OPASS)
      RINFO(3)  = dble(OPELI)
      INFO(13)  = NELVA
      INFO(14)  = COMP
      KEEP(33)  = MAXFRT; INFO(11)  = MAXFRT
      KEEP(246) = NMAXNPIV
      KEEP(89)  = NTOTPV; INFO(23)  = NTOTPV
      INFO(12)  = NOFFNEGPV
      KEEP(103) = NB22T1
      KEEP(105) = NB22T2
      KEEP(98)  = NBTINY
      IF (KEEP(258) .NE. 0) THEN
        KEEP(260) = KEEP(260) * DET_SIGN
        KEEP(259) = KEEP(259) + DET_EXP
        CALL ZMUMPS_UPDATEDETER( DET_MANT, DKEEP(6), KEEP(259) )
      ENDIF
      IF (KEEP(400) .GT. 0
     &  ) THEN
        IF (LL0_OMP_FACTORS.NE.KEEP(400)) THEN
          WRITE(*,*) "Internal error in ZMUMPS_FAC_B, KEEP(400), L..=",
     &    KEEP(400), LL0_OMP_FACTORS
          CALL MUMPS_ABORT()
        ENDIF
        IF ( INFO(1) .GE. 0 ) THEN
          CALL ZMUMPS_L0OMP_COPY_IW(S_IS_POINTERS%IW,
     &    LIW, IWPOS, MUMPS_TPS_ARR, KEEP, PTLUST_S,
     &    ICNTL, INFO)
        ENDIF
!$OMP   PARALLEL DO
        DO I=1, KEEP(400)
          IF (INFO(1) .LT. 0) THEN
            IF ( associated( L0_OMP_FACTORS(I)%A ) ) THEN
              DEALLOCATE( L0_OMP_FACTORS(I)%A )
              NULLIFY   ( L0_OMP_FACTORS(I)%A )
              CALL MUMPS_DM_FAC_UPD_DYN_MEMCNTS(
     &        -L0_OMP_FACTORS(I)%LA, .TRUE., 
     &        KEEP8, INFO(1), INFO(2), .TRUE., .FALSE. )
            ENDIF
            L0_OMP_FACTORS(I)%LA  =  -99999_8
          ENDIF
          IF (associated(MUMPS_TPS_ARR(I)%IW)) THEN
            DEALLOCATE(MUMPS_TPS_ARR(I)%IW)
            NULLIFY(MUMPS_TPS_ARR(I)%IW)
            CALL MUMPS_DM_FAC_UPD_DYN_MEMCNTS(
     &              -((int(MUMPS_TPS_ARR(I)%LIW,8) * int(KEEP(34),8))
     &              / int(KEEP(35),8)),
     &      .TRUE., 
     &      KEEP8, INFO(1), INFO(2), .TRUE., .FALSE. )
          ENDIF
        ENDDO
!$OMP   END PARALLEL DO
      ENDIF
      IF (allocated(MUMPS_TPS_ARR)) THEN
        DEALLOCATE(MUMPS_TPS_ARR)
      ENDIF
      IF (allocated(ZMUMPS_TPS_ARR)) THEN
        DEALLOCATE(ZMUMPS_TPS_ARR)
      ENDIF
      POSFAC = POSFAC -1_8
      IWPOS = IWPOS -1
      IF (KEEP(201).LE.0) THEN
        IF (KEEP(201) .EQ. -1 .AND. INFO(1) .LT. 0) THEN
          POSFAC = 0_8
        ENDIF
        KEEP8(31) = POSFAC 
         RINFO(6)  = ZERO
      ELSE
         RINFO(6)  = dble(KEEP8(31)*int(KEEP(35),8))/1D6
      ENDIF
      KEEP8(48) = KEEP8(31)+KEEP8(71)+KEEP8(64)
      KEEP(32) = IWPOS
      CALL MUMPS_SETI8TOI4(KEEP8(48), INFO(9))
      INFO(10) = KEEP(32)
      KEEP8(67) = LA - KEEP8(67)
      CALL MPI_ALLREDUCE(NTOTPV, NTOTPVTOT, 1, MPI_INTEGER, MPI_SUM, 
     &                COMM_NODES, IERR)
      IF ( ( (INFO(1).EQ.-10 .OR. INFO(1).EQ.-40)
     &       .AND. (NTOTPVTOT.EQ.N) )
     &     .OR. ( NTOTPVTOT.GT.N ) ) THEN
       write(*,*) ' Error 1 NTOTPVTOT=', NTOTPVTOT,N
       CALL MUMPS_ABORT()
      ENDIF
      IF ( (KEEP(19).NE.0 ) .AND. (NTOTPVTOT.NE.N) .AND. 
     &     (INFO(1).GE.0) )  THEN
       write(*,*) ' Error 2 NTOTPVTOT=', NTOTPVTOT 
       CALL MUMPS_ABORT()
      ENDIF
      IF ( (INFO(1) .GE. 0 ) 
     &      .AND. (NTOTPVTOT.NE.N) ) THEN
         INFO(1) = -10
      ENDIF
      IF (INFO(1).EQ.-10) THEN
         INFO(2) = NTOTPVTOT
      ENDIF
      IF (PROK) THEN
        WRITE (MPRINT,99980) INFO(1), INFO(2),
     &       KEEP(28), KEEP8(48), INFO(10), INFO(11)
        IF(KEEP(50) .EQ. 0) THEN
          WRITE(MPRINT,99982) INFO(12)
        ENDIF
        WRITE (MPRINT, 99986)
     &       INFO(13), INFO(14), RINFO(2), RINFO(3)
        IF (KEEP(97) .NE. 0) THEN
           WRITE (MPRINT, 99987)  INFO(25)
        ENDIF
      ENDIF
      RETURN
99980 FORMAT (/' LEAVING FACTORIZATION PHASE WITH ...'/
     &      ' INFO (1)                                      =',I15/
     &      '  --- (2)                                      =',I15/
     &      '           Number of nodes in the tree         =',I15/
     &      ' INFO (9)  Real space for factors              =',I15/
     &      '  --- (10) Integer space for factors           =',I15/
     &      '  --- (11) Maximum size of frontal matrices    =',I15)
99982 FORMAT ('  --- (12) Number of off diagonal pivots       =',I15)
99986 FORMAT ('  --- (13) Number of delayed pivots            =',I15/
     &      '  --- (14) Number of memory compresses         =',I15/
     &  ' RINFO(2)  Operations during node assembly     =',1PD10.3/
     &  ' -----(3)  Operations during node elimination  =',1PD10.3)
99987 FORMAT (' INFO (25) Number of tiny pivots(static)       =',I15)
      END SUBROUTINE ZMUMPS_FAC_B
      SUBROUTINE ZMUMPS_FAC_PAR_I(N, IW, LIW, A, LA, NSTK_STEPS,
     & ND,FILS,STEP, FRERE, DAD, CAND, ISTEP_TO_INIV2,
     & TAB_POS_IN_PERE, NSTEPSDONE, OPASS, OPELI, NELVA, COMP,
     & MAXFRT, NMAXNPIV, NTOTPV, NOFFNEGPV, NB22T1, NB22T2, NBTINY,
     & DET_EXP, DET_MANT, DET_SIGN, PTRIST, PTRAST, PIMASTER, PAMASTER,
     & PTRARW, PTRAIW, ITLOC, RHS_MUMPS, IPOOL, LPOOL,
     & L0_OMP_MAPPING, LL0_OMP_MAPPING,
     & MUMPS_TPS_ARR, ZMUMPS_TPS_ARR, LTPS_ARR,
     & RINFO, POSFAC ,IWPOS, LRLU, IPTRLU, LRLUS, LEAF, NBROOT, NBRTOT,
     & NBROOT_UNDER_L0, 
     & UU, ICNTL, PTLUST, PTRFAC, INFO, KEEP, KEEP8,
     & PROCNODE_STEPS, SLAVEF, MYID, COMM_NODES, MYID_NODES,
     & BUFR, LBUFR, LBUFR_BYTES, INTARR, DBLARR, root,
     & PERM, NELT, FRTPTR, FRTELT, LPTRAR, COMM_LOAD, ASS_IRECV,
     & SEUIL, SEUIL_LDLT_NIV2, MEM_DISTRIB, NE, DKEEP,
     & PIVNUL_LIST,LPN_LIST, LRGROUPS )
      USE ZMUMPS_LOAD
      USE ZMUMPS_OOC
      USE ZMUMPS_FAC_ASM_MASTER_M
      USE ZMUMPS_FAC_ASM_MASTER_ELT_M
      USE ZMUMPS_FAC1_LDLT_M
      USE ZMUMPS_FAC2_LDLT_M
      USE ZMUMPS_FAC1_LU_M
      USE ZMUMPS_FAC2_LU_M
      USE OMP_LIB
      USE MUMPS_TPS_M
      USE ZMUMPS_TPS_M
      USE ZMUMPS_STRUC_DEF, ONLY : ZMUMPS_ROOT_STRUC
      USE ZMUMPS_FAC_PAR_M, ONLY : ZMUMPS_FAC_PAR
      IMPLICIT NONE
      TYPE (ZMUMPS_ROOT_STRUC) :: root
      INTEGER N, LIW, LPTRAR, NSTEPSDONE, INFO(80)
      DOUBLE PRECISION, INTENT(INOUT) :: OPASS, OPELI
      INTEGER, INTENT(INOUT) :: NELVA, COMP
      INTEGER, INTENT(INOUT) :: MAXFRT, NTOTPV, NMAXNPIV, NOFFNEGPV
      INTEGER, INTENT(INOUT) :: NB22T1, NB22T2, NBTINY
      INTEGER, INTENT(INOUT) :: DET_SIGN, DET_EXP
      COMPLEX(kind=8), INTENT(INOUT) :: DET_MANT
      INTEGER(8) :: LA
      COMPLEX(kind=8) :: A(LA)
      INTEGER SLAVEF, COMM_NODES, MYID, MYID_NODES
      INTEGER, DIMENSION(0: SLAVEF - 1) :: MEM_DISTRIB
      INTEGER KEEP(500), ICNTL(60)
      INTEGER(8) KEEP8(150)
      INTEGER LPOOL
      INTEGER PROCNODE_STEPS(KEEP(28))
      INTEGER ITLOC(N+KEEP(253))
      COMPLEX(kind=8) :: RHS_MUMPS(KEEP(255))
      INTEGER IW(LIW), NSTK_STEPS(KEEP(28))
      INTEGER(8), INTENT(IN) :: PTRARW(LPTRAR), PTRAIW(LPTRAR)
      INTEGER ND(KEEP(28))
      INTEGER FILS(N),PTRIST(KEEP(28))
      INTEGER STEP(N), FRERE(KEEP(28)), DAD(KEEP(28))
      INTEGER PIMASTER(KEEP(28))
      INTEGER PTLUST(KEEP(28)), PERM(N)
      INTEGER CAND(SLAVEF+1,max(1,KEEP(56)))
      INTEGER   ISTEP_TO_INIV2(KEEP(71)),
     &          TAB_POS_IN_PERE(SLAVEF+2,max(1,KEEP(56)))
      INTEGER IPOOL(LPOOL)
      INTEGER NE(KEEP(28))
      DOUBLE PRECISION RINFO(40)
      INTEGER(8) :: PAMASTER(KEEP(28)), PTRAST(KEEP(28))
      INTEGER(8) :: PTRFAC(KEEP(28))
      INTEGER(8) :: POSFAC, LRLU, LRLUS, IPTRLU
      INTEGER IWPOS, LEAF, NBROOT, NBRTOT
      INTEGER, INTENT(in) :: NBROOT_UNDER_L0
      INTEGER COMM_LOAD, ASS_IRECV
      DOUBLE PRECISION UU, SEUIL, SEUIL_LDLT_NIV2
      INTEGER NELT
      INTEGER FRTPTR( N+1 ), FRTELT( NELT )
      INTEGER LBUFR, LBUFR_BYTES
      INTEGER BUFR( LBUFR )
      COMPLEX(kind=8) DBLARR( KEEP8(26) )
      INTEGER INTARR( KEEP8(27) )
      INTEGER LPN_LIST
      INTEGER PIVNUL_LIST(LPN_LIST)
      DOUBLE PRECISION DKEEP(230)
      INTEGER LRGROUPS(N)
      INTEGER, INTENT( IN ) :: LTPS_ARR, LL0_OMP_MAPPING
      TYPE (MUMPS_TPS_T)  ::  MUMPS_TPS_ARR(LTPS_ARR)
      TYPE (ZMUMPS_TPS_T) :: ZMUMPS_TPS_ARR(LTPS_ARR)
      INTEGER, INTENT( IN ) :: L0_OMP_MAPPING( LL0_OMP_MAPPING )
      CALL ZMUMPS_FAC_PAR( N, IW, LIW, A, LA, NSTK_STEPS,
     & ND,FILS,STEP, FRERE, DAD, CAND, ISTEP_TO_INIV2, TAB_POS_IN_PERE,
     & NSTEPSDONE, OPASS, OPELI, NELVA, COMP, MAXFRT, NMAXNPIV, NTOTPV,
     & NOFFNEGPV, NB22T1, NB22T2, NBTINY, DET_EXP, DET_MANT, DET_SIGN,
     & PTRIST, PTRAST, PIMASTER, PAMASTER, PTRARW, PTRAIW,
     & ITLOC, RHS_MUMPS, IPOOL, LPOOL,
     & L0_OMP_MAPPING, LL0_OMP_MAPPING,
     & MUMPS_TPS_ARR, ZMUMPS_TPS_ARR, LTPS_ARR,
     & RINFO, POSFAC ,IWPOS, LRLU, IPTRLU, LRLUS, LEAF, NBROOT, NBRTOT,
     & NBROOT_UNDER_L0, 
     & UU, ICNTL, PTLUST, PTRFAC, INFO, KEEP,KEEP8,
     & PROCNODE_STEPS,SLAVEF,MYID, COMM_NODES, MYID_NODES,
     & BUFR,LBUFR,LBUFR_BYTES,INTARR,DBLARR,root, PERM, NELT,
     & FRTPTR, FRTELT, LPTRAR, COMM_LOAD, ASS_IRECV,
     & SEUIL, SEUIL_LDLT_NIV2, MEM_DISTRIB, NE, DKEEP,
     & PIVNUL_LIST,LPN_LIST, LRGROUPS )
      RETURN
      END SUBROUTINE ZMUMPS_FAC_PAR_I
