C PRMILU    SOURCE    GOUNAND   25/04/30    21:15:35     12258          
      SUBROUTINE PRMILU(KMORS,KISA,MATRIK,RXMILU,IMPR,IRET)
      IMPLICIT INTEGER(I-N)
      IMPLICIT REAL*8 (A-H,O-Z)
C***********************************************************************
C NOM         : PRMILU
C DESCRIPTION :
C     Calcul du préconditionneur MILU(0) d'une matrice Morse.
C     MILU(0) : Modified Incomplete LU factorization of level 0
C               appelée aussi Choleski ou Crout incomplet modifié !
C     Ici, c'est meme un MILU(0) relaxé (avec RXMILU)...
C
C     Le préconditionneur est une matrice stockée
C     au format MSR (Modified Sparse Row, stockage de l'inverse de la
C     diagonale) de meme profil que la matrice Morse (format CSR) qu'il
C     préconditionne.
C     Le profil et les valeurs du préconditionneur sont
C     stockés dans KIDMAT(6 et 7) (réutilisation de l'existant).
C
C     Ce sous-programme est en fait une interface à :
C       memilu
C     qui est en Fortran presque pur (pour raison de rapidité)
C     et effectue la construction proprement dite du
C     préconditionneur.
C
C  ATTENTION : pour une matrice A quelconque, la factorisation
C  ---------   MILU(0) peut ne pas exister (pivot nul) ou avoir
C              des pivots négatifs MEME SI la factorisation
C              complète de A existe et n'a que des pivots
C              positifs.
C
C
C LANGAGE     : ESOPE
C AUTEUR      : Stéphane GOUNAND (CEA/DRN/DMT/SEMT/TTMF)
C               mél : gounand@semt2.smts.cea.fr
C REFERENCE (bibtex-like) :
C  @BOOK{templates,
C        AUTHOR={R.Barrett, M.Berry, T.F.Chan, J.Demmel, J.Donato,
C                J.Dongarra, V.Eijkhout, R.Pozo, C.Romine,
C                H. Van der Vorst},
C        TITLE={Templates for the Solution of Linear Systems :
C               Building Blocks for Iterative Methods},
C        PUBLISHER={SIAM}, YEAR={1994}, ADDRESS={Philadelphia,PA} }
C  -> URL : http://www.netlib.org/templates/Templates.html
C***********************************************************************
C APPELES       : MEILU0
C APPELES (E/S) : ECMORS
C APPELE PAR    : KRES2
C***********************************************************************
C ENTREES            : MATRIK, RXMILU, IMPR
C ENTREES/SORTIES    : -
C SORTIES            : ILUM, ILUI (KIDMAT(6-7) dans MATRIK), IRET
C CODE RETOUR (IRET) : 0 si ok
C                     <0 si problème
C     MATRIK : pointeur sur segment MATRIK de l'include SMMATRIK
C              on pioche dedans les informations nécessaires
C              (différents pointeurs, nb. de ddl...)
C     RXMILU : type REAL*8.
C              facteur de relaxation (normalement compris
C              entre 0.D0 et 1.D0)
C              0.D0 : on se ramène à Choleski incomplet
C              1.D0 : on se ramène à MILU(0) non relaxé.
C     IMPR   : niveau d'impression
C     ILUM   : pointeur sur segment PMORS de l'include SMMATRIK
C              profil morse du préconditionneur ILU(0)
C              =KIDMAT(6)=KMORS=KIDMAT(4) dans MATRIK
C     ILUI   : pointeur sur segment IZA de l'include SMMATRIK
C              valeur du préconditionneur ILU(0)
C              =KIDMAT(7) dans MATRIK
C***********************************************************************
C VERSION    : v1, 01/04/98, version initiale
C HISTORIQUE : v1, 01/04/98, création
C HISTORIQUE : 09/02/98, on ne construit pas le préconditionneur s'il
C              existe déjà.
C HISTORIQUE : 20/12/99, interfaçage avec le nouveau memilu
C Le préconditionneur est stocké au format MSR (Modified Sparse Row)
C (voir la doc de Sparskit version 2+ (Youcef Saad))
C HISTORIQUE :
C HISTORIQUE :
C***********************************************************************
C Prière de PRENDRE LE TEMPS de compléter les commentaires
C en cas de modification de ce sous-programme afin de faciliter
C la maintenance !
C***********************************************************************
-INC PPARAM
-INC CCOPTIO
-INC SMMATRIK
-INC SMLENTI
      POINTEUR KMORS.PMORS
      POINTEUR KISA.IZA
      POINTEUR ILUM.PMORS
      POINTEUR ILUI.IZA
      POINTEUR IWORK.MLENTI
      REAL*8 RXMILU
C***
      IRET=0
      IF (IMPR.GT.5) WRITE(IOIMP,*) 'Entrée dans prmilu'
C     On récupère les segments utiles
      SEGACT MATRIK
      ILUM=KIDMAT(6)
      ILUI=KIDMAT(7)
C     Le préconditionneur est-il déjà construit ?
      IF ((ILUM.EQ.0).OR.(ILUI.EQ.0)) THEN
C     La matrice Morse et son préconditionneur ont le meme
C     profil
         SEGACT KMORS
         N=KMORS.IA(/1)-1
         NNZ=KMORS.JA(/1)
         SEGACT KISA
         NTT=N-1
         NJA=NNZ+1
         SEGINI ILUM
         NBVA=NNZ+1
         SEGINI ILUI
         JG=N
         SEGINI IWORK
C     Les boucles sont en Fortran pur
         CALL MEMILU(N,NNZ,KISA.A,KMORS.JA,KMORS.IA,
     $        ILUI.A,ILUM.JA,ILUM.IA,
     $        IWORK.LECT,
     $        RXMILU,
     $        IMPR,IRET)
         SEGSUP IWORK
         IF (IRET.NE.0) GOTO 9999
C
C     On stocke la factorisation obtenue du préconditionneur
C
         SEGACT MATRIK*MOD
         KIDMAT(6)=ILUM
         KIDMAT(7)=ILUI
         SEGDES MATRIK
C
         IF (IMPR.GT.6) THEN
            WRITE(IOIMP,*) 'création de la matrice Morse'
            WRITE(IOIMP,*) 'de pointeurs',ILUM,'et',ILUI
            IF (IMPR.GT.8) THEN
               CALL ECMORS(ILUM,ILUI,(IMPR-1))
            ENDIF
         ENDIF
      ELSE
         IF (IMPR.GT.6) THEN
            WRITE(IOIMP,*) 'Le préconditionneur est déjà construit :'
            WRITE(IOIMP,*) 'ILUM=',ILUM,' et ILUI=',ILUI
            IF (IMPR.GT.8) THEN
               CALL ECMORS(ILUM,ILUI,(IMPR-1))
            ENDIF
         ENDIF
      ENDIF
*
*     Normal termination
*
      RETURN
*
* Format handling
*
*
* Error handling
*
 9999 CONTINUE
      WRITE(IOIMP,*) 'An error was detected in prmilu.eso'
      RETURN
*
*     End of PRMILU
*
      END
 
