C
C   THIS FILE IS PART OF MUMPS VERSION 4.6.3
C   This Version was built on Thu Jun 22 13:22:44 2006
C
C
C  This version of MUMPS is provided to you free of charge. It is public
C  domain, based on public domain software developed during the Esprit IV
C  European project PARASOL (1996-1999) by CERFACS, ENSEEIHT-IRIT and RAL. 
C  Since this first public domain version in 1999, the developments are
C  supported by the following institutions: CERFACS, ENSEEIHT-IRIT, and
C  INRIA.
C
C  Main contributors are Patrick Amestoy, Iain Duff, Abdou Guermouche,
C  Jacko Koster, Jean-Yves L'Excellent, and Stephane Pralet.
C
C  Up-to-date copies of the MUMPS package can be obtained
C  from the Web pages http://www.enseeiht.fr/apo/MUMPS/
C  or http://graal.ens-lyon.fr/MUMPS
C
C
C   THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY
C   EXPRESSED OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
C
C
C  User documentation of any code that uses this software can
C  include this complete notice. You can acknowledge (using
C  references [1], [2], and [3] the contribution of this package
C  in any scientific publication dependent upon the use of the
C  package. You shall use reasonable endeavours to notify
C  the authors of the package of this publication.
C
C   [1] P. R. Amestoy, I. S. Duff and  J.-Y. L'Excellent (1998),
C   Multifrontal parallel distributed symmetric and unsymmetric solvers,
C   in Comput. Methods in Appl. Mech. Eng., 184,  501-520 (2000).
C
C   [2] P. R. Amestoy, I. S. Duff, J. Koster and  J.-Y. L'Excellent,
C   A fully asynchronous multifrontal solver using distributed dynamic
C   scheduling, SIAM Journal of Matrix Analysis and Applications,
C   Vol 23, No 1, pp 15-41 (2001).
C
C   [3] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and
C   S. Pralet, Hybrid scheduling for the parallel solution of linear
C   systems. Parallel Computing Vol 32 (2), pp 136-156 (2006).
C
      MODULE CMUMPS_OOC
      IMPLICIT NONE
      INTEGER FIRST_HBUF,SECOND_HBUF
      PARAMETER (FIRST_HBUF=0, SECOND_HBUF=1)
      INTEGER, DIMENSION(:),POINTER :: POS_IN_FILE,NUM_FILE,
     $     SIZE_OF_BLOCK,OOC_INODE_SEQUENCE
      INTEGER, DIMENSION(:),ALLOCATABLE :: IO_REQ
      COMPLEX, DIMENSION(:),ALLOCATABLE :: BUF_IO
      INTEGER,SAVE :: DIM_BUF_IO
      INTEGER, DIMENSION(:),ALLOCATABLE :: LRLUS_SOLVE,LRLU_SOLVE_T,
     $     LRLU_SOLVE_B,POSFAC_SOLVE,IDEB_SOLVE_Z, SIZE_SOLVE_Z
     $     ,PDEB_SOLVE_Z
      INTEGER,SAVE :: MYID_OOC,STRAT_IO,FACT_AREA_SIZE,
     $     LOW_LEVEL_STRAT_IO,FIRST_ACTIVE_Z,
     $     SIZE_ZONE_SOLVE,SIZE_SOLVE_EMM,TMP_SIZE_FACT,TMP_NB_NODES,
     $     MAX_NB_NODES_FOR_ZONE,MAX_NB_REQ,CURRENT_SOLVE_READ_ZONE,
     $     CUR_POS_SEQUENCE,NB_Z,MIN_SIZE_READ,SOLVE_STEP,
     $     TOTAL_NB_OOC_NODES,NB_ZONE_REQ,MAX_SIZE_FACTOR_OOC
     $     ,NB_CALLED,REQ_ACT,NB_CALL
      INTEGER*8,SAVE :: SIZE_ZONE_REQ
      DOUBLE PRECISION,SAVE :: MAX_OOC_FILE_SIZE
      INTEGER,DIMENSION(:),ALLOCATABLE :: FIRST_POS_IN_READ,
     $     SIZE_OF_READ,READ_DEST,READ_MNG,REQ_TO_ZONE,POS_HOLE_T,
     $     POS_HOLE_B,REQ_ID
      INTEGER,SAVE :: HBUF_SIZE, EARLIEST_WRITE_MIN_SIZE,
     &  I_SHIFT_FIRST_HBUF, I_SHIFT_SECOND_HBUF,
     &  I_SHIFT_CUR_HBUF, I_REL_POS_CUR_HBUF,
     &  LAST_IOREQUEST,
     &  CUR_HBUF
      INTEGER,SAVE :: I_CUR_HBUF_NEXTPOS,
     &  I_CUR_HBUF_FSTPOS,
     &  I_SUB_HBUF_FSTPOS
      INTEGER CMUMPS_ELEMENTARY_DATA_SIZE,N_OOC
      INTEGER,DIMENSION(:),POINTER:: KEEP_OOC
      LOGICAL,SAVE :: STRAT_IO_ASYNC,WITH_BUF,SOLVE,IS_INIT_CALLED
      INTEGER, DIMENSION(:), ALLOCATABLE :: POS_IN_MEM, INODE_TO_POS
      INTEGER, DIMENSION(:), ALLOCATABLE :: CURRENT_POS_T,CURRENT_POS_B
      INTEGER, DIMENSION(:),POINTER :: STEP_OOC
      CHARACTER*1 ERR_STR_OOC(200)
      INTEGER DIM_ERR_STR_OOC
      PUBLIC :: CMUMPS_575,CMUMPS_576,
     $     CMUMPS_577,
     $     CMUMPS_578,
     $     CMUMPS_579,CMUMPS_580,
     $     CMUMPS_581,CMUMPS_582,
     $     CMUMPS_583,CMUMPS_584,
     $     CMUMPS_585,CMUMPS_586
      CONTAINS
      FUNCTION CMUMPS_579(INODE,ZONE)
      IMPLICIT NONE
      INTEGER INODE,ZONE
      LOGICAL CMUMPS_579
      CMUMPS_579=(LRLUS_SOLVE(ZONE).GE.
     $     SIZE_OF_BLOCK(STEP_OOC(INODE)))
      RETURN
      END FUNCTION CMUMPS_579
      SUBROUTINE CMUMPS_590(LA)
      IMPLICIT NONE
      INTEGER LA
      FACT_AREA_SIZE=LA
      END SUBROUTINE CMUMPS_590
      SUBROUTINE CMUMPS_575(id)
      USE CMUMPS_STRUC_DEF
      IMPLICIT NONE
      TYPE(CMUMPS_STRUC), TARGET :: id
      INTEGER IERR
      INTEGER allocok
      INTEGER ASYNC,BUF
      CHARACTER*1 TMP_DIR(150),TMP_FILE(150)
      INTEGER DIM_DIR,DIM_FILE
      MAX_SIZE_FACTOR_OOC=0
      N_OOC=id%N
      IS_INIT_CALLED=.TRUE.
      ASYNC=0
      BUF=0
      SOLVE=.FALSE.
      IERR=0
      IF(ALLOCATED(IO_REQ))THEN
         DEALLOCATE(IO_REQ)
      ENDIF
      IF(ASSOCIATED(KEEP_OOC))THEN
         NULLIFY(KEEP_OOC)
      ENDIF
      IF(ASSOCIATED(STEP_OOC))THEN
         NULLIFY(STEP_OOC)
      ENDIF
      IF(ASSOCIATED(POS_IN_FILE))THEN
         NULLIFY(POS_IN_FILE)
      ENDIF
      IF(ASSOCIATED(NUM_FILE))THEN
         NULLIFY(NUM_FILE)
      ENDIF
      IF(ASSOCIATED(OOC_INODE_SEQUENCE))THEN
         NULLIFY(OOC_INODE_SEQUENCE)
      ENDIF
      IF(ASSOCIATED(SIZE_OF_BLOCK))THEN
         NULLIFY(SIZE_OF_BLOCK)
      ENDIF
      CALL CMUMPS_588(id,IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         id%INFO(1) = IERR
         id%INFO(2) = 0
         RETURN
      ENDIF
      STEP_OOC=>id%STEP
      MYID_OOC=id%MYID
      KEEP_OOC => id%KEEP
      POS_IN_FILE=>id%OOC_POS_IN_FILE
      NUM_FILE=>id%OOC_NUM_FILE
      SIZE_OF_BLOCK=>id%OOC_SIZE_OF_BLOCK
      IF(id%KEEP(107).GT.0)THEN
         SIZE_SOLVE_EMM=MAX(id%KEEP(202),INT(REAL(id%MAXS*
     $        0.9)*0.2))
         SIZE_ZONE_SOLVE=MAX(SIZE_SOLVE_EMM,
     $        INT((REAL(id%MAXS*0.9)-
     $        REAL(SIZE_SOLVE_EMM))/REAL(id%KEEP(107))))
         IF(SIZE_ZONE_SOLVE.EQ.SIZE_SOLVE_EMM)THEN
            SIZE_SOLVE_EMM=id%KEEP(202)
            SIZE_ZONE_SOLVE=INT((REAL(id%MAXS*0.9)-
     $           REAL(SIZE_SOLVE_EMM))/REAL(id%KEEP(107)))
         ENDIF
      ELSE
         SIZE_ZONE_SOLVE=INT(REAL(id%MAXS*0.9))
         SIZE_SOLVE_EMM=SIZE_ZONE_SOLVE
      ENDIF
      CMUMPS_ELEMENTARY_DATA_SIZE = id%KEEP(35)
      SIZE_OF_BLOCK=0
      STRAT_IO=id%KEEP(99)
      STRAT_IO_ASYNC=.FALSE.
      WITH_BUF=.FALSE.
      IF((STRAT_IO.EQ.1).OR.(STRAT_IO.EQ.2))THEN
         STRAT_IO_ASYNC=.TRUE.
         WITH_BUF=.FALSE.
      ELSEIF((STRAT_IO.EQ.4).OR.(STRAT_IO.EQ.5))THEN
         STRAT_IO_ASYNC=.TRUE.
         WITH_BUF=.TRUE.
      ELSEIF(STRAT_IO.EQ.3)THEN
         STRAT_IO_ASYNC=.FALSE.
         WITH_BUF=.TRUE.
      ENDIF
      LOW_LEVEL_STRAT_IO=MOD(STRAT_IO,3)
# if defined(perfanal)
      WRITE(*,*) 'LOW_LEVEL_STRAT_IO= ',LOW_LEVEL_STRAT_IO
#endif
      TMP_SIZE_FACT=0
      TMP_NB_NODES=0
      MAX_NB_NODES_FOR_ZONE=0
      OOC_INODE_SEQUENCE=>id%OOC_INODE_SEQUENCE
      I_CUR_HBUF_NEXTPOS = 1
      IF(WITH_BUF)THEN
        BUF=1
        DIM_BUF_IO = id%KEEP(100)
        WRITE(*,*)'DIM_BUF_IO =',DIM_BUF_IO 
        ALLOCATE(BUF_IO(DIM_BUF_IO), stat=allocok)
        IF (allocok > 0) THEN
          WRITE(*,*) 'PB allocation in CMUMPS_INIT_OOC'
          id%INFO(1) = -13
          id%INFO(2) = DIM_BUF_IO
          RETURN
        ENDIF
        CALL DB_INIT_DOUBLE_BUFFER()
      ENDIF
      ALLOCATE(IO_REQ(id%KEEP(28)),
     $     stat=allocok)
      IF (allocok > 0) THEN
         WRITE(*,*) 'PB allocation in CMUMPS_INIT_OOC'
         id%INFO(1) = -13
         id%INFO(2) = id%KEEP(28)
         RETURN
      ENDIF
      IF(STRAT_IO_ASYNC)THEN
         ASYNC=1
      ENDIF
      CALL CMUMPS_LOW_LEVEL_INIT_ERR_STR(DIM_ERR_STR_OOC,ERR_STR_OOC)
      DIM_DIR=LEN(TRIM(id%OOC_TMPDIR))
      DIM_FILE=LEN(TRIM(id%OOC_PREFIX))
      CALL CMUMPS_589(TMP_DIR(1),
     $     id%OOC_TMPDIR)
      CALL CMUMPS_589(TMP_FILE(1),
     $     id%OOC_PREFIX)
      CALL CMUMPS_LOW_LEVEL_INIT_PREFIX(DIM_FILE, TMP_FILE)
      CALL CMUMPS_LOW_LEVEL_INIT_TMPDIR(DIM_DIR, TMP_DIR)
      IERR=0
      CALL CMUMPS_LOW_LEVEL_INIT_OOC_C(MYID_OOC,id%MAXS,
     $     id%KEEP(35),LOW_LEVEL_STRAT_IO,id%KEEP(211),
     $     IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': PB in CMUMPS_LOW_LEVEL_INIT_OOC_C'
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         id%INFO(1) = IERR
         id%INFO(2) = 0
         RETURN
      ENDIF
      CALL CMUMPS_GET_MAX_FILE_SIZE(MAX_OOC_FILE_SIZE,IERR)
      END SUBROUTINE CMUMPS_575
      SUBROUTINE DB_INIT_DOUBLE_BUFFER()
      IMPLICIT NONE
      HBUF_SIZE = DIM_BUF_IO / 2
      EARLIEST_WRITE_MIN_SIZE = 0
      I_SHIFT_FIRST_HBUF = 0
      I_SHIFT_SECOND_HBUF = HBUF_SIZE
      LAST_IOREQUEST = -1
      I_CUR_HBUF_NEXTPOS = 1
      I_CUR_HBUF_FSTPOS = 1
      I_SUB_HBUF_FSTPOS = 1
      CUR_HBUF = SECOND_HBUF
      CALL DB_NEXT_HBUF()      
      END SUBROUTINE DB_INIT_DOUBLE_BUFFER
      SUBROUTINE DB_NEXT_HBUF()
      IMPLICIT NONE
      SELECT CASE(CUR_HBUF)
         CASE (FIRST_HBUF)
            CUR_HBUF = SECOND_HBUF
            I_SHIFT_CUR_HBUF = I_SHIFT_SECOND_HBUF
         CASE (SECOND_HBUF)
            CUR_HBUF = FIRST_HBUF
            I_SHIFT_CUR_HBUF = I_SHIFT_FIRST_HBUF
      END SELECT
      I_SUB_HBUF_FSTPOS =
     &  I_CUR_HBUF_FSTPOS
      I_CUR_HBUF_FSTPOS =
     &  I_CUR_HBUF_NEXTPOS
      I_REL_POS_CUR_HBUF = 1
      END SUBROUTINE DB_NEXT_HBUF
      SUBROUTINE DB_DO_IO_AND_CHANGE_HBUF(IERR)
      IMPLICIT NONE
      INTEGER NEW_IOREQUEST
      INTEGER IERR
      IERR=0
      CALL DB_WRITE_CUR_HBUF_TO_DISK(NEW_IOREQUEST,IERR)
      IF(IERR.LT.0)THEN
         RETURN
      ENDIF
      IERR=0
      CALL CMUMPS_WAIT_REQUEST(LAST_IOREQUEST,IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         RETURN
      ENDIF
      CALL UPDATE_POS_IN_FILE(I_SUB_HBUF_FSTPOS,
     &  I_CUR_HBUF_FSTPOS - 1)
      LAST_IOREQUEST = NEW_IOREQUEST
      CALL DB_NEXT_HBUF()      
      END SUBROUTINE DB_DO_IO_AND_CHANGE_HBUF
      SUBROUTINE DB_COPY_FACTOR_TO_BUFFER(INODE,PTRFAC,KEEP,KEEP8,
     &  A,LA,SIZE,IERR)
      IMPLICIT NONE
      INTEGER INODE
      INTEGER NEW_IOREQUEST
      INTEGER KEEP(500),LA
      INTEGER*8 KEEP8(150)
      INTEGER PTRFAC(KEEP(28))
      COMPLEX A(LA)
      INTEGER IERR,SIZE
      INTEGER I
      IERR=0
      IF (SIZE_OF_BLOCK(STEP_OOC(INODE)) > HBUF_SIZE ) THEN
        WRITE(*,*)'CMUMPS I/O ERROR : INODE ',
     &    INODE,'IS TOO BIG TO MATCH ONE HALF-BUFFER :',
     &    ' Size of block=',SIZE_OF_BLOCK(STEP_OOC(INODE)),
     &    ' Size half-buffer=',HBUF_SIZE
        CALL CMUMPS_ABORT()
        RETURN
      END IF
      IF (I_REL_POS_CUR_HBUF +
     &    SIZE_OF_BLOCK(STEP_OOC(INODE)) <= HBUF_SIZE + 1) THEN
      ELSE
        CALL DB_DO_IO_AND_CHANGE_HBUF(IERR)
        IF(IERR.LT.0)THEN
           RETURN
        ENDIF
      END IF
      DO I = 0, SIZE_OF_BLOCK(STEP_OOC(INODE)) - 1
        BUF_IO(I_SHIFT_CUR_HBUF + I_REL_POS_CUR_HBUF + I) =
     &    A(PTRFAC(STEP_OOC(INODE)) + I)
      END DO
      I_REL_POS_CUR_HBUF = I_REL_POS_CUR_HBUF +
     &  SIZE_OF_BLOCK(STEP_OOC(INODE))
      OOC_INODE_SEQUENCE(I_CUR_HBUF_NEXTPOS) =
     &  INODE
      I_CUR_HBUF_NEXTPOS =
     &  I_CUR_HBUF_NEXTPOS + 1
      END SUBROUTINE DB_COPY_FACTOR_TO_BUFFER
      SUBROUTINE DB_WRITE_CUR_HBUF_TO_DISK(IOREQUEST,IERR)
      IMPLICIT NONE
      INTEGER IOREQUEST,IERR
      INTEGER TOTAL_SIZE,FIRST_INODE,
     &  SIZE,FROM_BUFIO_POS
      IERR=0
      IF (I_REL_POS_CUR_HBUF == 1) THEN
        IOREQUEST=-1
        RETURN
      END IF      
      FIRST_INODE =
     &  OOC_INODE_SEQUENCE(I_CUR_HBUF_FSTPOS)
      FROM_BUFIO_POS=I_SHIFT_CUR_HBUF+1
      SIZE = I_REL_POS_CUR_HBUF-1
      CALL CMUMPS_LOW_LEVEL_WRITE_OOC_C(LOW_LEVEL_STRAT_IO,
     &     BUF_IO(FROM_BUFIO_POS),SIZE,
     &     POS_IN_FILE(STEP_OOC(FIRST_INODE)),
     $     NUM_FILE(STEP_OOC(FIRST_INODE)),
     $     FIRST_INODE,IOREQUEST,IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         RETURN
      ENDIF
      END SUBROUTINE DB_WRITE_CUR_HBUF_TO_DISK
      SUBROUTINE UPDATE_POS_IN_FILE(I_FIRSTPOS_INODE_SEQUENCE,
     &  I_LASTPOS_INODE_SEQUENCE)
      IMPLICIT NONE
      INTEGER I_FIRSTPOS_INODE_SEQUENCE, I_LASTPOS_INODE_SEQUENCE
      INTEGER I,TMP_NUM_FILE,NB_FILE_LOC
      DOUBLE PRECISION POS
      IF(I_FIRSTPOS_INODE_SEQUENCE.GT.I_LASTPOS_INODE_SEQUENCE)THEN
         RETURN
      ENDIF
      TMP_NUM_FILE=NUM_FILE(STEP_OOC(OOC_INODE_SEQUENCE
     $     (I_FIRSTPOS_INODE_SEQUENCE)))
      IF(TMP_NUM_FILE.GE.0)THEN
         DO I = I_FIRSTPOS_INODE_SEQUENCE + 1, I_LASTPOS_INODE_SEQUENCE
            POS_IN_FILE(STEP_OOC(OOC_INODE_SEQUENCE(I))) =
     &           POS_IN_FILE(STEP_OOC(OOC_INODE_SEQUENCE(I-1))) +
     &           (SIZE_OF_BLOCK(STEP_OOC(OOC_INODE_SEQUENCE(I-1))) *
     &           CMUMPS_ELEMENTARY_DATA_SIZE)
            NUM_FILE(STEP_OOC(OOC_INODE_SEQUENCE(I))) =
     $           TMP_NUM_FILE
         END DO
      ELSE
         POS=POS_IN_FILE(STEP_OOC(OOC_INODE_SEQUENCE
     $        (I_FIRSTPOS_INODE_SEQUENCE)))         
         TMP_NUM_FILE=ABS(TMP_NUM_FILE)
         DO I = I_FIRSTPOS_INODE_SEQUENCE, I_LASTPOS_INODE_SEQUENCE
            IF((POS+SIZE_OF_BLOCK(STEP_OOC(OOC_INODE_SEQUENCE(I)))*
     $           CMUMPS_ELEMENTARY_DATA_SIZE)
     $           .GT.MAX_OOC_FILE_SIZE)THEN
               POS_IN_FILE(STEP_OOC(OOC_INODE_SEQUENCE(I)))=POS
               NB_FILE_LOC=INT(CMPLX(POS+
     $              SIZE_OF_BLOCK(STEP_OOC(OOC_INODE_SEQUENCE(I)))*
     $              CMUMPS_ELEMENTARY_DATA_SIZE)/
     $              MAX_OOC_FILE_SIZE)
               NUM_FILE(STEP_OOC(OOC_INODE_SEQUENCE(I))) =
     $              -TMP_NUM_FILE
               POS=CMPLX(MOD(INT(POS)+
     $              SIZE_OF_BLOCK(STEP_OOC(OOC_INODE_SEQUENCE(I)))*
     $              CMUMPS_ELEMENTARY_DATA_SIZE,
     $              INT(MAX_OOC_FILE_SIZE)))
               TMP_NUM_FILE=TMP_NUM_FILE+NB_FILE_LOC
            ELSE
               POS_IN_FILE(STEP_OOC(OOC_INODE_SEQUENCE(I))) = POS
               NUM_FILE(STEP_OOC(OOC_INODE_SEQUENCE(I))) = 
     $              TMP_NUM_FILE
               POS=POS+
     $              SIZE_OF_BLOCK(STEP_OOC(OOC_INODE_SEQUENCE(I)))*
     $              CMUMPS_ELEMENTARY_DATA_SIZE
            ENDIF
         END DO
      ENDIF
      END SUBROUTINE UPDATE_POS_IN_FILE
      SUBROUTINE DB_END_DOUBLE_BUFFER(IERR)
      IMPLICIT NONE
      INTEGER IERR
      WRITE(*,*)'ENDING'
      IERR=0
      CALL DB_DO_IO_AND_CHANGE_HBUF(IERR)
      IF(IERR.LT.0)THEN
         RETURN
      ENDIF
      IERR=0
      CALL DB_DO_IO_AND_CHANGE_HBUF(IERR)
      IF(IERR.LT.0)THEN
         RETURN
      ENDIF
      WRITE(*,*)'ENDED'
      END SUBROUTINE DB_END_DOUBLE_BUFFER
      SUBROUTINE CMUMPS_576(INODE,PTRFAC,KEEP,KEEP8,
     *           A,LA,SIZE,IERR)
      IMPLICIT NONE
      INTEGER INODE,KEEP(500),LA
      INTEGER*8 KEEP8(150)
      INTEGER PTRFAC(KEEP(28))
      COMPLEX A(LA)
      INTEGER SIZE,IERR,I,FLAG,NODE,ASYNC,REQUEST
      LOGICAL IO_C
      IF(STRAT_IO_ASYNC)THEN
         ASYNC=1
      ELSE
         ASYNC=0
      ENDIF
      IERR=0
      IO_C=.TRUE.
      SIZE_OF_BLOCK(STEP_OOC(INODE))=SIZE
      MAX_SIZE_FACTOR_OOC=MAX(MAX_SIZE_FACTOR_OOC,SIZE)
      TMP_SIZE_FACT=TMP_SIZE_FACT+SIZE
      TMP_NB_NODES=TMP_NB_NODES+1
      IF(TMP_SIZE_FACT.GT.SIZE_ZONE_SOLVE)THEN
         MAX_NB_NODES_FOR_ZONE=MAX(MAX_NB_NODES_FOR_ZONE,TMP_NB_NODES)
         TMP_SIZE_FACT=0
         TMP_NB_NODES=0
      ENDIF
      IF (.NOT. WITH_BUF) THEN
        CALL CMUMPS_LOW_LEVEL_WRITE_OOC_C(LOW_LEVEL_STRAT_IO,
     &       A(PTRFAC(STEP_OOC(INODE))),SIZE,
     &       POS_IN_FILE(STEP_OOC(INODE)),NUM_FILE(STEP_OOC(INODE)),
     $       INODE,REQUEST,IERR)
        IF(IERR.LT.0)THEN
           WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
           RETURN
        ENDIF
        IF(I_CUR_HBUF_NEXTPOS.GT.KEEP_OOC(28))THEN
             WRITE(*,*)MYID_OOC,': Internal error (37) in OOC '
           CALL CMUMPS_ABORT()
        ENDIF
        OOC_INODE_SEQUENCE(I_CUR_HBUF_NEXTPOS)=INODE
        I_CUR_HBUF_NEXTPOS=
     $       I_CUR_HBUF_NEXTPOS+1
      ELSE
         IF(SIZE.LE.HBUF_SIZE)THEN
            CALL DB_COPY_FACTOR_TO_BUFFER(INODE,PTRFAC,KEEP,KEEP8,
     $           A,LA,SIZE,IERR)
#if ! defined (OOC_DEBUG)
            PTRFAC(STEP_OOC(INODE))=-777777
#endif
            RETURN
         ELSE
            CALL DB_DO_IO_AND_CHANGE_HBUF(IERR)
            IF(IERR.LT.0)THEN
               RETURN
            ENDIF
            CALL DB_DO_IO_AND_CHANGE_HBUF(IERR)
            IF(IERR.LT.0)THEN
               RETURN
            ENDIF
            CALL CMUMPS_LOW_LEVEL_WRITE_OOC_C(LOW_LEVEL_STRAT_IO,
     &           A(PTRFAC(STEP_OOC(INODE))),SIZE,
     &           POS_IN_FILE(STEP_OOC(INODE)),NUM_FILE(STEP_OOC(INODE)),
     $           INODE,REQUEST,IERR)
            IF(IERR.LT.0)THEN
               WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
               RETURN
            ENDIF
            IF(I_CUR_HBUF_NEXTPOS.GT.KEEP_OOC(28))THEN
             WRITE(*,*)MYID_OOC,': Internal error (38) in OOC '
               CALL CMUMPS_ABORT()
            ENDIF
            OOC_INODE_SEQUENCE(I_CUR_HBUF_NEXTPOS)=INODE
            I_CUR_HBUF_NEXTPOS=
     $           I_CUR_HBUF_NEXTPOS+1
            CALL DB_NEXT_HBUF()
         ENDIF
      END IF
      NODE=-9999
#if ! defined (OOC_DEBUG)
      PTRFAC(STEP_OOC(INODE))=-777777
#endif
      IF(STRAT_IO_ASYNC)THEN
         IERR=0
         CALL CMUMPS_WAIT_REQUEST(REQUEST,IERR)
         IF(IERR.LT.0)THEN
            WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
            RETURN
         ENDIF
      ENDIF
      RETURN
      END SUBROUTINE CMUMPS_576
      SUBROUTINE CMUMPS_577(DEST,INODE,IERR)
      IMPLICIT NONE
      INCLUDE 'mpif.h'
      INTEGER IERR,INODE,STATUS
      COMPLEX DEST
      INTEGER FLAG,NODE,ASYNC,REQUEST
      LOGICAL IO_C
      IF(STRAT_IO_ASYNC)THEN
        ASYNC=1
      ELSE
        ASYNC=0
      ENDIF
      IERR=0
      IO_C=.TRUE.
#if ! defined(OLD_READ)
      CALL CMUMPS_LOW_LEVEL_DIRECT_READ(DEST,
     $     SIZE_OF_BLOCK(STEP_OOC(INODE)),
     $     POS_IN_FILE(STEP_OOC(INODE)),NUM_FILE(STEP_OOC(INODE)),
     $     IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         WRITE(*,*)MYID_OOC,': Problem in CMUMPS_LOW_LEVEL_READ_OCC'
         RETURN
      ENDIF
#else
      CALL CMUMPS_LOW_LEVEL_READ_OOC_C(LOW_LEVEL_STRAT_IO,
     $     DEST,SIZE_OF_BLOCK(STEP_OOC(INODE)),
     $     POS_IN_FILE(STEP_OOC(INODE)),NUM_FILE(STEP_OOC(INODE)),
     $     INODE,REQUEST,IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         WRITE(*,*)MYID_OOC,': Problem in CMUMPS_LOW_LEVEL_READ_OCC'
         RETURN
      ENDIF
      IF(STRAT_IO_ASYNC)THEN
         IERR=0
         CALL CMUMPS_WAIT_REQUEST(REQUEST,IERR)
         IF(IERR.LT.0)THEN
            WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
            RETURN
         ENDIF
      ENDIF
#endif
      IF(.NOT.CMUMPS_SOLVE_IS_END_REACHED())THEN
         IF(OOC_INODE_SEQUENCE(CUR_POS_SEQUENCE).EQ.INODE)THEN
            IF(SOLVE_STEP.EQ.0)THEN
               CUR_POS_SEQUENCE=CUR_POS_SEQUENCE+1
            ELSEIF(SOLVE_STEP.EQ.1)THEN
               CUR_POS_SEQUENCE=CUR_POS_SEQUENCE-1
            ENDIF
         ENDIF
      ENDIF
      RETURN
      END SUBROUTINE CMUMPS_577
      SUBROUTINE CMUMPS_591(id,IERR)
      USE CMUMPS_STRUC_DEF
      IMPLICIT NONE
      TYPE(CMUMPS_STRUC), TARGET :: id
      INTEGER IERR
      IERR=0
      IF (WITH_BUF) THEN
        CALL DB_END_DOUBLE_BUFFER(IERR)
        IF(IERR.LT.0)THEN
           RETURN
        ENDIF
      END IF
      END SUBROUTINE CMUMPS_591
      SUBROUTINE CMUMPS_592(id,IERR)
      USE CMUMPS_STRUC_DEF
      IMPLICIT NONE
      TYPE(CMUMPS_STRUC), TARGET :: id
      INTEGER IERR,I,SOLVE_OR_FACTO
      IERR=0
      IF(WITH_BUF)THEN
         IF(ALLOCATED(BUF_IO))THEN
            DEALLOCATE(BUF_IO)
         ENDIF
      ENDIF
      IF(ALLOCATED(IO_REQ))THEN
         DEALLOCATE(IO_REQ)
      ENDIF
      IF(ASSOCIATED(KEEP_OOC))THEN
         NULLIFY(KEEP_OOC)
      ENDIF
      IF(ASSOCIATED(STEP_OOC))THEN
         NULLIFY(STEP_OOC)
      ENDIF
      IF(ASSOCIATED(POS_IN_FILE))THEN
         NULLIFY(POS_IN_FILE)
      ENDIF
      IF(ASSOCIATED(NUM_FILE))THEN
         NULLIFY(NUM_FILE)
      ENDIF
      IF(ASSOCIATED(OOC_INODE_SEQUENCE))THEN
         NULLIFY(OOC_INODE_SEQUENCE)
      ENDIF
      IF(ASSOCIATED(SIZE_OF_BLOCK))THEN
         NULLIFY(SIZE_OF_BLOCK)
      ENDIF
      CALL CMUMPS_OOC_END_WRITE(IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         RETURN
      ENDIF
      id%OOC_MAX_NB_NODES_FOR_ZONE=MAX(MAX_NB_NODES_FOR_ZONE,
     $     TMP_NB_NODES)
      id%OOC_TOTAL_NB_NODES=I_CUR_HBUF_NEXTPOS-1
      id%KEEP(203)=MAX_SIZE_FACTOR_OOC
      CALL CMUMPS_613(id)
      IF(id%INFO(1).LT.0)THEN
         RETURN
      ENDIF
      IERR=0
      SOLVE_OR_FACTO=0
      CALL CMUMPS_CLEAN_IO_DATA_C(MYID_OOC,SOLVE_OR_FACTO,IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         RETURN
      ENDIF
      RETURN
      END SUBROUTINE CMUMPS_592
      SUBROUTINE CMUMPS_588(id,IERR)
      USE CMUMPS_STRUC_DEF
      IMPLICIT NONE
      EXTERNAL CMUMPS_OOC_REMOVE_FILE
      TYPE(CMUMPS_STRUC), TARGET :: id
      INTEGER IERR
      INTEGER I,J
      CHARACTER*1 TMP_NAME(150)
      IERR=0
      IF(ASSOCIATED(id%OOC_FILE_NAMES).AND.
     $     ASSOCIATED(id%OOC_FILE_NAME_LENGTH))THEN
         DO I=1,id%OOC_NB_FILES
            DO J=1,id%OOC_FILE_NAME_LENGTH(I)
               TMP_NAME(J)=id%OOC_FILE_NAMES(I,J)
            ENDDO
            CALL CMUMPS_OOC_REMOVE_FILE(IERR, TMP_NAME(1))
            IF(IERR.LT.0)THEN
               WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
               RETURN
            ENDIF
         ENDDO
      ENDIF
      IF(ASSOCIATED(id%OOC_FILE_NAMES))THEN
         DEALLOCATE(id%OOC_FILE_NAMES)
         NULLIFY(id%OOC_FILE_NAMES)
      ENDIF
      IF(ASSOCIATED(id%OOC_FILE_NAME_LENGTH))THEN
         DEALLOCATE(id%OOC_FILE_NAME_LENGTH)
         NULLIFY(id%OOC_FILE_NAME_LENGTH)
      ENDIF      
      END SUBROUTINE CMUMPS_588
      SUBROUTINE CMUMPS_587(id,IERR)
      USE CMUMPS_STRUC_DEF
      IMPLICIT NONE
      TYPE(CMUMPS_STRUC), TARGET :: id
      INTEGER IERR
      IERR=0
      CALL CMUMPS_588(id,IERR)
      IF(ASSOCIATED(id%OOC_INODE_SEQUENCE))THEN
         DEALLOCATE(id%OOC_INODE_SEQUENCE)
         NULLIFY(id%OOC_INODE_SEQUENCE)
      ENDIF
      IF(ASSOCIATED(id%OOC_NUM_FILE))THEN
         DEALLOCATE(id%OOC_NUM_FILE)
         NULLIFY(id%OOC_NUM_FILE)
      ENDIF
      IF(ASSOCIATED(id%OOC_POS_IN_FILE))THEN
         DEALLOCATE(id%OOC_POS_IN_FILE)
         NULLIFY(id%OOC_POS_IN_FILE)
      ENDIF
      IF(ASSOCIATED(id%OOC_SIZE_OF_BLOCK))THEN
         DEALLOCATE(id%OOC_SIZE_OF_BLOCK)
         NULLIFY(id%OOC_SIZE_OF_BLOCK)
      ENDIF
      END SUBROUTINE CMUMPS_587
      SUBROUTINE CMUMPS_586(id)
      USE CMUMPS_STRUC_DEF
      IMPLICIT NONE
      INCLUDE 'mpif.h'
      TYPE(CMUMPS_STRUC), TARGET :: id
      INTEGER TMP,TMP_SIZE,I,J
      INTEGER ZONE,INODE,SIZE,allocok,IERR,ASYNC
      IERR=0
      SOLVE=.TRUE.
      N_OOC=id%N
      IF(ALLOCATED(LRLUS_SOLVE))THEN
         DEALLOCATE(LRLUS_SOLVE)
      ENDIF
      IF(ALLOCATED(LRLU_SOLVE_T))THEN
         DEALLOCATE(LRLU_SOLVE_T)
      ENDIF
      IF(ALLOCATED(LRLU_SOLVE_B))THEN
         DEALLOCATE(LRLU_SOLVE_B)
      ENDIF
      IF(ALLOCATED(POSFAC_SOLVE))THEN
         DEALLOCATE(POSFAC_SOLVE)
      ENDIF
      IF(ALLOCATED(IDEB_SOLVE_Z))THEN
         DEALLOCATE(IDEB_SOLVE_Z)
      ENDIF
      IF(ALLOCATED(PDEB_SOLVE_Z))THEN
         DEALLOCATE(PDEB_SOLVE_Z)
      ENDIF
      IF(ALLOCATED(SIZE_SOLVE_Z))THEN
         DEALLOCATE(SIZE_SOLVE_Z)
      ENDIF
      IF(ALLOCATED(CURRENT_POS_T))THEN
         DEALLOCATE(CURRENT_POS_T)
      ENDIF
      IF(ALLOCATED(CURRENT_POS_B))THEN
         DEALLOCATE(CURRENT_POS_B)
      ENDIF
      IF(ALLOCATED(POS_HOLE_T))THEN
         DEALLOCATE(POS_HOLE_T)
      ENDIF
      IF(ALLOCATED(POS_HOLE_B))THEN
         DEALLOCATE(POS_HOLE_B)
      ENDIF
      IF(ALLOCATED(POS_IN_MEM))THEN
         DEALLOCATE(POS_IN_MEM)
      ENDIF
      IF(ALLOCATED(INODE_TO_POS))THEN
         DEALLOCATE(INODE_TO_POS)
      ENDIF
      IF(ALLOCATED(SIZE_OF_READ))THEN
         DEALLOCATE(SIZE_OF_READ)
      ENDIF
      IF(ALLOCATED(FIRST_POS_IN_READ))THEN
         DEALLOCATE(FIRST_POS_IN_READ)
      ENDIF
      IF(ALLOCATED(READ_DEST))THEN
         DEALLOCATE(READ_DEST)
      ENDIF
      IF(ALLOCATED(READ_MNG))THEN
         DEALLOCATE(READ_MNG)
      ENDIF
      IF(ALLOCATED(REQ_TO_ZONE))THEN
         DEALLOCATE(REQ_TO_ZONE)
      ENDIF
      IF(ALLOCATED(REQ_ID))THEN
         DEALLOCATE(REQ_ID)
      ENDIF
      IF(ALLOCATED(IO_REQ))THEN
         DEALLOCATE(IO_REQ)
      ENDIF
      IF(ASSOCIATED(KEEP_OOC))THEN
         NULLIFY(KEEP_OOC)
      ENDIF
      IF(ASSOCIATED(STEP_OOC))THEN
         NULLIFY(STEP_OOC)
      ENDIF
      IF(ASSOCIATED(POS_IN_FILE))THEN
         NULLIFY(POS_IN_FILE)
      ENDIF
      IF(ASSOCIATED(NUM_FILE))THEN
         NULLIFY(NUM_FILE)
      ENDIF
      IF(ASSOCIATED(OOC_INODE_SEQUENCE))THEN
         NULLIFY(OOC_INODE_SEQUENCE)
      ENDIF
      IF(ASSOCIATED(SIZE_OF_BLOCK))THEN
         NULLIFY(SIZE_OF_BLOCK)
      ENDIF
      CALL CMUMPS_LOW_LEVEL_INIT_ERR_STR(DIM_ERR_STR_OOC,ERR_STR_OOC)
      CALL CMUMPS_614(id)
      IF(id%INFO(1).LT.0)THEN
         RETURN
      ENDIF
      STEP_OOC=>id%STEP
      MYID_OOC=id%MYID
      KEEP_OOC => id%KEEP
      POS_IN_FILE=>id%OOC_POS_IN_FILE
      NUM_FILE=>id%OOC_NUM_FILE
      SIZE_OF_BLOCK=>id%OOC_SIZE_OF_BLOCK
      OOC_INODE_SEQUENCE=>id%OOC_INODE_SEQUENCE
      ALLOCATE(IO_REQ(id%KEEP(28)),
     $     stat=allocok)
      IF (allocok > 0) THEN
         WRITE(*,*) 'PB allocation in CMUMPS_INIT_OOC'
         id%INFO(1) = -13
         id%INFO(2) = id%KEEP(28)
         RETURN
      ENDIF
      CMUMPS_ELEMENTARY_DATA_SIZE = id%KEEP(35)
      STRAT_IO=id%KEEP(204)
      MAX_NB_NODES_FOR_ZONE=id%OOC_MAX_NB_NODES_FOR_ZONE
      TOTAL_NB_OOC_NODES=id%OOC_TOTAL_NB_NODES
      STRAT_IO_ASYNC=.FALSE.
      WITH_BUF=.FALSE.
      IF((STRAT_IO.EQ.1).OR.(STRAT_IO.EQ.2))THEN
         STRAT_IO_ASYNC=.TRUE.
         WITH_BUF=.FALSE.
      ELSEIF((STRAT_IO.EQ.4).OR.(STRAT_IO.EQ.5))THEN
         STRAT_IO_ASYNC=.TRUE.
         WITH_BUF=.TRUE.
      ELSEIF(STRAT_IO.EQ.3)THEN
         STRAT_IO_ASYNC=.FALSE.
         WITH_BUF=.TRUE.
      ENDIF
      LOW_LEVEL_STRAT_IO=MOD(STRAT_IO,3)
      IF(id%KEEP(107).GT.0)THEN
         SIZE_SOLVE_EMM=MAX(id%KEEP(203),
     $        INT(REAL(FACT_AREA_SIZE)*0.2))
         SIZE_ZONE_SOLVE=MAX(SIZE_SOLVE_EMM,
     $        INT((REAL(FACT_AREA_SIZE)-
     $        REAL(SIZE_SOLVE_EMM))/REAL(id%KEEP(107))))
         SIZE_ZONE_SOLVE=MAX(SIZE_ZONE_SOLVE,0)
         IF(SIZE_ZONE_SOLVE.EQ.SIZE_SOLVE_EMM)THEN
            SIZE_SOLVE_EMM=id%KEEP(203)
            SIZE_ZONE_SOLVE=INT((REAL(FACT_AREA_SIZE)-
     $           REAL(SIZE_SOLVE_EMM))/REAL(id%KEEP(107)))
            SIZE_ZONE_SOLVE=MAX(SIZE_ZONE_SOLVE,0)
         ENDIF
      ELSE
         SIZE_ZONE_SOLVE=INT(REAL(FACT_AREA_SIZE))
         SIZE_SOLVE_EMM=SIZE_ZONE_SOLVE
      ENDIF
      IF(SIZE_SOLVE_EMM.LT.id%KEEP(203))THEN
         WRITE(*,*)MYID_OOC,': More space needed for
     $        solution step in CMUMPS_586'
         id%INFO(1) = -11
         id%INFO(2) = id%KEEP(203)
         RETURN
      ENDIF
      TMP=MAX_NB_NODES_FOR_ZONE
      CALL MPI_ALLREDUCE(TMP,MAX_NB_NODES_FOR_ZONE,1,
     $     MPI_INTEGER,MPI_MAX,id%COMM_NODES, IERR)
      NB_Z=KEEP_OOC(107)+1
      ALLOCATE(POS_IN_MEM(MAX_NB_NODES_FOR_ZONE*NB_Z),
     $     INODE_TO_POS(KEEP_OOC(28)),
     $     stat=allocok)
      IF (allocok > 0) THEN
         WRITE(*,*) 'PB allocation in CMUMPS_586'
         id%INFO(1) = -13
         id%INFO(2) = id%KEEP(28)+(MAX_NB_NODES_FOR_ZONE*NB_Z)
         RETURN
      ENDIF
      INODE_TO_POS=0
      POS_IN_MEM=0
      ALLOCATE(LRLUS_SOLVE(NB_Z), LRLU_SOLVE_T(NB_Z),LRLU_SOLVE_B(NB_Z),
     $     POSFAC_SOLVE(NB_Z),IDEB_SOLVE_Z(NB_Z),
     $     PDEB_SOLVE_Z(NB_Z),SIZE_SOLVE_Z(NB_Z),
     $     CURRENT_POS_T(NB_Z),CURRENT_POS_B(NB_Z),
     $     POS_HOLE_T(NB_Z),POS_HOLE_B(NB_Z),
     $     stat=allocok)
      IF (allocok > 0) THEN
         WRITE(*,*) 'PB allocation in CMUMPS_INIT_OOC_SOLVE'
         id%INFO(1) = -13
         id%INFO(2) = 9*(NB_Z+1)
         RETURN
      ENDIF
      IERR=0
      CALL CMUMPS_GET_MAX_NB_REQ(MAX_NB_REQ,IERR)
      ALLOCATE(SIZE_OF_READ(MAX_NB_REQ),FIRST_POS_IN_READ(MAX_NB_REQ),
     $     READ_DEST(MAX_NB_REQ),READ_MNG(MAX_NB_REQ),
     $     REQ_TO_ZONE(MAX_NB_REQ),REQ_ID(MAX_NB_REQ),stat=allocok)
      SIZE_OF_READ=-9999
      FIRST_POS_IN_READ=-9999
      READ_DEST=-9999
      READ_MNG=-9999
      REQ_TO_ZONE=-9999
      REQ_ID=-9999
      IF (allocok > 0) THEN
         WRITE(*,*) 'PB allocation in CMUMPS_INIT_OOC_SOLVE'
         id%INFO(1) = -13
         id%INFO(2) = 6*(NB_Z+1)
         RETURN
      ENDIF
      MIN_SIZE_READ=MIN(MAX((128*1024)/id%KEEP(35),SIZE_ZONE_SOLVE/3),
     $     SIZE_ZONE_SOLVE)
      TMP_SIZE=1
      J=1
      DO I=1,NB_Z-1
         IDEB_SOLVE_Z(I)=TMP_SIZE
         POSFAC_SOLVE(I)=TMP_SIZE
         LRLUS_SOLVE(I)=SIZE_ZONE_SOLVE
         LRLU_SOLVE_T(I)=SIZE_ZONE_SOLVE
         LRLU_SOLVE_B(I)=0
         SIZE_SOLVE_Z(I)=SIZE_ZONE_SOLVE
         CURRENT_POS_T(I)=J
         CURRENT_POS_B(I)=J
         PDEB_SOLVE_Z(I)=J
         POS_HOLE_T(I)=J
         POS_HOLE_B(I)=J
         J=J+MAX_NB_NODES_FOR_ZONE
         TMP_SIZE=TMP_SIZE+SIZE_ZONE_SOLVE
      ENDDO
      IDEB_SOLVE_Z(NB_Z)=TMP_SIZE
      PDEB_SOLVE_Z(NB_Z)=J
      POSFAC_SOLVE(NB_Z)=TMP_SIZE
      LRLUS_SOLVE(NB_Z)=SIZE_SOLVE_EMM
      LRLU_SOLVE_T(NB_Z)=SIZE_SOLVE_EMM
      LRLU_SOLVE_B(NB_Z)=0
      SIZE_SOLVE_Z(NB_Z)=SIZE_SOLVE_EMM
      CURRENT_POS_T(NB_Z)=J
      CURRENT_POS_B(NB_Z)=J
      POS_HOLE_T(NB_Z)=J
      POS_HOLE_B(NB_Z)=J
      IO_REQ=-77777
      REQ_ACT=0
      FIRST_ACTIVE_Z=1
      NB_ZONE_REQ=0
      SIZE_ZONE_REQ=0
      CURRENT_SOLVE_READ_ZONE=0
      NB_CALLED=0
      NB_CALL=0
      END SUBROUTINE CMUMPS_586
      SUBROUTINE CMUMPS_585(A,LA,PTRFAC,NSTEPS,IERR)
      IMPLICIT NONE
      INTEGER LA,NSTEPS,IERR
      COMPLEX A(LA)
      INTEGER PTRFAC(NSTEPS)
      INTEGER I
      IERR=0
      IF(NB_Z.GT.1)THEN
         IF(STRAT_IO_ASYNC)THEN
            DO I=1,NB_Z-1
               CALL CMUMPS_594(A,LA,PTRFAC,NSTEPS,IERR)
               IF(IERR.LT.0)THEN
                  RETURN
               ENDIF
            ENDDO
         ELSE
            CALL CMUMPS_594(A,LA,PTRFAC,NSTEPS,IERR)
            IF(IERR.LT.0)THEN
               RETURN
            ENDIF
         ENDIF
      ENDIF
      END SUBROUTINE CMUMPS_585
      SUBROUTINE CMUMPS_594(A,LA,PTRFAC,NSTEPS,IERR)
      IMPLICIT NONE
      INTEGER NSTEPS,LA,IERR
      COMPLEX A(LA)
      INTEGER PTRFAC(NSTEPS)
      INTEGER ZONE,SIZE,DEST,FLAG
      CALL CMUMPS_603(ZONE)
      IERR=0
      CALL CMUMPS_611(ZONE,A,LA,PTRFAC,NSTEPS,IERR)
      IF(IERR.LT.0)THEN
         RETURN
      ENDIF
      END SUBROUTINE CMUMPS_594 
      SUBROUTINE CMUMPS_595(DEST,INDICE,SIZE,
     $     ZONE,PTRFAC,NSTEPS,POS_SEQ,NB_NODES,FLAG,IERR)
      IMPLICIT NONE
      INCLUDE 'mpif.h'
      INTEGER ZONE,SIZE,NSTEPS,INDICE,FLAG,POS_SEQ,NB_NODES
      COMPLEX DEST
      INTEGER PTRFAC(NSTEPS)
      INTEGER REQUEST,INODE,IERR
      IERR=0
      INODE=OOC_INODE_SEQUENCE(POS_SEQ)
      CALL CMUMPS_LOW_LEVEL_READ_OOC_C(LOW_LEVEL_STRAT_IO,
     $     DEST,SIZE,
     $     POS_IN_FILE(STEP_OOC(INODE)),NUM_FILE(STEP_OOC(INODE)),
     $     INODE,REQUEST,IERR)
      IF(IERR.LT.0)THEN
         RETURN
      ENDIF
      IF(STRAT_IO_ASYNC)THEN
         CALL CMUMPS_597(INODE,SIZE,INDICE,ZONE,
     $        REQUEST,POS_SEQ,NB_NODES,FLAG,PTRFAC,NSTEPS,IERR)
      ELSE
         CALL CMUMPS_597(INODE,SIZE,INDICE,ZONE,
     $        REQUEST,POS_SEQ,NB_NODES,FLAG,PTRFAC,NSTEPS,IERR)
         CALL CMUMPS_596(IO_REQ(STEP_OOC(INODE)),
     $        PTRFAC,NSTEPS)
      ENDIF
      END SUBROUTINE CMUMPS_595
      SUBROUTINE CMUMPS_596(REQUEST,PTRFAC,
     $     NSTEPS)
      IMPLICIT NONE
      INTEGER NSTEPS,REQUEST
      INTEGER PTRFAC(NSTEPS)
      INTEGER ZONE
      INTEGER POS,J,POS_REQ,I,TMP_NODE,LAST,POS_IN_S,POS_IN_MANAGE
      INTEGER SIZE, STATUS
      POS_REQ=MOD(REQUEST,MAX_NB_REQ)+1
      SIZE=SIZE_OF_READ(POS_REQ)
      I=FIRST_POS_IN_READ(POS_REQ)
      POS_IN_S=READ_DEST(POS_REQ)
      POS_IN_MANAGE=READ_MNG(POS_REQ)
      ZONE=REQ_TO_ZONE(POS_REQ)
      J=0
      DO WHILE((J.LT.SIZE).AND.(I.LE.TOTAL_NB_OOC_NODES))
         TMP_NODE=OOC_INODE_SEQUENCE(I)
         LAST=SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
         IF((INODE_TO_POS(STEP_OOC(TMP_NODE)).NE.0).AND.
     $        (INODE_TO_POS(STEP_OOC(TMP_NODE)).LT.
     $        -((N_OOC+1)*NB_Z)))THEN
            PTRFAC(STEP_OOC(TMP_NODE))=POS_IN_S
            IF(PTRFAC(STEP_OOC(TMP_NODE)).LT.IDEB_SOLVE_Z(ZONE))THEN
               WRITE(*,*)MYID_OOC,': Inernal error (42) in OOC ', 
     $              PTRFAC(STEP_OOC(TMP_NODE)),IDEB_SOLVE_Z(ZONE)
               CALL CMUMPS_ABORT()
            ENDIF
            IF(PTRFAC(STEP_OOC(TMP_NODE)).GT.
     $           (IDEB_SOLVE_Z(ZONE)+SIZE_SOLVE_Z(ZONE)-1))THEN
               WRITE(*,*)MYID_OOC,': Inernal error (43) in OOC '
               CALL CMUMPS_ABORT()
            ENDIF
            POS_IN_MEM(POS_IN_MANAGE)=TMP_NODE
            INODE_TO_POS(STEP_OOC(TMP_NODE))=POS_IN_MANAGE
            IO_REQ(STEP_OOC(TMP_NODE))=-7777
         ELSE
            POS_IN_MEM(POS_IN_MANAGE)=0
         ENDIF
         POS_IN_S=POS_IN_S+LAST
         POS_IN_MANAGE=POS_IN_MANAGE+1
         J=J+LAST
         I=I+1
      ENDDO
      SIZE_OF_READ(POS_REQ)=-9999
      FIRST_POS_IN_READ(POS_REQ)=-9999
      READ_DEST(POS_REQ)=-9999
      READ_MNG(POS_REQ)=-9999
      REQ_TO_ZONE(POS_REQ)=-9999
      REQ_ID(POS_REQ)=-9999
      END SUBROUTINE CMUMPS_596
      SUBROUTINE CMUMPS_597(INODE,SIZE,DEST,ZONE,
     $     REQUEST,POS_SEQ,NB_NODES,FLAG,PTRFAC,NSTEPS,IERR)
      IMPLICIT NONE
      INTEGER INODE,SIZE,ZONE,REQUEST,FLAG,POS_SEQ,NB_NODES,NSTEPS
      INTEGER PTRFAC(NSTEPS)
      INTEGER DEST,LOCAL_DEST
      INTEGER I,J,LAST,TMP_NUM_FILE,TMP_NODE,LOC_I,POS_REQ,NB,IERR
      IERR=0
      IF(CUR_POS_SEQUENCE.GT.TOTAL_NB_OOC_NODES)THEN
         RETURN
      ENDIF
      NB=0
      LOCAL_DEST=DEST
      I=POS_SEQ
      POS_REQ=MOD(REQUEST,MAX_NB_REQ)+1
      IF(REQ_ID(POS_REQ).NE.-9999)THEN
         CALL CMUMPS_WAIT_REQUEST(REQ_ID(POS_REQ),IERR)
         IF(IERR.LT.0)THEN
            WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
            RETURN
         ENDIF
         CALL CMUMPS_596(REQUEST,PTRFAC,NSTEPS)
      ENDIF
      SIZE_OF_READ(POS_REQ)=SIZE
      FIRST_POS_IN_READ(POS_REQ)=I
      READ_DEST(POS_REQ)=DEST
      IF(FLAG.EQ.0)THEN
         READ_MNG(POS_REQ)=CURRENT_POS_B(ZONE)-NB_NODES+1
      ELSEIF(FLAG.EQ.1)THEN
         READ_MNG(POS_REQ)=CURRENT_POS_T(ZONE)
      ENDIF
      REQ_TO_ZONE(POS_REQ)=ZONE
      REQ_ID(POS_REQ)=REQUEST
      J=0
      IF(FLAG.EQ.0)THEN
         LOC_I=CURRENT_POS_B(ZONE)-NB_NODES+1
      ENDIF
      DO WHILE((J.LT.SIZE).AND.(I.LE.TOTAL_NB_OOC_NODES))
         TMP_NODE=OOC_INODE_SEQUENCE(I)
         LAST=SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
         IF((IO_REQ(STEP_OOC(TMP_NODE)).GE.0).OR.
     $        (INODE_TO_POS(STEP_OOC(TMP_NODE)).NE.0))THEN
            IF(FLAG.EQ.1)THEN
               POS_IN_MEM(CURRENT_POS_T(ZONE))=0
            ELSEIF(FLAG.EQ.0)THEN
               POS_IN_MEM(CURRENT_POS_B(ZONE))=0
            ENDIF
         ELSE
            IO_REQ(STEP_OOC(TMP_NODE))=REQUEST
            LRLUS_SOLVE(ZONE)=LRLUS_SOLVE(ZONE)-LAST
            IF(FLAG.EQ.1)THEN
               IF(POSFAC_SOLVE(ZONE).EQ.IDEB_SOLVE_Z(ZONE))THEN
                  POS_HOLE_B(ZONE)=-9999
                  CURRENT_POS_B(ZONE)=-9999
                  LRLU_SOLVE_B(ZONE)=0
               ENDIF
               POSFAC_SOLVE(ZONE)=POSFAC_SOLVE(ZONE)+LAST
               LRLU_SOLVE_T(ZONE)=LRLU_SOLVE_T(ZONE)-LAST
               POS_IN_MEM(CURRENT_POS_T(ZONE))=-TMP_NODE-
     $              ((N_OOC+1)*NB_Z)
               INODE_TO_POS(STEP_OOC(TMP_NODE))=-CURRENT_POS_T(ZONE)-
     $              ((N_OOC+1)*NB_Z)
               PTRFAC(STEP_OOC(TMP_NODE))=-LOCAL_DEST
               LOCAL_DEST=LOCAL_DEST+SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
            ELSEIF(FLAG.EQ.0)THEN
               LRLU_SOLVE_B(ZONE)=LRLU_SOLVE_B(ZONE)-LAST
               POS_IN_MEM(LOC_I)=-TMP_NODE-((N_OOC+1)*NB_Z)
               IF(LOC_I.EQ.POS_HOLE_T(ZONE))THEN
                  IF(POS_HOLE_T(ZONE).LT.CURRENT_POS_T(ZONE))THEN
                     POS_HOLE_T(ZONE)=POS_HOLE_T(ZONE)+1
                  ENDIF
               ENDIF
               INODE_TO_POS(STEP_OOC(TMP_NODE))=-LOC_I-((N_OOC+1)*NB_Z)
               PTRFAC(STEP_OOC(TMP_NODE))=-LOCAL_DEST
               LOCAL_DEST=LOCAL_DEST+SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
            ELSE
             WRITE(*,*)MYID_OOC,': Internal error (39) in OOC ',
     &                 ' Invalid Flag Value in ', 
     $                 ' CMUMPS_597',FLAG
               CALL CMUMPS_ABORT()
            ENDIF
         ENDIF
         IF(POS_IN_MEM(CURRENT_POS_T(ZONE)).NE.0)THEN
            IF(POS_IN_MEM(CURRENT_POS_T(ZONE)).EQ.
     $           POS_IN_MEM(PDEB_SOLVE_Z(ZONE)))THEN
               IF(CURRENT_POS_T(ZONE).NE.PDEB_SOLVE_Z(ZONE))THEN
             WRITE(*,*)MYID_OOC,': Internal error (40) in OOC ',
     &                      CURRENT_POS_T(ZONE),
     $                 PDEB_SOLVE_Z(ZONE),
     $                 POS_IN_MEM(CURRENT_POS_T(ZONE)),
     $                 POS_IN_MEM(PDEB_SOLVE_Z(ZONE))
                  CALL CMUMPS_ABORT()
               ENDIF
            ENDIF
         ENDIF
         J=J+LAST
         IF(LRLUS_SOLVE(ZONE).LT.0)THEN
             WRITE(*,*)MYID_OOC,': Internal error (41) in OOC ',
     &           ' LRLUS_SOLVE must be (1) > 0',
     $           LRLUS_SOLVE(ZONE)
            CALL CMUMPS_ABORT()
         ENDIF
         I=I+1
         IF(FLAG.EQ.1)THEN
            CURRENT_POS_T(ZONE)=CURRENT_POS_T(ZONE)+1
            IF(CURRENT_POS_T(ZONE).GT.
     $           MAX_NB_NODES_FOR_ZONE+PDEB_SOLVE_Z(ZONE))THEN
               WRITE(*,*)MYID_OOC,': Internal error (1) in OOC '
               CALL CMUMPS_ABORT()
            ENDIF
            POS_HOLE_T(ZONE)=CURRENT_POS_T(ZONE)
         ELSEIF(FLAG.EQ.0)THEN
            IF(POS_HOLE_B(ZONE).LT.PDEB_SOLVE_Z(ZONE))THEN
               WRITE(*,*)MYID_OOC,': Internal error (2) in OOC ', 
     $              POS_HOLE_B(ZONE),LOC_I
               CALL CMUMPS_ABORT()
            ENDIF
            CURRENT_POS_B(ZONE)=CURRENT_POS_B(ZONE)-1
            POS_HOLE_B(ZONE)=POS_HOLE_B(ZONE)-1
            IF(POS_HOLE_B(ZONE).LT.PDEB_SOLVE_Z(ZONE))THEN
               POS_HOLE_B(ZONE)=-9999
               LRLU_SOLVE_B(ZONE)=0
            ENDIF
         ELSE
            WRITE(*,*)MYID_OOC,': Internal error (3) in OOC ', 
     &       ' Invalid Flag Value in ', 
     $       ' CMUMPS_597',FLAG
            CALL CMUMPS_ABORT()
         ENDIF
         IF(FLAG.EQ.0)THEN
            LOC_I=LOC_I+1
         ENDIF
         NB=NB+1
      ENDDO
      IF(NB.NE.NB_NODES)THEN
         WRITE(*,*)MYID_OOC,': Internal error (4) in OOC ',
     $        ' CMUMPS_597 ',NB,NB_NODES
      ENDIF
      IF(SOLVE_STEP.EQ.0)THEN
         CUR_POS_SEQUENCE=I
      ELSE
         CUR_POS_SEQUENCE=POS_SEQ-1
      ENDIF
      END SUBROUTINE CMUMPS_597
      SUBROUTINE CMUMPS_598(INODE,PTRFAC,NSTEPS,A,
     $     LA,IERR)
      IMPLICIT NONE
      INTEGER LA
      INTEGER IERR
      COMPLEX A(LA)
      INTEGER INODE,NSTEPS
      INTEGER PTRFAC(NSTEPS)
      INTEGER TMP,FREE_SIZE,TMP_NODE,I,ZONE,J,FREE_HOLE_POS,
     $     FREE_HOLE_FLAG
      LOGICAL CONTIGUOUS
      INTEGER WHICH
      WHICH=-1
      IF(INODE_TO_POS(STEP_OOC(INODE)).LE.0)THEN
         WRITE(*,*)MYID_OOC,': Internal error (5) in OOC ',
     &            ' Problem in CMUMPS_598'
         CALL CMUMPS_ABORT()
      ENDIF
      CALL CMUMPS_600(INODE,ZONE,PTRFAC,NSTEPS)
      TMP=INODE_TO_POS(STEP_OOC(INODE))
      INODE_TO_POS(STEP_OOC(INODE))=-TMP
      POS_IN_MEM(TMP)=-INODE
      PTRFAC(STEP_OOC(INODE))=-PTRFAC(STEP_OOC(INODE))
      LRLUS_SOLVE(ZONE)=LRLUS_SOLVE(ZONE)+
     $        SIZE_OF_BLOCK(STEP_OOC(INODE))         
      IF(LRLUS_SOLVE(ZONE).LT.0)THEN
         WRITE(*,*)MYID_OOC,': Internal error (6) in OOC ',
     &                      ': LRLUS_SOLVE must be (2) > 0'
         CALL CMUMPS_ABORT()
      ENDIF
      FREE_HOLE_FLAG=0
      IF(SOLVE_STEP.EQ.0)THEN
         IF(TMP.GT.POS_HOLE_B(ZONE))THEN
            WHICH=0
         ELSEIF(TMP.LT.POS_HOLE_T(ZONE))THEN
            WHICH=1
         ENDIF
      ELSEIF(SOLVE_STEP.EQ.1)THEN
         IF(TMP.LT.POS_HOLE_T(ZONE))THEN
            WHICH=0
         ELSEIF(TMP.GT.POS_HOLE_B(ZONE))THEN
            WHICH=1
         ENDIF         
      ENDIF
#if ! defined (OLD_OOC_CODE)
      IF(WHICH.EQ.1)THEN
         J=MAX(PDEB_SOLVE_Z(ZONE),POS_HOLE_T(ZONE))
         J=MIN(J,PDEB_SOLVE_Z(ZONE)+MAX_NB_NODES_FOR_ZONE-1)
         FREE_SIZE=0
         DO I=J,TMP,-1
            IF((POS_IN_MEM(I).LT.0).AND.(POS_IN_MEM(I).GT.
     $           -(N_OOC+1)*NB_Z))THEN
               TMP_NODE=-POS_IN_MEM(I)
               FREE_SIZE=FREE_SIZE+SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
            ELSEIF(POS_IN_MEM(I).NE.0)THEN
               GOTO 666
            ENDIF
            J=J-1
         ENDDO
         POS_HOLE_T(ZONE)=TMP
 666     CONTINUE
      ELSEIF(WHICH.EQ.0)THEN
         J=MAX(PDEB_SOLVE_Z(ZONE),POS_HOLE_B(ZONE))
         J=MIN(J,PDEB_SOLVE_Z(ZONE)+MAX_NB_NODES_FOR_ZONE-1)
         FREE_SIZE=0
         DO I=J,TMP
            IF((POS_IN_MEM(I).LT.0).AND.(POS_IN_MEM(I).GT.
     $           -(N_OOC+1)*NB_Z))THEN
               TMP_NODE=-POS_IN_MEM(I)
               FREE_SIZE=FREE_SIZE+SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
            ELSEIF(POS_IN_MEM(I).NE.0)THEN
               IF(J.EQ.PDEB_SOLVE_Z(ZONE))THEN
                  POS_HOLE_B(ZONE)=-9999
                  LRLU_SOLVE_B(ZONE)=0
               ENDIF
               GOTO 777
            ENDIF
         ENDDO
         POS_HOLE_B(ZONE)=TMP
 777     CONTINUE
      ENDIF
#else
      IF((TMP.EQ.CURRENT_POS_T(ZONE)-1).OR.
     $     (TMP.EQ.POS_HOLE_T(ZONE)-1))THEN
         J=MAX(PDEB_SOLVE_Z(ZONE),CURRENT_POS_T(ZONE))
         FREE_SIZE=0
         DO I=CURRENT_POS_T(ZONE)-1,PDEB_SOLVE_Z(ZONE),-1
            IF((POS_IN_MEM(I).LT.0).AND.(POS_IN_MEM(I).GT.
     $           -(N_OOC+1)*NB_Z))THEN
               TMP_NODE=-POS_IN_MEM(I)
               FREE_SIZE=FREE_SIZE+SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
            ELSEIF(POS_IN_MEM(I).NE.0)THEN
               GOTO 666
            ENDIF
            J=J-1
         ENDDO
 666     CONTINUE
         POS_HOLE_T(ZONE)=MAX(J,PDEB_SOLVE_Z(ZONE))
         IF(POS_HOLE_T(ZONE).EQ.PDEB_SOLVE_Z(ZONE))THEN
            CURRENT_POS_B(ZONE)=-9999
            POS_HOLE_B(ZONE)=-9999
            LRLU_SOLVE_B(ZONE)=0
         ENDIF
      ELSEIF(TMP.GT.POS_HOLE_B(ZONE))THEN
         J=MAX(POS_HOLE_B(ZONE),PDEB_SOLVE_Z(ZONE))
         FREE_SIZE=0
         DO I=TMP,J,-1
            IF((POS_IN_MEM(I).LT.0).AND.(POS_IN_MEM(I).GT.
     $           -(N_OOC+1)*NB_Z))THEN
               TMP_NODE=-POS_IN_MEM(I)
               FREE_SIZE=FREE_SIZE+SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
            ELSEIF(POS_IN_MEM(I).NE.0)THEN
               IF(J.EQ.PDEB_SOLVE_Z(ZONE))THEN
                  POS_HOLE_B(ZONE)=-9999
                  LRLU_SOLVE_B(ZONE)=0
               ENDIF
               GOTO 777
            ENDIF
         ENDDO
         POS_HOLE_B(ZONE)=TMP
 777     CONTINUE
      ENDIF
#endif
 222  CONTINUE
      IERR=0
      IF(NB_Z.GT.1)THEN
         CALL CMUMPS_601(ZONE)
         IF((LRLUS_SOLVE(ZONE).GE.MIN_SIZE_READ).OR.
     $        (LRLUS_SOLVE(ZONE).GE.
     $        INT(0.5*REAL(SIZE_SOLVE_Z(ZONE)))))THEN
            CALL CMUMPS_594(A,LA,PTRFAC,NSTEPS,IERR)
            IF(IERR.LT.0)THEN
               RETURN
            ENDIF
         ELSE
            CALL CMUMPS_603(ZONE)
         ENDIF
      ENDIF      
      END SUBROUTINE CMUMPS_598
      FUNCTION CMUMPS_SOLVE_IS_INODE_IN_MEM(INODE,PTRFAC,NSTEPS,A,LA,
     $     IERR)
      IMPLICIT NONE
      INTEGER INODE,NSTEPS,LA,IERR
      COMPLEX A(LA)
      INTEGER PTRFAC(NSTEPS)
      LOGICAL CMUMPS_SOLVE_IS_INODE_IN_MEM
      INTEGER ZONE
      IERR=0
      IF(INODE_TO_POS(STEP_OOC(INODE)).GT.0)THEN
         CMUMPS_SOLVE_IS_INODE_IN_MEM=.TRUE.
         IF(.NOT.CMUMPS_SOLVE_IS_END_REACHED())THEN
            IF(OOC_INODE_SEQUENCE(CUR_POS_SEQUENCE).EQ.INODE)THEN
               IF(SOLVE_STEP.EQ.0)THEN
                  CUR_POS_SEQUENCE=CUR_POS_SEQUENCE+1
               ELSEIF(SOLVE_STEP.EQ.1)THEN
                  CUR_POS_SEQUENCE=CUR_POS_SEQUENCE-1
               ENDIF
            ENDIF
         ENDIF
      ELSEIF(INODE_TO_POS(STEP_OOC(INODE)).LT.0)THEN
         IF(INODE_TO_POS(STEP_OOC(INODE)).LT.-((N_OOC+1)*NB_Z))THEN
            CALL CMUMPS_WAIT_REQUEST(IO_REQ(STEP_OOC(INODE)),IERR)
            IF(IERR.LT.0)THEN
               WRITE(*,*)MYID_OOC,': Internal error (7) in OOC ',
     &                   ERR_STR_OOC(1:DIM_ERR_STR_OOC)
               RETURN
            ENDIF
            CALL CMUMPS_596(IO_REQ(STEP_OOC(INODE)),
     $           PTRFAC,NSTEPS)
            REQ_ACT=REQ_ACT-1
         ELSE
            CALL CMUMPS_599(INODE,PTRFAC,NSTEPS)
            IF(.NOT.CMUMPS_SOLVE_IS_END_REACHED())THEN
               IF(OOC_INODE_SEQUENCE(CUR_POS_SEQUENCE).EQ.INODE)THEN
                  IF(SOLVE_STEP.EQ.0)THEN
                     CUR_POS_SEQUENCE=CUR_POS_SEQUENCE+1
                  ELSEIF(SOLVE_STEP.EQ.1)THEN
                     CUR_POS_SEQUENCE=CUR_POS_SEQUENCE-1
                  ENDIF
               ENDIF
            ENDIF
         ENDIF
         CMUMPS_SOLVE_IS_INODE_IN_MEM=.TRUE.
      ELSE
         CMUMPS_SOLVE_IS_INODE_IN_MEM=.FALSE.
      ENDIF
      RETURN
      END FUNCTION CMUMPS_SOLVE_IS_INODE_IN_MEM
      SUBROUTINE CMUMPS_599(INODE,PTRFAC,NSTEPS)
      IMPLICIT NONE
      INTEGER INODE,NSTEPS
      INTEGER PTRFAC(NSTEPS)
      INTEGER ZONE
      INODE_TO_POS(STEP_OOC(INODE))=-INODE_TO_POS(STEP_OOC(INODE))
      POS_IN_MEM(INODE_TO_POS(STEP_OOC(INODE)))=
     $     -POS_IN_MEM(INODE_TO_POS(STEP_OOC(INODE)))
      PTRFAC(STEP_OOC(INODE))=-PTRFAC(STEP_OOC(INODE))
      CALL CMUMPS_610(PTRFAC(STEP_OOC(INODE)),ZONE)
      IF(INODE_TO_POS(STEP_OOC(INODE)).LE.POS_HOLE_B(ZONE))THEN
         IF(INODE_TO_POS(STEP_OOC(INODE)).GT.
     $        PDEB_SOLVE_Z(ZONE))THEN
            POS_HOLE_B(ZONE)=
     $           INODE_TO_POS(STEP_OOC(INODE))-1
         ELSE
            CURRENT_POS_B(ZONE)=-9999
            POS_HOLE_B(ZONE)=-9999
            LRLU_SOLVE_B(ZONE)=0
         ENDIF
      ENDIF
      IF(INODE_TO_POS(STEP_OOC(INODE)).GE.POS_HOLE_T(ZONE))THEN
         IF(INODE_TO_POS(STEP_OOC(INODE)).LT.
     $        CURRENT_POS_T(ZONE)-1)THEN
            POS_HOLE_T(ZONE)=INODE_TO_POS(STEP_OOC(INODE))+1
         ELSE
            POS_HOLE_T(ZONE)=CURRENT_POS_T(ZONE)
         ENDIF
      ENDIF
      CALL CMUMPS_609(INODE,PTRFAC,NSTEPS,1)
      END SUBROUTINE CMUMPS_599
      SUBROUTINE CMUMPS_600(INODE,ZONE,PTRFAC,NSTEPS)
      IMPLICIT NONE
      INTEGER INODE,ZONE,NSTEPS
      INTEGER PTRFAC(NSTEPS)
      ZONE=1
      DO WHILE (ZONE.LE.NB_Z)
         IF(PTRFAC(STEP_OOC(INODE)).LT.IDEB_SOLVE_Z(ZONE))THEN
            ZONE=ZONE-1
            EXIT
         ENDIF
         ZONE=ZONE+1
      ENDDO
      IF(ZONE.EQ.NB_Z+1)THEN
         ZONE=ZONE-1
      ENDIF
      END SUBROUTINE CMUMPS_600
      SUBROUTINE CMUMPS_601(ZONE)
      IMPLICIT NONE
      INTEGER ZONE
      ZONE=MOD((CURRENT_SOLVE_READ_ZONE+1),NB_Z-1)+1
      END SUBROUTINE CMUMPS_601
      SUBROUTINE CMUMPS_603(ZONE)
      IMPLICIT NONE
      INTEGER ZONE
      IF(NB_Z.GT.1)THEN
         CURRENT_SOLVE_READ_ZONE=MOD((CURRENT_SOLVE_READ_ZONE+1),NB_Z-1)
         ZONE=CURRENT_SOLVE_READ_ZONE+1
      ELSE
         ZONE=NB_Z
      ENDIF
      END SUBROUTINE CMUMPS_603
      SUBROUTINE CMUMPS_578(INODE,PTRFAC,
     *     KEEP,KEEP8,
     $     A,IERR)
      IMPLICIT NONE
      INTEGER INODE,KEEP(500),IERR
      INTEGER*8 KEEP8(150)
      INTEGER PTRFAC(KEEP(28))
      COMPLEX A(FACT_AREA_SIZE)
      INTEGER REQUESTED_SIZE
      INTEGER ZONE,IFLAG
      LOGICAL FLAG
      IERR=0
      IFLAG=0
      REQUESTED_SIZE=SIZE_OF_BLOCK(STEP_OOC(INODE))
      ZONE=NB_Z
      IF(CURRENT_POS_T(ZONE).GT.
     $     (PDEB_SOLVE_Z(ZONE)+MAX_NB_NODES_FOR_ZONE-1))THEN
         CALL CMUMPS_608(A,FACT_AREA_SIZE,
     $        REQUESTED_SIZE,PTRFAC,KEEP(28),ZONE,IERR)
      ENDIF
      IF((LRLU_SOLVE_T(ZONE).GT.SIZE_OF_BLOCK(STEP_OOC(INODE))).AND.
     $     (CURRENT_POS_T(ZONE).LE.
     $     (PDEB_SOLVE_Z(ZONE)+MAX_NB_NODES_FOR_ZONE-1)))THEN
         CALL CMUMPS_606(INODE,PTRFAC,
     *        KEEP,KEEP8,A,ZONE)
      ELSEIF(LRLU_SOLVE_B(ZONE).GT.SIZE_OF_BLOCK(STEP_OOC(INODE)).AND.
     $        (CURRENT_POS_B(ZONE).GT.0))THEN
         CALL CMUMPS_607(INODE,PTRFAC,
     *        KEEP,KEEP8,A,ZONE)
      ELSE
         IF(CMUMPS_579(INODE,ZONE))THEN
            IF(SOLVE_STEP.EQ.0)THEN
               CALL CMUMPS_604(A,FACT_AREA_SIZE,
     $              REQUESTED_SIZE,PTRFAC,
     $              KEEP(28),ZONE,IFLAG,IERR)
               IF(IFLAG.EQ.1)THEN
                  CALL CMUMPS_606(INODE,PTRFAC,
     $                 KEEP,KEEP8,A,ZONE)
               ELSEIF(IFLAG.EQ.0)THEN
                  CALL CMUMPS_605(A,FACT_AREA_SIZE,
     $                 REQUESTED_SIZE,PTRFAC,
     $                 KEEP(28),ZONE,IFLAG,IERR)           
                  IF(IFLAG.EQ.1)THEN
                     CALL CMUMPS_607(INODE,PTRFAC,
     $                    KEEP,KEEP8,A,ZONE)
                  ENDIF
               ENDIF
            ELSE
               CALL CMUMPS_605(A,FACT_AREA_SIZE,
     $              REQUESTED_SIZE,PTRFAC,
     $              KEEP(28),ZONE,IFLAG,IERR)               
               IF(IFLAG.EQ.1)THEN
                  CALL CMUMPS_607(INODE,PTRFAC,
     $                 KEEP,KEEP8,A,ZONE)
               ELSEIF(IFLAG.EQ.0)THEN
                  CALL CMUMPS_604(A,FACT_AREA_SIZE,
     $                 REQUESTED_SIZE,PTRFAC,
     $                 KEEP(28),ZONE,IFLAG,IERR)
                  IF(IFLAG.EQ.1)THEN
                     CALL CMUMPS_606(INODE,PTRFAC,
     $                    KEEP,KEEP8,A,ZONE)
                  ENDIF
               ENDIF
            ENDIF
            IF(IFLAG.EQ.0)THEN
               CALL CMUMPS_608(A,FACT_AREA_SIZE,
     $              REQUESTED_SIZE,PTRFAC,KEEP(28),ZONE,IERR)
               CALL CMUMPS_606(INODE,PTRFAC,
     $              KEEP,KEEP8,A,ZONE)
            ENDIF
         ELSE
            WRITE(*,*)MYID_OOC,': Internal error (8) in OOC ',
     &                         ' Not enough space for Solve',INODE,
     $           SIZE_OF_BLOCK(STEP_OOC(INODE)),LRLUS_SOLVE(ZONE)
            IERR=-9
            RETURN
         ENDIF
      ENDIF
      IF(LRLUS_SOLVE(ZONE).LT.0)THEN
         WRITE(*,*)MYID_OOC,': Internal error (9) in OOC ',
     &                      ' LRLUS_SOLVE must be (3) > 0'
         CALL CMUMPS_ABORT()
      ENDIF
      END SUBROUTINE CMUMPS_578
      SUBROUTINE CMUMPS_604(A,LA,REQUESTED_SIZE,PTRFAC,
     $     NSTEPS,ZONE,FLAG,IERR)
      IMPLICIT NONE
      INTEGER REQUESTED_SIZE,LA,NSTEPS,ZONE,FLAG
      INTEGER PTRFAC(NSTEPS)
      COMPLEX A(LA)
      INTEGER I,TMP_NODE,FREE_SIZE,HOLE,FREE_HOLE_POS,FREE_HOLE_FLAG,
     $     FREE_HOLE,J,IERR
      LOGICAL FLAG_HOLE
      FLAG=0
      IERR=0
      IF(LRLU_SOLVE_T(ZONE).EQ.SIZE_SOLVE_Z(ZONE))THEN
         GOTO 50
      ENDIF
      IF((POS_HOLE_T(ZONE).EQ.PDEB_SOLVE_Z(ZONE)).OR.
     $     (POS_HOLE_T(ZONE).LE.POS_HOLE_B(ZONE)).OR.
     $     (POS_HOLE_T(ZONE).EQ.POS_HOLE_B(ZONE)+1))THEN
         CURRENT_POS_B(ZONE)=-9999
         POS_HOLE_B(ZONE)=-9999
         LRLU_SOLVE_B(ZONE)=0
         POS_HOLE_T(ZONE)=PDEB_SOLVE_Z(ZONE)
      ENDIF
      FREE_HOLE=0
      FREE_SIZE=0
      FREE_HOLE_FLAG=0      
      FREE_HOLE_POS=POSFAC_SOLVE(ZONE)
      DO I=CURRENT_POS_T(ZONE)-1,POS_HOLE_T(ZONE),-1
         IF((POS_IN_MEM(I).LT.0).AND.(POS_IN_MEM(I).GT.
     $        -(N_OOC+1)*NB_Z))THEN
            TMP_NODE=-POS_IN_MEM(I)
            IF(FREE_HOLE_FLAG.EQ.1)THEN
               FREE_HOLE=FREE_HOLE_POS-
     $              (ABS(PTRFAC(STEP_OOC(TMP_NODE)))+
     $              SIZE_OF_BLOCK(STEP_OOC(TMP_NODE)))
               FREE_HOLE_FLAG=0
               FREE_SIZE=FREE_SIZE+FREE_HOLE
            ENDIF
            FREE_HOLE_POS=ABS(PTRFAC(STEP_OOC(TMP_NODE)))
            PTRFAC(STEP_OOC(TMP_NODE))=-777777
            INODE_TO_POS(STEP_OOC(TMP_NODE))=0
            POS_IN_MEM(I)=0
            FREE_SIZE=FREE_SIZE+SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
         ELSEIF(POS_IN_MEM(I).EQ.0)THEN
            FREE_HOLE_FLAG=1
         ELSEIF(POS_IN_MEM(I).NE.0)THEN
            WRITE(*,*)MYID_OOC,': Internal error (10) in OOC ',
     $            ' CMUMPS_604',
     $           CURRENT_POS_T(ZONE)-1,POS_HOLE_T(ZONE),I
            CALL CMUMPS_ABORT()
         ENDIF
      ENDDO
      IF(POS_HOLE_T(ZONE).EQ.PDEB_SOLVE_Z(ZONE))THEN
         IF(FREE_HOLE_FLAG.EQ.0)THEN
            FREE_HOLE_FLAG=1
         ENDIF
      ENDIF
      IF(FREE_HOLE_FLAG.EQ.1)THEN
         IF(POS_HOLE_T(ZONE)-1.GT.PDEB_SOLVE_Z(ZONE))THEN
            I=POS_HOLE_T(ZONE)-1
            TMP_NODE=ABS(POS_IN_MEM(I))
            IF(TMP_NODE.GT.(N_OOC+1)*NB_Z)THEN
               TMP_NODE=TMP_NODE-(N_OOC+1)*NB_Z
               CALL CMUMPS_WAIT_REQUEST(IO_REQ(STEP_OOC(TMP_NODE)),IERR)
               IF(IERR.LT.0)THEN
                  WRITE(*,*)MYID_OOC,': Internal error (11) in OOC ',
     &                               ERR_STR_OOC(1:DIM_ERR_STR_OOC)
                  RETURN
               ENDIF
               REQ_ACT=REQ_ACT-1
               CALL CMUMPS_596(
     $              IO_REQ(STEP_OOC(TMP_NODE)),PTRFAC,NSTEPS)
               FREE_HOLE=FREE_HOLE_POS-
     $              (ABS(PTRFAC(STEP_OOC(TMP_NODE)))+
     $              SIZE_OF_BLOCK(STEP_OOC(TMP_NODE)))
            ELSEIF(TMP_NODE.EQ.0)THEN
               DO J=I,PDEB_SOLVE_Z(ZONE),-1
                  IF(POS_IN_MEM(J).NE.0) EXIT
               ENDDO
               IF(POS_IN_MEM(J).LT.0)THEN
                  WRITE(*,*)MYID_OOC,': Internal error (12) in OOC ',
     $                 ' CMUMPS_604'
                  CALL CMUMPS_ABORT()
               ENDIF
               IF(J.GE.PDEB_SOLVE_Z(ZONE))THEN
                  TMP_NODE=POS_IN_MEM(J)
                  FREE_HOLE=FREE_HOLE_POS-
     $                 (ABS(PTRFAC(STEP_OOC(TMP_NODE)))+
     $                 SIZE_OF_BLOCK(STEP_OOC(TMP_NODE)))
               ELSE
                  FREE_HOLE=FREE_HOLE_POS-IDEB_SOLVE_Z(ZONE)
               ENDIF
            ELSEIF(TMP_NODE.LT.0)THEN
               WRITE(*,*)MYID_OOC,': Internal error (13) in OOC', 
     $           ' CMUMPS_604'
               CALL CMUMPS_ABORT()
            ELSE
               FREE_HOLE=FREE_HOLE_POS-
     $              (ABS(PTRFAC(STEP_OOC(TMP_NODE)))+
     $              SIZE_OF_BLOCK(STEP_OOC(TMP_NODE)))
            ENDIF
         ELSE
            FREE_HOLE=FREE_HOLE_POS-IDEB_SOLVE_Z(ZONE)
         ENDIF
         FREE_SIZE=FREE_SIZE+FREE_HOLE
      ENDIF
      CURRENT_POS_T(ZONE)=POS_HOLE_T(ZONE)
      LRLU_SOLVE_T(ZONE)=LRLU_SOLVE_T(ZONE)+FREE_SIZE
      POSFAC_SOLVE(ZONE)=POSFAC_SOLVE(ZONE)-FREE_SIZE
 50   CONTINUE
      IF(REQUESTED_SIZE.LE.LRLU_SOLVE_T(ZONE))THEN
         FLAG=1
      ELSE
         FLAG=0
      ENDIF
      END SUBROUTINE CMUMPS_604
      SUBROUTINE CMUMPS_605(A,LA,REQUESTED_SIZE,
     $     PTRFAC,NSTEPS,ZONE,FLAG,IERR)
      IMPLICIT NONE
      INTEGER REQUESTED_SIZE,LA,NSTEPS,ZONE,FLAG
      INTEGER PTRFAC(NSTEPS)
      COMPLEX A(LA)
      INTEGER I,J,TMP_NODE,FREE_SIZE,FREE_HOLE_POS,FREE_HOLE_FLAG,
     $     FREE_HOLE,TMP_LRLU,IERR
      IERR=0
      FLAG=0
      IF(LRLU_SOLVE_B(ZONE).EQ.SIZE_SOLVE_Z(ZONE))THEN
         GOTO 50
      ENDIF
      IF((POS_HOLE_T(ZONE).EQ.PDEB_SOLVE_Z(ZONE)).OR.
     $     (POS_HOLE_T(ZONE).LE.POS_HOLE_B(ZONE)).OR.
     $     (POS_HOLE_T(ZONE).EQ.POS_HOLE_B(ZONE)+1))THEN
         CURRENT_POS_B(ZONE)=-9999
         POS_HOLE_B(ZONE)=-9999
         LRLU_SOLVE_B(ZONE)=0
         POS_HOLE_T(ZONE)=PDEB_SOLVE_Z(ZONE)
      ENDIF
      FREE_HOLE=0
      FREE_SIZE=0
      FREE_HOLE_FLAG=0
      FREE_HOLE_POS=IDEB_SOLVE_Z(ZONE)
      IF(POS_HOLE_B(ZONE).EQ.-9999)THEN
         GOTO 50
      ENDIF
      DO I=PDEB_SOLVE_Z(ZONE),POS_HOLE_B(ZONE)
         IF((POS_IN_MEM(I).LE.0).AND.(POS_IN_MEM(I).GT.
     $        -(N_OOC+1)*NB_Z))THEN
            TMP_NODE=-POS_IN_MEM(I)
            IF(TMP_NODE.NE.0)THEN
               IF(I.EQ.PDEB_SOLVE_Z(ZONE))THEN
                  IF(ABS(PTRFAC(STEP_OOC(TMP_NODE))).NE.
     $                 IDEB_SOLVE_Z(ZONE))THEN
                     FREE_SIZE=FREE_SIZE+ABS(PTRFAC(STEP_OOC(TMP_NODE)))
     $                    -IDEB_SOLVE_Z(ZONE)
                  ENDIF
               ENDIF
               IF(FREE_HOLE_FLAG.EQ.1)THEN
                  FREE_HOLE=ABS(PTRFAC(STEP_OOC(TMP_NODE)))-
     $                 FREE_HOLE_POS
                  FREE_HOLE_FLAG=0
                  FREE_SIZE=FREE_SIZE+FREE_HOLE
               ENDIF
               FREE_HOLE_POS=ABS(PTRFAC(STEP_OOC(TMP_NODE)))+
     $              SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
               PTRFAC(STEP_OOC(TMP_NODE))=-777777
               INODE_TO_POS(STEP_OOC(TMP_NODE))=0
               FREE_SIZE=FREE_SIZE+SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
            ELSE
               FREE_HOLE_FLAG=1
            ENDIF
            POS_IN_MEM(I)=0
         ELSEIF(POS_IN_MEM(I).NE.0)THEN
            WRITE(*,*)MYID_OOC,': Internal error (14) in OOC ',
     $            ' CMUMPS_605',
     $           CURRENT_POS_T(ZONE)-1,POS_HOLE_B(ZONE),I,POS_IN_MEM(I)
            CALL CMUMPS_ABORT()
         ENDIF
      ENDDO
      IF(FREE_HOLE_FLAG.EQ.1)THEN
         IF(POS_HOLE_B(ZONE)+1.LT.CURRENT_POS_T(ZONE)-1)THEN
            I=POS_HOLE_B(ZONE)+1
            TMP_NODE=ABS(POS_IN_MEM(I))
            IF(TMP_NODE.GT.(N_OOC+1)*NB_Z)THEN
               TMP_NODE=TMP_NODE-(N_OOC+1)*NB_Z
               CALL CMUMPS_WAIT_REQUEST(IO_REQ(STEP_OOC(TMP_NODE)),IERR)
               IF(IERR.LT.0)THEN
                 WRITE(*,*)MYID_OOC,': Internal error (15) in OOC ',
     &                               ERR_STR_OOC(1:DIM_ERR_STR_OOC)
                  RETURN
               ENDIF
               REQ_ACT=REQ_ACT-1
               CALL CMUMPS_596(
     $              IO_REQ(STEP_OOC(TMP_NODE)),PTRFAC,NSTEPS)
               FREE_HOLE=ABS(PTRFAC(STEP_OOC(TMP_NODE)))-FREE_HOLE_POS
            ELSEIF(TMP_NODE.EQ.0)THEN
               DO J=I,CURRENT_POS_T(ZONE)-1
                  IF(POS_IN_MEM(J).NE.0) EXIT
               ENDDO
               IF(POS_IN_MEM(J).LT.0)THEN
                  WRITE(*,*)MYID_OOC,': Internal error (16) in OOC ',
     $                  ' CMUMPS_605'
                  CALL CMUMPS_ABORT()
               ENDIF
               IF(J.LE.CURRENT_POS_T(ZONE)-1)THEN
                  TMP_NODE=POS_IN_MEM(J)
                  FREE_HOLE=ABS(PTRFAC(STEP_OOC(TMP_NODE)))-
     $                 FREE_HOLE_POS
               ELSE
                  FREE_HOLE=POSFAC_SOLVE(ZONE)-FREE_HOLE_POS
               ENDIF
            ELSEIF(TMP_NODE.LT.0)THEN
               WRITE(*,*)MYID_OOC,': Internal error (17) in OOC ',
     $           ' CMUMPS_605'
               CALL CMUMPS_ABORT()
            ELSE
               FREE_HOLE=ABS(PTRFAC(STEP_OOC(TMP_NODE)))-
     $              FREE_HOLE_POS
            ENDIF
         ELSE
            FREE_HOLE=POSFAC_SOLVE(ZONE)-FREE_HOLE_POS
         ENDIF
         FREE_SIZE=FREE_SIZE+FREE_HOLE
      ENDIF
      LRLU_SOLVE_B(ZONE)=FREE_SIZE
      IF(POS_HOLE_B(ZONE).LT.CURRENT_POS_T(ZONE)-1)THEN
         TMP_NODE=POS_IN_MEM(POS_HOLE_B(ZONE)+1)
         IF(TMP_NODE.LT.-(N_OOC+1)*NB_Z)THEN
            TMP_NODE=ABS(TMP_NODE)-(N_OOC+1)*NB_Z
            CALL CMUMPS_WAIT_REQUEST(IO_REQ(STEP_OOC(TMP_NODE)),IERR)
            IF(IERR.LT.0)THEN
               WRITE(*,*)MYID_OOC,': Internal error (18) in OOC ',
     &                            ERR_STR_OOC(1:DIM_ERR_STR_OOC)
               RETURN
            ENDIF
            REQ_ACT=REQ_ACT-1
            CALL CMUMPS_596(
     $           IO_REQ(STEP_OOC(TMP_NODE)),PTRFAC,NSTEPS)
         ENDIF
         LRLU_SOLVE_B(ZONE)=LRLU_SOLVE_B(ZONE)+
     $        (ABS(PTRFAC(STEP_OOC(ABS(TMP_NODE))))-IDEB_SOLVE_Z(ZONE)-
     $        LRLU_SOLVE_B(ZONE))
      ENDIF
      CURRENT_POS_B(ZONE)=POS_HOLE_B(ZONE)
 50   CONTINUE
      IF((POS_HOLE_B(ZONE).EQ.-9999).AND.(LRLU_SOLVE_B(ZONE).NE.0))THEN
         WRITE(*,*)MYID_OOC,': Internal error (19) in OOC ',
     &             'CMUMPS_605'
         CALL CMUMPS_ABORT()
      ENDIF
      IF((REQUESTED_SIZE.LE.LRLU_SOLVE_B(ZONE)).AND.
     $     (POS_HOLE_B(ZONE).NE.-9999))THEN
         FLAG=1
      ELSE
         FLAG=0
      ENDIF
      END SUBROUTINE CMUMPS_605
      SUBROUTINE CMUMPS_606(INODE,PTRFAC,
     *           KEEP,KEEP8, A,ZONE)
      IMPLICIT NONE
      INTEGER INODE,KEEP(500)
      INTEGER*8 KEEP8(150)
      INTEGER PTRFAC(KEEP(28))
      COMPLEX A(FACT_AREA_SIZE)
      INTEGER REQUESTED_SIZE
      INTEGER ZONE,IFLAG
      LOGICAL FLAG
      LRLU_SOLVE_T(ZONE)=LRLU_SOLVE_T(ZONE)-
     $     SIZE_OF_BLOCK(STEP_OOC(INODE))
      LRLUS_SOLVE(ZONE)=LRLUS_SOLVE(ZONE)-
     $     SIZE_OF_BLOCK(STEP_OOC(INODE))
      PTRFAC(STEP_OOC(INODE))=POSFAC_SOLVE(ZONE)
      IF(POSFAC_SOLVE(ZONE).EQ.IDEB_SOLVE_Z(ZONE))THEN
         POS_HOLE_B(ZONE)=-9999
         CURRENT_POS_B(ZONE)=-9999
         LRLU_SOLVE_B(ZONE)=0
      ENDIF
      IF(PTRFAC(STEP_OOC(INODE)).LT.IDEB_SOLVE_Z(ZONE))THEN
         WRITE(*,*)MYID_OOC,': Internal error (20) in OOC ',
     &                      ' Problem avec debut (2)',INODE,
     $              PTRFAC(STEP_OOC(INODE)),IDEB_SOLVE_Z(ZONE),ZONE
         CALL CMUMPS_ABORT()
      ENDIF
      INODE_TO_POS(STEP_OOC(INODE))=CURRENT_POS_T(ZONE)
      POS_IN_MEM(CURRENT_POS_T(ZONE))=INODE
      IF(CURRENT_POS_T(ZONE).GT.(PDEB_SOLVE_Z(ZONE)+
     $     MAX_NB_NODES_FOR_ZONE-1))THEN
         WRITE(*,*)MYID_OOC,': Internal error (21) in OOC ',
     &                      ' Problem with CURRENT_POS_T',
     $        CURRENT_POS_T(ZONE),ZONE
         CALL CMUMPS_ABORT()
      ENDIF
      CURRENT_POS_T(ZONE)=CURRENT_POS_T(ZONE)+1
      IF(POS_HOLE_T(ZONE).EQ.PDEB_SOLVE_Z(ZONE))THEN
         POS_HOLE_B(ZONE)=MAX(CURRENT_POS_T(ZONE)-2,PDEB_SOLVE_Z(ZONE))
         CURRENT_POS_B(ZONE)=POS_HOLE_B(ZONE)
      ENDIF
      POS_HOLE_T(ZONE)=CURRENT_POS_T(ZONE)
      POSFAC_SOLVE(ZONE)=POSFAC_SOLVE(ZONE)+
     $     SIZE_OF_BLOCK(STEP_OOC(INODE))
      END SUBROUTINE CMUMPS_606
      SUBROUTINE CMUMPS_607(INODE,PTRFAC,
     *     KEEP,KEEP8,
     $     A,ZONE)
      IMPLICIT NONE
      INTEGER INODE,KEEP(500)
      INTEGER*8 KEEP8(150)
      INTEGER PTRFAC(KEEP(28))
      COMPLEX A(FACT_AREA_SIZE)
      INTEGER REQUESTED_SIZE
      INTEGER ZONE,IFLAG,TMP_NODE
      LOGICAL FLAG
      IF(POS_HOLE_B(ZONE).EQ.-9999)THEN
         WRITE(*,*)MYID_OOC,': Internal error (22) in OOC ',
     $        ' CMUMPS_607'
         CALL CMUMPS_ABORT()
      ENDIF
      LRLUS_SOLVE(ZONE)=LRLUS_SOLVE(ZONE)-
     $     SIZE_OF_BLOCK(STEP_OOC(INODE))
      LRLU_SOLVE_B(ZONE)=LRLU_SOLVE_B(ZONE)-
     $        SIZE_OF_BLOCK(STEP_OOC(INODE))
      PTRFAC(STEP_OOC(INODE))=IDEB_SOLVE_Z(ZONE)+
     $     LRLU_SOLVE_B(ZONE)
      IF(PTRFAC(STEP_OOC(INODE)).LT.IDEB_SOLVE_Z(ZONE))THEN
         WRITE(*,*)MYID_OOC,': Internal error (23) in OOC ',
     $              PTRFAC(STEP_OOC(INODE)),IDEB_SOLVE_Z(ZONE)
         CALL CMUMPS_ABORT()
      ENDIF
      INODE_TO_POS(STEP_OOC(INODE))=CURRENT_POS_B(ZONE)
      IF(CURRENT_POS_B(ZONE).EQ.0)THEN
         WRITE(*,*)MYID_OOC,': Internal error (23b) in OOC '
         CALL CMUMPS_ABORT()
      ENDIF
      POS_IN_MEM(CURRENT_POS_B(ZONE))=INODE
      CURRENT_POS_B(ZONE)=CURRENT_POS_B(ZONE)-1
      POS_HOLE_B(ZONE)=POS_HOLE_B(ZONE)-1
      END SUBROUTINE CMUMPS_607
      SUBROUTINE CMUMPS_608(A,LA,REQUESTED_SIZE,PTRFAC,
     $     NSTEPS,ZONE,IERR)
      IMPLICIT NONE
      INTEGER REQUESTED_SIZE,LA,NSTEPS,ZONE,IERR
      INTEGER PTRFAC(NSTEPS)
      COMPLEX A(LA)
      INTEGER J,I,TMP_NODE,FIRST_FREE,SIZE_HOLE,K,
     $     APOS_FIRST_FREE,NB_FREE,IPOS_FIRST_FREE
      INTEGER AREA_POINTER,FREE_HOLE_POS,FREE_HOLE_FLAG,FREE_HOLE,TMPP
      IERR=0
      IF(LRLU_SOLVE_T(ZONE).EQ.SIZE_SOLVE_Z(ZONE))THEN
         WRITE(*,*)MYID_OOC,': Internal error (24) in OOC '
         RETURN
      ENDIF
      AREA_POINTER=IDEB_SOLVE_Z(ZONE)
      SIZE_HOLE=0
      DO I=PDEB_SOLVE_Z(ZONE),CURRENT_POS_T(ZONE)-1
         IF((POS_IN_MEM(I).LE.0).AND.
     $        (POS_IN_MEM(I).GT.-((N_OOC+1)*NB_Z))) GOTO 666
         TMP_NODE=ABS(POS_IN_MEM(I))
         IF(TMP_NODE.GT.((N_OOC+1)*NB_Z))THEN
            TMP_NODE=TMP_NODE-((N_OOC+1)*NB_Z)
         ENDIF
         AREA_POINTER=AREA_POINTER+
     $        ABS(SIZE_OF_BLOCK(STEP_OOC(TMP_NODE)))
      ENDDO
 666  CONTINUE
      IF((I.EQ.CURRENT_POS_T(ZONE)-1).AND.
     $     (PDEB_SOLVE_Z(ZONE).NE.CURRENT_POS_T(ZONE)-1))THEN
         IF((POS_IN_MEM(I).GT.0).OR.
     $        (POS_IN_MEM(I).LT.-((N_OOC+1)*NB_Z)))THEN
         WRITE(*,*)MYID_OOC,': Internal error (25) in OOC ',
     &                      ': There are no free blocks ',
     $         'in CMUMPS_608',PDEB_SOLVE_Z(ZONE),
     $           CURRENT_POS_T(ZONE)
            CALL CMUMPS_ABORT()
         ENDIF
      ENDIF
      IF(POS_IN_MEM(I).EQ.0)THEN
         APOS_FIRST_FREE=AREA_POINTER
         FREE_HOLE_POS=AREA_POINTER
      ELSE
         TMP_NODE=ABS(POS_IN_MEM(I))
         APOS_FIRST_FREE=ABS(PTRFAC(STEP_OOC(TMP_NODE)))
      ENDIF
      IF(POS_IN_MEM(PDEB_SOLVE_Z(ZONE)).NE.0)THEN
         IF(POS_IN_MEM(PDEB_SOLVE_Z(ZONE)).LT.-((N_OOC+1)*NB_Z))THEN
            TMP_NODE=ABS(POS_IN_MEM(PDEB_SOLVE_Z(ZONE)))-
     $           ((N_OOC+1)*NB_Z)
            CALL CMUMPS_WAIT_REQUEST(IO_REQ(STEP_OOC(TMP_NODE)),IERR)
            REQ_ACT=REQ_ACT-1
            CALL CMUMPS_596(
     $           IO_REQ(STEP_OOC(TMP_NODE)),PTRFAC,NSTEPS)
         ELSE
            TMP_NODE=ABS(POS_IN_MEM(PDEB_SOLVE_Z(ZONE)))            
         ENDIF
         IF(ABS(PTRFAC(STEP_OOC(TMP_NODE))).NE.IDEB_SOLVE_Z(ZONE))THEN
            IF((POS_IN_MEM(I).NE.0).OR.(I.EQ.CURRENT_POS_T(ZONE)))THEN
               SIZE_HOLE=ABS(PTRFAC(STEP_OOC(TMP_NODE)))-
     $              IDEB_SOLVE_Z(ZONE)
            ENDIF
            APOS_FIRST_FREE=IDEB_SOLVE_Z(ZONE)
            IF(POS_IN_MEM(PDEB_SOLVE_Z(ZONE)).GT.0)THEN
               DO J=PDEB_SOLVE_Z(ZONE),I-1
                  TMP_NODE=POS_IN_MEM(J)
                  IF(TMP_NODE.LE.0)THEN
                     IF(TMP_NODE.LT.-((N_OOC+1)*NB_Z))THEN
                        TMP_NODE=ABS(POS_IN_MEM(J))-((N_OOC+1)*NB_Z)
                        CALL CMUMPS_WAIT_REQUEST(
     $                       IO_REQ(STEP_OOC(TMP_NODE)),IERR)
                        IF(IERR.LT.0)THEN
                           WRITE(*,*)MYID_OOC,': ',
     $                          ERR_STR_OOC(1:DIM_ERR_STR_OOC)
                           RETURN
                        ENDIF
                        REQ_ACT=REQ_ACT-1
                        CALL CMUMPS_596(
     $                       IO_REQ(STEP_OOC(TMP_NODE)),PTRFAC,NSTEPS)
                        TMP_NODE=POS_IN_MEM(J)
                     ELSE
                    WRITE(*,*)MYID_OOC,': Internal error (26) in OOC ',
     $                      ' CMUMPS_608',TMP_NODE,
     $                       J,I-1,(N_OOC+1)*NB_Z
                        CALL CMUMPS_ABORT()
                     ENDIF
                  ENDIF
                  DO K=1,SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
                     A(APOS_FIRST_FREE+K-1)=
     $                    A(PTRFAC(STEP_OOC(TMP_NODE))+K-1)
                  ENDDO
                  PTRFAC(STEP_OOC(TMP_NODE))=APOS_FIRST_FREE
                  APOS_FIRST_FREE=APOS_FIRST_FREE+
     $                 SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
               ENDDO
            ENDIF
         ENDIF
      ENDIF
      NB_FREE=0
      FREE_HOLE=0
      FREE_HOLE_FLAG=0
      DO J=I,CURRENT_POS_T(ZONE)-1
         TMP_NODE=ABS(POS_IN_MEM(J))
         IF(POS_IN_MEM(J).GT.0)THEN
            DO K=1,SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
               A(APOS_FIRST_FREE+K-1)=A(PTRFAC(STEP_OOC(TMP_NODE))+K-1)
            ENDDO
            IF(FREE_HOLE_FLAG.EQ.1)THEN
               FREE_HOLE=ABS(PTRFAC(STEP_OOC(TMP_NODE)))-
     $              FREE_HOLE_POS
               FREE_HOLE_FLAG=0
               SIZE_HOLE=SIZE_HOLE+FREE_HOLE               
            ENDIF
            FREE_HOLE_POS=ABS(PTRFAC(STEP_OOC(TMP_NODE)))+
     $           SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
            PTRFAC(STEP_OOC(TMP_NODE))=APOS_FIRST_FREE
            APOS_FIRST_FREE=APOS_FIRST_FREE+
     $           SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
         ELSE
            IF(POS_IN_MEM(J).LT.-((N_OOC+1)*NB_Z))THEN               
               TMP_NODE=TMP_NODE-((N_OOC+1)*NB_Z)
               CALL CMUMPS_WAIT_REQUEST(IO_REQ(STEP_OOC(TMP_NODE)),IERR)
               IF(IERR.LT.0)THEN
                  WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
                  RETURN
               ENDIF
               REQ_ACT=REQ_ACT-1
               CALL CMUMPS_596(
     $              IO_REQ(STEP_OOC(TMP_NODE)),PTRFAC,NSTEPS)
               DO K=1,SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
                  A(APOS_FIRST_FREE+K-1)=
     $                 A(PTRFAC(STEP_OOC(TMP_NODE))+K-1)
               ENDDO
               IF(FREE_HOLE_FLAG.EQ.1)THEN
                  FREE_HOLE=ABS(PTRFAC(STEP_OOC(TMP_NODE)))-
     $                 FREE_HOLE_POS
                  FREE_HOLE_FLAG=0
                  SIZE_HOLE=SIZE_HOLE+FREE_HOLE
               ENDIF
               FREE_HOLE_POS=ABS(PTRFAC(STEP_OOC(TMP_NODE)))+
     $              SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
               PTRFAC(STEP_OOC(TMP_NODE))=APOS_FIRST_FREE
               APOS_FIRST_FREE=APOS_FIRST_FREE+
     $              SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
            ELSEIF(POS_IN_MEM(J).EQ.0)THEN
               FREE_HOLE_FLAG=1
               NB_FREE=NB_FREE+1
            ELSE
               NB_FREE=NB_FREE+1
               IF(FREE_HOLE_FLAG.EQ.1)THEN
                  FREE_HOLE=ABS(PTRFAC(STEP_OOC(TMP_NODE)))-
     $                 FREE_HOLE_POS
                  FREE_HOLE_FLAG=0
                  SIZE_HOLE=SIZE_HOLE+FREE_HOLE
               ENDIF
               FREE_HOLE_POS=ABS(PTRFAC(STEP_OOC(TMP_NODE)))+
     $              SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
               SIZE_HOLE=SIZE_HOLE+SIZE_OF_BLOCK(STEP_OOC(TMP_NODE))
               PTRFAC(STEP_OOC(ABS(POS_IN_MEM(J))))=-77777
            ENDIF
         ENDIF
      ENDDO
      IF(FREE_HOLE_FLAG.EQ.1)THEN
         FREE_HOLE=POSFAC_SOLVE(ZONE)-FREE_HOLE_POS
         FREE_HOLE_FLAG=0
         SIZE_HOLE=SIZE_HOLE+FREE_HOLE
      ENDIF
      IPOS_FIRST_FREE=I
      DO J=I,CURRENT_POS_T(ZONE)-1
         IF(POS_IN_MEM(J).LT.0)THEN
            TMP_NODE=ABS(POS_IN_MEM(J))
            INODE_TO_POS(STEP_OOC(TMP_NODE))=0
            POS_IN_MEM(J)=0
          ELSEIF(POS_IN_MEM(J).GT.0)THEN
             TMP_NODE=ABS(POS_IN_MEM(J))
             POS_IN_MEM(IPOS_FIRST_FREE)=POS_IN_MEM(J)
             INODE_TO_POS(STEP_OOC(TMP_NODE))=IPOS_FIRST_FREE
             IPOS_FIRST_FREE=IPOS_FIRST_FREE+1
         ENDIF
      ENDDO
 777  CONTINUE
      LRLU_SOLVE_T(ZONE)=LRLU_SOLVE_T(ZONE)+SIZE_HOLE
      POSFAC_SOLVE(ZONE)=POSFAC_SOLVE(ZONE)-SIZE_HOLE
      CURRENT_POS_T(ZONE)=CURRENT_POS_T(ZONE)-NB_FREE
      POS_HOLE_T(ZONE)=CURRENT_POS_T(ZONE)
      LRLU_SOLVE_B(ZONE)=0
      POS_HOLE_B(ZONE)=-9999
      CURRENT_POS_B(ZONE)=-9999
      LRLU_SOLVE_B(ZONE)=0
      IF(LRLU_SOLVE_T(ZONE).NE.LRLUS_SOLVE(ZONE))THEN
         WRITE(*,*)MYID_OOC,': Internal error (27) in OOC ',
     &                 LRLU_SOLVE_T(ZONE),
     $                 LRLUS_SOLVE(ZONE)
         CALL CMUMPS_ABORT()
      ENDIF
      LRLU_SOLVE_T(ZONE)=LRLUS_SOLVE(ZONE)
      IF(LRLUS_SOLVE(ZONE).LT.0)THEN
         WRITE(*,*)MYID_OOC,': Internal error (28) in OOC ',
     &                      ' LRLUS_SOLVE must be (4) > 0'
         CALL CMUMPS_ABORT()
      ENDIF
      IF(POSFAC_SOLVE(ZONE).LT.IDEB_SOLVE_Z(ZONE))THEN
         WRITE(*,*)MYID_OOC,': Internal error (29) in OOC ',
     $        POSFAC_SOLVE(ZONE),IDEB_SOLVE_Z(ZONE)
         CALL CMUMPS_ABORT()
      ENDIF
      IF(POSFAC_SOLVE(ZONE).NE.(IDEB_SOLVE_Z(ZONE)+SIZE_SOLVE_Z(ZONE)-
     $     LRLUS_SOLVE(ZONE)))THEN
         WRITE(*,*)MYID_OOC,': Internal error (30) in OOC ',
     &                      ' Problem avec debut POSFAC_SOLVE',
     $        POSFAC_SOLVE(ZONE),(SIZE_SOLVE_Z(ZONE)-
     $     LRLUS_SOLVE(ZONE))+IDEB_SOLVE_Z(ZONE),LRLUS_SOLVE(ZONE)
         CALL CMUMPS_ABORT()
      ENDIF      
      IF(POSFAC_SOLVE(ZONE).GT.
     $     (IDEB_SOLVE_Z(ZONE)+SIZE_SOLVE_Z(ZONE)-1))THEN
         WRITE(*,*)MYID_OOC,': Internal error (31) in OOC ',
     $        POSFAC_SOLVE(ZONE),IDEB_SOLVE_Z(ZONE)+
     $        SIZE_SOLVE_Z(ZONE)-1
         CALL CMUMPS_ABORT()
      ENDIF
      RETURN
      END SUBROUTINE CMUMPS_608
      SUBROUTINE CMUMPS_580(IERR)
      IMPLICIT NONE
      INTEGER IERR
      IERR=0
      IF(.NOT.WITH_BUF)THEN
         RETURN
      ENDIF
      CALL DB_DO_IO_AND_CHANGE_HBUF(IERR)
      END SUBROUTINE CMUMPS_580
      SUBROUTINE CMUMPS_581()
      IMPLICIT NONE
      IS_INIT_CALLED=.FALSE.
      END SUBROUTINE CMUMPS_581
      SUBROUTINE CMUMPS_609(INODE,PTRFAC,NSTEPS,FLAG)
      IMPLICIT NONE
      INTEGER INODE,NSTEPS,FLAG
      INTEGER PTRFAC(NSTEPS)
      INTEGER ZONE
      IF((FLAG.LT.0).OR.(FLAG.GT.1))THEN
         WRITE(*,*)MYID_OOC,': Internal error (32) in OOC ',
     $        ' CMUMPS_609'
         CALL CMUMPS_ABORT()
      ENDIF
      CALL CMUMPS_610(PTRFAC(STEP_OOC(INODE)),ZONE)
      IF(LRLUS_SOLVE(ZONE).LT.0)THEN
         WRITE(*,*)MYID_OOC,': Internal error (33) in OOC ',
     &                      ' LRLUS_SOLVE must be (5) ++ > 0'
         CALL CMUMPS_ABORT()
      ENDIF      
      IF(FLAG.EQ.0)THEN
         LRLUS_SOLVE(ZONE)=LRLUS_SOLVE(ZONE)+
     $        SIZE_OF_BLOCK(STEP_OOC(INODE))
      ELSE
         LRLUS_SOLVE(ZONE)=LRLUS_SOLVE(ZONE)-
     $        SIZE_OF_BLOCK(STEP_OOC(INODE))         
      ENDIF
      IF(LRLUS_SOLVE(ZONE).LT.0)THEN
         WRITE(*,*)MYID_OOC,': Internal error (34) in OOC ',
     &                      ' LRLUS_SOLVE must be (5) > 0'
         CALL CMUMPS_ABORT()
      ENDIF
      END SUBROUTINE CMUMPS_609
      SUBROUTINE CMUMPS_610(ADDR,ZONE)
      IMPLICIT NONE
      INTEGER ADDR,ZONE
      INTEGER I
      I=1
      DO WHILE (I.LE.NB_Z)
         IF(ADDR.LT.IDEB_SOLVE_Z(I))THEN
            EXIT
         ENDIF
         I=I+1
      ENDDO
      ZONE=I-1
      END SUBROUTINE CMUMPS_610
      FUNCTION CMUMPS_SOLVE_IS_END_REACHED()
      IMPLICIT NONE
      LOGICAL CMUMPS_SOLVE_IS_END_REACHED
      CMUMPS_SOLVE_IS_END_REACHED=.FALSE.
      IF(SOLVE_STEP.EQ.0)THEN
         IF(CUR_POS_SEQUENCE.GT.TOTAL_NB_OOC_NODES)THEN
            CMUMPS_SOLVE_IS_END_REACHED=.TRUE.
         ENDIF
      ELSEIF(SOLVE_STEP.EQ.1)THEN
         IF(CUR_POS_SEQUENCE.LT.1)THEN
            CMUMPS_SOLVE_IS_END_REACHED=.TRUE.
         ENDIF
      ENDIF
      RETURN
      END FUNCTION CMUMPS_SOLVE_IS_END_REACHED
      SUBROUTINE CMUMPS_611(ZONE,A,LA,PTRFAC,NSTEPS,IERR)
      IMPLICIT NONE
      INTEGER NSTEPS,LA,ZONE,IERR
      COMPLEX A(LA)
      INTEGER PTRFAC(NSTEPS)
      INTEGER FLAG,TMP_FLAG,SIZE,DEST,POS_SEQ,NEEDED_SIZE,TMP_NODE,
     $     NB_NODES
      IERR=0
      TMP_FLAG=0
      FLAG=0
      IF(CMUMPS_SOLVE_IS_END_REACHED())THEN
         RETURN
      ENDIF
      IF(SOLVE_STEP.EQ.0)THEN
         IF(CUR_POS_SEQUENCE.LE.TOTAL_NB_OOC_NODES)THEN
            TMP_NODE=OOC_INODE_SEQUENCE(CUR_POS_SEQUENCE)
            DO WHILE(SIZE_OF_BLOCK(STEP_OOC(TMP_NODE)).GT.
     $           SIZE_SOLVE_Z(ZONE))
               CUR_POS_SEQUENCE=CUR_POS_SEQUENCE+1
               IF(CMUMPS_SOLVE_IS_END_REACHED())THEN
                  RETURN
               ENDIF               
               TMP_NODE=OOC_INODE_SEQUENCE(CUR_POS_SEQUENCE)
            ENDDO
            NEEDED_SIZE=MAX(MIN_SIZE_READ,
     $           SIZE_OF_BLOCK(STEP_OOC(TMP_NODE)))
         ELSE
            NEEDED_SIZE=MIN_SIZE_READ
         ENDIF
      ELSEIF(SOLVE_STEP.EQ.1)THEN
         IF(CUR_POS_SEQUENCE.GE.1)THEN
            TMP_NODE=OOC_INODE_SEQUENCE(CUR_POS_SEQUENCE)
            DO WHILE(SIZE_OF_BLOCK(STEP_OOC(TMP_NODE)).GT.
     $           SIZE_SOLVE_Z(ZONE))
               CUR_POS_SEQUENCE=CUR_POS_SEQUENCE-1
               IF(CMUMPS_SOLVE_IS_END_REACHED())THEN
                  RETURN
               ENDIF               
               TMP_NODE=OOC_INODE_SEQUENCE(CUR_POS_SEQUENCE)
            ENDDO
            NEEDED_SIZE=MAX(MIN_SIZE_READ,
     $           SIZE_OF_BLOCK(STEP_OOC(TMP_NODE)))
         ELSE
            NEEDED_SIZE=MIN_SIZE_READ
         ENDIF
      ENDIF
      IF(LRLUS_SOLVE(ZONE).LT.NEEDED_SIZE)THEN
         RETURN
      ELSEIF((LRLU_SOLVE_T(ZONE).LT.NEEDED_SIZE).AND.
     $        (LRLU_SOLVE_B(ZONE).LT.NEEDED_SIZE).AND.
     $        (LRLUS_SOLVE(ZONE).LT.0.5*SIZE_SOLVE_Z(ZONE)))THEN
         RETURN
      ENDIF
      IF((LRLU_SOLVE_T(ZONE).GT.NEEDED_SIZE).AND.(SOLVE_STEP.EQ.0))THEN
         FLAG=1
      ELSE
         IF(SOLVE_STEP.EQ.0)THEN
            CALL CMUMPS_604(A,FACT_AREA_SIZE,
     $           NEEDED_SIZE,PTRFAC,NSTEPS,ZONE,TMP_FLAG,IERR)
            FLAG=1
            IF(TMP_FLAG.EQ.0)THEN
               CALL CMUMPS_605(A,FACT_AREA_SIZE,
     $              NEEDED_SIZE,PTRFAC,NSTEPS,ZONE,TMP_FLAG,IERR)
               FLAG=0
            ENDIF
         ELSE
            CALL CMUMPS_605(A,FACT_AREA_SIZE,
     $           NEEDED_SIZE,PTRFAC,NSTEPS,ZONE,TMP_FLAG,IERR)
            FLAG=0
            IF(TMP_FLAG.EQ.0)THEN
               CALL CMUMPS_604(A,FACT_AREA_SIZE,
     $              NEEDED_SIZE,PTRFAC,NSTEPS,ZONE,TMP_FLAG,IERR)
               FLAG=1
            ENDIF
         ENDIF
         IF(TMP_FLAG.EQ.0)THEN
            CALL CMUMPS_608(A,FACT_AREA_SIZE,
     $           NEEDED_SIZE,PTRFAC,NSTEPS,ZONE,IERR)
            FLAG=1
         ENDIF
      ENDIF
      CALL CMUMPS_602(ZONE,SIZE,DEST,POS_SEQ,
     $     NB_NODES,FLAG,PTRFAC,NSTEPS)
      IF(SIZE.EQ.0)THEN
         RETURN
      ENDIF
      NB_ZONE_REQ=NB_ZONE_REQ+1
      SIZE_ZONE_REQ=SIZE_ZONE_REQ+SIZE
      REQ_ACT=REQ_ACT+1
      CALL CMUMPS_595(A(DEST),DEST,SIZE,ZONE,PTRFAC,NSTEPS,
     $     POS_SEQ,NB_NODES,FLAG,IERR)
      IF(IERR.LT.0)THEN
         RETURN
      ENDIF
      END SUBROUTINE CMUMPS_611
      SUBROUTINE CMUMPS_602(ZONE,SIZE,DEST,POS_SEQ,
     $     NB_NODES,FLAG,PTRFAC,NSTEPS)
      IMPLICIT NONE
      INTEGER ZONE,SIZE,DEST,FLAG,POS_SEQ,NSTEPS
      INTEGER PTRFAC(NSTEPS)
      INTEGER I,J,LAST,TMP_NUM_FILE,START_NODE,MAX_SIZE,K,TMP,MAX_NB,
     $     NB_NODES
      LOGICAL ALREADY
      IF(CMUMPS_SOLVE_IS_END_REACHED())THEN
         SIZE=0
         RETURN
      ENDIF
      IF(FLAG.EQ.0)THEN
         MAX_SIZE=LRLU_SOLVE_B(ZONE)
         MAX_NB=MAX(0,CURRENT_POS_B(ZONE)-PDEB_SOLVE_Z(ZONE)+1)
      ELSEIF(FLAG.EQ.1)THEN
         MAX_SIZE=LRLU_SOLVE_T(ZONE)
         MAX_NB=MAX_NB_NODES_FOR_ZONE
      ELSE
         WRITE(*,*)MYID_OOC,': Internal error (35) in OOC ',
     &                      ' Unknown Flag value in ',
     $         ' CMUMPS_602',FLAG
         CALL CMUMPS_ABORT()
      ENDIF
      I=CUR_POS_SEQUENCE
      START_NODE=OOC_INODE_SEQUENCE(I)
      TMP_NUM_FILE=NUM_FILE(STEP_OOC(START_NODE))
      ALREADY=.FALSE.
      NB_NODES=0
      IF(ZONE.EQ.NB_Z)THEN
         SIZE=SIZE_OF_BLOCK(STEP_OOC(START_NODE))
      ELSE
         J=0
         IF(FLAG.EQ.0)THEN
            K=0
         ELSEIF(FLAG.EQ.1)THEN
            K=CURRENT_POS_T(ZONE)-PDEB_SOLVE_Z(ZONE)            
         ENDIF
         IF(SOLVE_STEP.EQ.0)THEN
            I=CUR_POS_SEQUENCE
            DO WHILE(I.LE.TOTAL_NB_OOC_NODES)
               IF(SIZE_OF_BLOCK(STEP_OOC(OOC_INODE_SEQUENCE(I)))
     $              .NE.0)THEN
                  EXIT
               ENDIF
               I=I+1
            ENDDO
            CUR_POS_SEQUENCE=MIN(I,TOTAL_NB_OOC_NODES)
            I=CUR_POS_SEQUENCE
            DO WHILE((J.LE.MAX_SIZE).AND.(I.LE.TOTAL_NB_OOC_NODES).AND.
     $           (K.LT.MAX_NB))
               IF(NUM_FILE(STEP_OOC(OOC_INODE_SEQUENCE(I))).NE.
     $              TMP_NUM_FILE)THEN
                  EXIT
               ENDIF
               IF((INODE_TO_POS(STEP_OOC(OOC_INODE_SEQUENCE(I)))
     $              .NE.0).OR.
     $              (IO_REQ(STEP_OOC(OOC_INODE_SEQUENCE(I))).GE.0))THEN
                  IF(.NOT.ALREADY)THEN
                     CUR_POS_SEQUENCE=CUR_POS_SEQUENCE+1
                     I=I+1
                     CYCLE
                  ELSE
                     EXIT
                  ENDIF
               ENDIF
               ALREADY=.TRUE.
               LAST=SIZE_OF_BLOCK(STEP_OOC(OOC_INODE_SEQUENCE(I)))
               J=J+LAST
               I=I+1
               K=K+1
               NB_NODES=NB_NODES+1
            ENDDO
            IF(J.GT.MAX_SIZE)THEN
               SIZE=J-LAST
               NB_NODES=NB_NODES-1
            ELSE
               SIZE=J
            ENDIF
            DO WHILE (CUR_POS_SEQUENCE+NB_NODES-1.GT.0)
               IF(SIZE_OF_BLOCK(STEP_OOC(
     $              OOC_INODE_SEQUENCE(CUR_POS_SEQUENCE+NB_NODES-1)))
     $              .NE.0)THEN
                  EXIT
               ENDIF
               NB_NODES=NB_NODES-1
            ENDDO
            POS_SEQ=CUR_POS_SEQUENCE
         ELSEIF(SOLVE_STEP.EQ.1)THEN
            DO WHILE(I.GE.1)
               IF(SIZE_OF_BLOCK(STEP_OOC(OOC_INODE_SEQUENCE(I)))
     $              .NE.0)THEN
                  EXIT
               ENDIF
               I=I-1
            ENDDO
            CUR_POS_SEQUENCE=MAX(I,1)
            I=CUR_POS_SEQUENCE
            DO WHILE((J.LE.MAX_SIZE).AND.(I.GE.1).AND.
     $           (K.LT.MAX_NB))
               IF(NUM_FILE(STEP_OOC(OOC_INODE_SEQUENCE(I))).NE.
     $              TMP_NUM_FILE)THEN
                  EXIT
               ENDIF
               IF((INODE_TO_POS(STEP_OOC(OOC_INODE_SEQUENCE(I)))
     $              .NE.0).OR.
     $              (IO_REQ(STEP_OOC(OOC_INODE_SEQUENCE(I))).GE.0))THEN
                  IF(.NOT.ALREADY)THEN
                     I=I-1
                     CUR_POS_SEQUENCE=CUR_POS_SEQUENCE-1
                     CYCLE
                  ELSE
                     EXIT
                  ENDIF
               ENDIF
               ALREADY=.TRUE.
               LAST=SIZE_OF_BLOCK(STEP_OOC(OOC_INODE_SEQUENCE(I)))
               J=J+LAST
               I=I-1
               K=K+1
               NB_NODES=NB_NODES+1
            ENDDO
            IF(J.GT.MAX_SIZE)THEN
               SIZE=J-LAST
               NB_NODES=NB_NODES-1
            ELSE
               SIZE=J
            ENDIF
            I=CUR_POS_SEQUENCE
            DO WHILE (I.GT.0)
               IF(SIZE_OF_BLOCK(STEP_OOC(
     $              OOC_INODE_SEQUENCE(I))).NE.0)THEN
                  EXIT
               ENDIF
               I=I-1
               NB_NODES=NB_NODES-1
            ENDDO
            POS_SEQ=CUR_POS_SEQUENCE-NB_NODES+1
         ENDIF
      ENDIF
      IF(FLAG.EQ.0)THEN
         DEST=IDEB_SOLVE_Z(ZONE)+LRLU_SOLVE_B(ZONE)-SIZE
      ELSE
         DEST=POSFAC_SOLVE(ZONE)
      ENDIF
      END SUBROUTINE CMUMPS_602
      SUBROUTINE CMUMPS_582(IERR)
      IMPLICIT NONE
      INTEGER SOLVE_OR_FACTO,IERR
      IERR=0
      IF(ALLOCATED(LRLUS_SOLVE))THEN
         DEALLOCATE(LRLUS_SOLVE)
      ENDIF
      IF(ALLOCATED(LRLU_SOLVE_T))THEN
         DEALLOCATE(LRLU_SOLVE_T)
      ENDIF
      IF(ALLOCATED(LRLU_SOLVE_B))THEN
         DEALLOCATE(LRLU_SOLVE_B)
      ENDIF
      IF(ALLOCATED(POSFAC_SOLVE))THEN
         DEALLOCATE(POSFAC_SOLVE)
      ENDIF
      IF(ALLOCATED(IDEB_SOLVE_Z))THEN
         DEALLOCATE(IDEB_SOLVE_Z)
      ENDIF
      IF(ALLOCATED(PDEB_SOLVE_Z))THEN
         DEALLOCATE(PDEB_SOLVE_Z)
      ENDIF
      IF(ALLOCATED(SIZE_SOLVE_Z))THEN
         DEALLOCATE(SIZE_SOLVE_Z)
      ENDIF
      IF(ALLOCATED(CURRENT_POS_T))THEN
         DEALLOCATE(CURRENT_POS_T)
      ENDIF
      IF(ALLOCATED(CURRENT_POS_B))THEN
         DEALLOCATE(CURRENT_POS_B)
      ENDIF
      IF(ALLOCATED(POS_HOLE_T))THEN
         DEALLOCATE(POS_HOLE_T)
      ENDIF
      IF(ALLOCATED(POS_HOLE_B))THEN
         DEALLOCATE(POS_HOLE_B)
      ENDIF
      IF(ALLOCATED(POS_IN_MEM))THEN
         DEALLOCATE(POS_IN_MEM)
      ENDIF
      IF(ALLOCATED(INODE_TO_POS))THEN
         DEALLOCATE(INODE_TO_POS)
      ENDIF
      IF(ALLOCATED(IO_REQ))THEN
         DEALLOCATE(IO_REQ)
      ENDIF
      IF(ALLOCATED(SIZE_OF_READ))THEN
         DEALLOCATE(SIZE_OF_READ)
      ENDIF
      IF(ALLOCATED(FIRST_POS_IN_READ))THEN
         DEALLOCATE(FIRST_POS_IN_READ)
      ENDIF
      IF(ALLOCATED(READ_DEST))THEN
         DEALLOCATE(READ_DEST)
      ENDIF
      IF(ALLOCATED(READ_MNG))THEN
         DEALLOCATE(READ_MNG)
      ENDIF
      IF(ALLOCATED(REQ_TO_ZONE))THEN
         DEALLOCATE(REQ_TO_ZONE)
      ENDIF
      IF(ALLOCATED(REQ_ID))THEN
         DEALLOCATE(REQ_ID)
      ENDIF
      SOLVE_OR_FACTO=1
      CALL CMUMPS_CLEAN_IO_DATA_C(MYID_OOC,SOLVE_OR_FACTO,IERR)
      END SUBROUTINE CMUMPS_582
      SUBROUTINE CMUMPS_612(PTRFAC,NSTEPS)
      IMPLICIT NONE
      INTEGER NSTEPS
      INTEGER PTRFAC(NSTEPS)
      INTEGER I,TMP,ZONE,SAVE_PTR
      IF(SOLVE_STEP.EQ.0)THEN
         DO I=1,TOTAL_NB_OOC_NODES
            TMP=INODE_TO_POS(STEP_OOC(OOC_INODE_SEQUENCE(I)))
            IF(TMP.EQ.0)THEN
               EXIT
            ELSEIF(TMP.LT.0)THEN
               IF(TMP.GT.-(N_OOC+1)*NB_Z)THEN
                  SAVE_PTR=PTRFAC(STEP_OOC(OOC_INODE_SEQUENCE(I)))
                  PTRFAC(STEP_OOC(OOC_INODE_SEQUENCE(I)))=ABS(SAVE_PTR)
                  CALL CMUMPS_600(OOC_INODE_SEQUENCE(I),
     $                 ZONE,PTRFAC,NSTEPS)
                  PTRFAC(STEP_OOC(OOC_INODE_SEQUENCE(I)))=SAVE_PTR
                  IF(ZONE.EQ.NB_Z)THEN
                     IF(.NOT.((OOC_INODE_SEQUENCE(I).EQ.KEEP_OOC(38))
     $                    .AND.(KEEP_OOC(38).NE.0)))THEN
                        EXIT
                     ENDIF
                  ENDIF
                  CALL CMUMPS_599(
     $                 OOC_INODE_SEQUENCE(I),PTRFAC,NSTEPS)
               ENDIF
            ENDIF
         ENDDO
         CUR_POS_SEQUENCE=I
      ELSE
         DO I=TOTAL_NB_OOC_NODES,1,-1
            TMP=INODE_TO_POS(STEP_OOC(OOC_INODE_SEQUENCE(I)))
            IF(TMP.EQ.0)THEN
               EXIT
            ELSEIF(TMP.LT.0)THEN
               IF(TMP.GT.-(N_OOC+1)*NB_Z)THEN
                  SAVE_PTR=PTRFAC(STEP_OOC(OOC_INODE_SEQUENCE(I)))
                  PTRFAC(STEP_OOC(OOC_INODE_SEQUENCE(I)))=ABS(SAVE_PTR)
                  CALL CMUMPS_600(OOC_INODE_SEQUENCE(I)
     $                 ,ZONE,
     $                 PTRFAC,NSTEPS)
                  PTRFAC(STEP_OOC(OOC_INODE_SEQUENCE(I)))=SAVE_PTR
                  IF(ZONE.EQ.NB_Z)THEN
                     IF(.NOT.((OOC_INODE_SEQUENCE(I).EQ.KEEP_OOC(38))
     $                    .AND.(KEEP_OOC(38).NE.0)))THEN
                        EXIT
                     ENDIF
                  ENDIF
                  CALL CMUMPS_599(
     $                 OOC_INODE_SEQUENCE(I),PTRFAC,NSTEPS)
               ENDIF
            ENDIF
         ENDDO
         CUR_POS_SEQUENCE=I
      ENDIF
      END SUBROUTINE CMUMPS_612
      SUBROUTINE CMUMPS_584(PTRFAC,NSTEPS)
      IMPLICIT NONE
      INTEGER NSTEPS
      INTEGER PTRFAC(NSTEPS)
      SOLVE_STEP=0
      CUR_POS_SEQUENCE=1
      CALL CMUMPS_612(PTRFAC,NSTEPS)
      END SUBROUTINE CMUMPS_584
      SUBROUTINE CMUMPS_583(PTRFAC,NSTEPS)
      IMPLICIT NONE
      INTEGER NSTEPS
      INTEGER PTRFAC(NSTEPS)
      SOLVE_STEP=MOD(SOLVE_STEP+1,2)
      IF(SOLVE_STEP.EQ.0)THEN
         CUR_POS_SEQUENCE=1
      ELSEIF(SOLVE_STEP.EQ.1)THEN
         CUR_POS_SEQUENCE=TOTAL_NB_OOC_NODES
      ELSE
         WRITE(*,*)MYID_OOC,': Internal error (36) in OOC ',
     $        ' CMUMPS_583' 
         CALL CMUMPS_ABORT()
      ENDIF
      CALL CMUMPS_612(PTRFAC,NSTEPS)
      END SUBROUTINE CMUMPS_583
      SUBROUTINE CMUMPS_613(id)
      USE CMUMPS_STRUC_DEF
      IMPLICIT NONE
      TYPE(CMUMPS_STRUC), TARGET :: id
      INTEGER I,DIM,IERR,J
      CHARACTER*1 TMP_NAME(150)
      EXTERNAL CMUMPS_OOC_GET_NB_FILES,CMUMPS_OOC_GET_FILE_NAME
      IERR=0
      CALL CMUMPS_OOC_GET_NB_FILES(I)
      id%OOC_NB_FILES=I
      IF(ASSOCIATED(id%OOC_FILE_NAMES))THEN
         DEALLOCATE(id%OOC_FILE_NAMES)
         NULLIFY(id%OOC_FILE_NAMES)
      ENDIF
      ALLOCATE(id%OOC_FILE_NAMES(id%OOC_NB_FILES,150),stat=IERR)
      IF (IERR > 0) THEN
         WRITE(*,*) 'PB allocation in CMUMPS_613'
         id%INFO(1) = -13
         id%INFO(2) = id%OOC_NB_FILES*150
         RETURN
      ENDIF
      IF(ASSOCIATED(id%OOC_FILE_NAME_LENGTH))THEN
         DEALLOCATE(id%OOC_FILE_NAME_LENGTH)
         NULLIFY(id%OOC_FILE_NAME_LENGTH)
      ENDIF
      ALLOCATE(id%OOC_FILE_NAME_LENGTH(id%OOC_NB_FILES),stat=IERR)
      IF (IERR > 0) THEN
         WRITE(*,*) 'PB allocation in CMUMPS_613'
         id%INFO(1) = -13
         id%INFO(2) = id%OOC_NB_FILES
         RETURN
      ENDIF
      DO I=1,id%OOC_NB_FILES
         CALL CMUMPS_OOC_GET_FILE_NAME(I,DIM, TMP_NAME(1))
         DO J=1,DIM+1
            id%OOC_FILE_NAMES(I,J)=TMP_NAME(J)
         ENDDO
         id%OOC_FILE_NAME_LENGTH(I)=DIM+1
      ENDDO
      END SUBROUTINE CMUMPS_613
      SUBROUTINE CMUMPS_614(id)
      USE CMUMPS_STRUC_DEF
      IMPLICIT NONE
      TYPE(CMUMPS_STRUC), TARGET :: id
      CHARACTER*1 TMP_NAME(150)
      INTEGER I,J,K,L,DIM,NB_FILES,IERR
      INTEGER K211
      IERR=0
      NB_FILES=id%OOC_NB_FILES
      I=id%MYID
      J=id%OOC_NB_FILES
      K=id%KEEP(35)
      L=MOD(id%KEEP(204),3)
      K211=id%KEEP(211)
      CALL CMUMPS_OOC_ALLOC_POINTERS(NB_FILES,IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         id%INFO(1)=IERR
         RETURN
      ENDIF
      CALL CMUMPS_OOC_INIT_VARS(I,J,K,L,K211,IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         id%INFO(1)=IERR
         RETURN
      ENDIF
      DO I=1,id%OOC_NB_FILES
         DIM=id%OOC_FILE_NAME_LENGTH(I)
         DO J=1,DIM
            TMP_NAME(J)=id%OOC_FILE_NAMES(I,J)
         ENDDO
         CALL CMUMPS_OOC_SET_FILE_NAME(I,DIM,IERR,TMP_NAME(1))
         IF(IERR.LT.0)THEN
            WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
            id%INFO(1)=IERR
            RETURN
         ENDIF
      ENDDO
      CALL CMUMPS_OOC_START_LOW_LEVEL(IERR)
      IF(IERR.LT.0)THEN
         WRITE(*,*)MYID_OOC,': ',ERR_STR_OOC(1:DIM_ERR_STR_OOC)
         id%INFO(1)=IERR
         RETURN
      ENDIF
      END SUBROUTINE CMUMPS_614      
      SUBROUTINE CMUMPS_589(DEST,SRC)
      IMPLICIT NONE
      CHARACTER(LEN=150) SRC
      CHARACTER*1 DEST(150)
      INTEGER I
      DO I=1,LEN(TRIM(SRC))
         DEST(I)=SRC(I:I)
      ENDDO
      END SUBROUTINE CMUMPS_589
      END MODULE CMUMPS_OOC
