*DECK SPHEQU
      SUBROUTINE SPHEQU(NBMIX2,IPTRK2,IFTRAK,IPMACR,IPFLX,CDOOR,NSPH,
     1 KSPH,MAXIT,MAXNBI,IBELL,EPSPH,IPRINT,NGCOND,NMERGE,ISCAT,NWGTH,
     2 NREG2,NUN2,MAT2,VOL2,KEY2,MERG2,ILK,CTITRE,SPH)
*
*-----------------------------------------------------------------------
*
*Purpose:
* calculation of the SPH factors for the homogenization of any geometry
* using a transport-transport or transport-diffusion equivalence
* technique. The macro-calculation can be performed using a standard
* solution door of Dragon.
*
*Copyright:
* Copyright (C) 2002 Ecole Polytechnique de Montreal
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version
*
*Author(s): A. Hebert
*
*Parameters: input
* NBMIX2  number of macro-mixtures. Equal to MAX(MAT2(IREG)) for
*         (IREG .le. NREG2).
* IPTRK2  pointer to the tracking of the macro-geometry (L_TRACK
*         signature).
* IFTRAK  unit number of the sequential binary tracking file.
* IPMACR  pointer to the reference macrolib (L_MACROLIB signature).
* IPFLX   pointer towards an initialization flux (L_FLUX signature).
* CDOOR   tracking operator used to track the macro-geometry.
* NSPH    type of SPH algorithm:
*         =2 homogeneous macro-calculation (non-iterative procedure
*            or Hebert-Benoist SPH-5 procedure);
*         =3 any type of pij macro-calculation;
*         =4 any type of diffusion, SN, PN or SPN macro-calculation;
* KSPH    type of SPH factor normalization:
*         <0 asymptotic normatization with respect to mixture -KSPH;
*         =1 average flux normalization;
*         =2 Selengut normalization using ALBS information;
*         =3 Selengut normalization using FD_B boundary fluxes;
*         =4 generalized Selengut normalization (EDF type);
*         =5 Selengut normalization with surface leakage.
*         The Hebert-Benoist procedure is used if NSPH=2 and KSPH=5.
* MAXIT   maximum number of SPH iterations.
* MAXNBI  acceptable number of SPH iterations with an increase in
*         convergence error before aborting.
* EPSPH   convergence criterion for stopping the SPH iterations.
* IBELL   Bell factor acceleration flag (0:off/1:on).
* IPRINT  print flag (equal to 0 for no print).
* NGCOND  number of condensed groups.
* NMERGE  number of merged regions (equal to 1 or to the number of
*         different flux components in the macro-calculation).
* ISCAT   scattering anisotropy in the reference set of cross sections
*         (=1: isotropic in LAB; =2: linearly-anisotropic in LAB).
* NWGTH   type of weighting for P1 cross section information:
*         = 0 P0; = 1 P1. P1-weighted SPH factors are computed if NWGTH
*         is greater than zero.
* NREG2   number of macro-regions (in the macro-calculation).
* NUN2    number of unknowns in a one-group macro-calculation.
* MAT2    mixture index per macro-region.
* VOL2    volume of macro-regions.
* KEY2    pointer to flux values in unknown vector.
* MERG2   index of merged macro-regions per macro-mixture.
* ILK     leakage switch.
* CTITRE  title.
*
*Parameters: output
* SPH     SPH homogenization factors.
*
*References(s):
*  A. Hebert, 'A Consistent Technique for the Pin-by-Pin Homogenization
*  of a Pressurized Water Reactor Assembly', Nucl. Sci. Eng., 113, 227
*  (1993).
*
*  A. Hebert and P. Benoist, 'A Consistent Technique for the Global
*  Homogenization of a Pressurized Water Reactor Assembly', Nucl. Sci.
*  Eng., 109, 360 (1991).
*
*  A. Hebert and G. Mathonniere, 'Development of a Third-Generation
*  Superhomogeneisation Method for the Homogenization of a
*  Pressurized Water Reactor Assembly', Nucl. Sci. Eng., 115, 129
*  (1993).
*
*  T. Courau, M. Cometto, E. Girardi, D. Couyras and N. Schwartz,
*  'Elements of Validation of Pin-by-Pin Calculations with the Future
*  EDF Calculation Scheme Based on APOLLO2 and COCAGNE Codes',
*  Proceedings of ICAPP '08 Anaheim, CA USA, June 8-12, 2008.
*
*-----------------------------------------------------------------------
*
      USE GANLIB
*----
*  SUBROUTINE ARGUMENTS
*----
      TYPE(C_PTR) IPTRK2,IPMACR,IPFLX
      INTEGER NBMIX2,IFTRAK,NSPH,KSPH,MAXIT,MAXNBI,IBELL,IPRINT,
     1 NGCOND,NMERGE,ISCAT,NWGTH,NREG2,NUN2,MAT2(NREG2),KEY2(NREG2),
     2 MERG2(NBMIX2)
      REAL VOL2(NREG2),SPH(NMERGE,NGCOND,NWGTH+1)
      LOGICAL ILK
      CHARACTER CDOOR*12,CTITRE*72
*----
*  LOCAL VARIABLES
*----
      PARAMETER(NSTATE=40)
      INTEGER IPAR(NSTATE)
      LOGICAL LNORM,LOK,LEXAC,LDIFF
      CHARACTER SUFF(2)*2
      DOUBLE PRECISION FLXTOT,VOLTOT
      TYPE(C_PTR) IPADF,IPSYS2,JPSYS2,JPFLX,KPSYS2
      INTEGER, ALLOCATABLE, DIMENSION(:) :: NPSYS
      REAL, ALLOCATABLE, DIMENSION(:) :: SIGMD,VOLMER,FACTOR
      REAL, ALLOCATABLE, DIMENSION(:,:) :: SIGMA,SIGMS,COURIN,COUROW,
     1 DIFF,FUNKNO,SUNKNO
      REAL, ALLOCATABLE, DIMENSION(:,:,:) :: SIGT,SIGW,FLXMER,ZLEAK
      REAL, ALLOCATABLE, DIMENSION(:,:,:,:) :: SUNMER
      DATA SUFF/'00','01'/
*----
*  SCRATCH STORAGE ALLOCATION
*----
      ALLOCATE(NPSYS(NGCOND))
      ALLOCATE(SIGMA(0:NBMIX2,ISCAT),SIGMS(0:NBMIX2,2),SIGMD(0:NBMIX2),
     1 COURIN(NGCOND,NWGTH+1),COUROW(NGCOND,NWGTH+1),VOLMER(NMERGE),
     2 SIGT(NMERGE,NGCOND,NWGTH+1),SIGW(NMERGE,NGCOND,ISCAT),
     3 FLXMER(NMERGE,NGCOND,NWGTH+1),DIFF(NMERGE,NGCOND),
     4 ZLEAK(NMERGE,NGCOND,NWGTH+1),SUNMER(NMERGE,NGCOND,NGCOND,ISCAT),
     5 FUNKNO(NUN2,NGCOND),SUNKNO(NUN2,NGCOND),FACTOR(NMERGE))
*----
*  CALCULATION OF THE REFERENCE MERGED/CONDENSED SET OF CROSS SECTIONS
*----
      CALL LCMGET(IPMACR,'STATE-VECTOR',IPAR)
      NL=IPAR(3)
      NIFISS=IPAR(4)
      ILEAKS=IPAR(9)
      CALL SPHMAC(IPMACR,IPRINT,NMERGE,NGCOND,ISCAT,NWGTH,NIFISS,
     1 ILEAKS,VOLMER,FLXMER,SUNMER,SIGT,SIGW,DIFF,ZLEAK)
*
      DO 10 INL=1,ISCAT
      DO 10 IGR=1,NGCOND
      DO 10 IKK=1,NMERGE
   10 SUNMER(IKK,IGR,IGR,INL)=SUNMER(IKK,IGR,IGR,INL)-SIGW(IKK,IGR,INL)
      LDIFF=.FALSE.
      NLF=0
      NANI=0
      IF((NSPH.EQ.4).AND.((CDOOR.EQ.'BIVAC').OR.(CDOOR.EQ.'TRIVAC')))
     > THEN
*        TRANSPORT-DIFFUSION EQUIVALENCE.
         IF(.NOT.C_ASSOCIATED(IPTRK2)) THEN
            CALL XABORT('SPHEQU: MACRO-TRACKING NOT DEFINED(1).')
         ENDIF
         CALL LCMGET(IPTRK2,'STATE-VECTOR',IPAR)
         IF(CDOOR.EQ.'BIVAC') THEN
            NLF=IPAR(14)
            NANI=IPAR(16)
         ELSE IF(CDOOR.EQ.'TRIVAC') THEN
            NLF=IPAR(30)
            NANI=IPAR(32)
         ENDIF
         LDIFF=(NLF.EQ.0).OR.(NANI.LT.0)
         NANI=ABS(NANI)
         IF(NANI.GT.ISCAT) CALL XABORT('SPHEQU: ISCAT OVERFLOW.')
         IF(LDIFF) THEN
           IF(ILEAKS.EQ.0) CALL XABORT('SPHEQU: UNABLE TO COMPUTE DIFF'
     >     //'USION COEFFICIENTS.')
           IF(NWGTH.NE.0) CALL XABORT('SPHEQU: P0W WEIGHTING EXPECTED.')
         ENDIF
      ENDIF
      IF(NLF.EQ.0) NANI=1
*----
*  RECOVER THE AVERAGED GAP AND ROW FLUXES FOR EDF-TYPE NORMALIZATION.
*----
      IF(KSPH.GE.2) THEN
         CALL LCMLEN(IPMACR,'ADF',ILONG,ITYLCM)
         IF(ILONG.EQ.0) THEN
            CALL LCMLIB(IPMACR)
            CALL XABORT('SPHEQU: NO ADF DIRECTORY IN THE MACROLIB.')
         ENDIF
         IPADF=LCMDID(IPMACR,'ADF')
      ENDIF
      DO 30 INL=1,NWGTH+1
      IF((KSPH.EQ.2).OR.(KSPH.EQ.5)) THEN
         CALL LCMLEN(IPADF,'ALBS'//SUFF(INL),ILONG,ITYLCM)
         IF(ILONG.EQ.0) CALL XABORT('SPHEQU: NO ALBS'//SUFF(INL)//' DI'
     >   //'RECTORY IN THE MACROLIB.')
         CALL LCMGET(IPADF,'ALBS'//SUFF(INL),COURIN(1,INL))
         IF(IPRINT.GT.3) THEN
           WRITE(6,'(/23H SPHEQU: VALUES OF ALBS,I2.2,13H PER MACRO-GR,
     >     8HOUPS ARE)') INL-1
           WRITE(6,'(1X,1P,10E13.5)') (COURIN(IGRCD,INL),IGRCD=1,NGCOND)
         ENDIF
      ELSE IF(KSPH.EQ.3) THEN
         CALL LCMLEN(IPADF,'FD_B'//SUFF(INL),ILONG,ITYLCM)
         IF(ILONG.EQ.0) CALL XABORT('SPHEQU: NO FD_B'//SUFF(INL)//' DI'
     >   //'RECTORY IN THE MACROLIB.')
         CALL LCMGET(IPADF,'FD_B'//SUFF(INL),COURIN(1,INL))
         IF(IPRINT.GT.3) THEN
           WRITE(6,'(/23H SPHEQU: VALUES OF FD_B,I2.2,13H PER MACRO-GR,
     >     8HOUPS ARE)') INL-1
           WRITE(6,'(1X,1P,10E13.5)') (COURIN(IGRCD,INL),IGRCD=1,NGCOND)
         ENDIF
      ELSE IF(KSPH.EQ.4) THEN
         CALL LCMLEN(IPADF,'FD_B'//SUFF(INL),ILONG,ITYLCM)
         IF(ILONG.EQ.0) CALL XABORT('SPHEQU: NO FD_B'//SUFF(INL)//' DI'
     >   //'RECTORY IN THE MACROLIB.')
         CALL LCMGET(IPADF,'FD_B'//SUFF(INL),COURIN(1,INL))
         CALL LCMLEN(IPADF,'FD_H'//SUFF(INL),ILONG,ITYLCM)
         IF(ILONG.EQ.0) CALL XABORT('SPHEQU: NO FD_H'//SUFF(INL)//' DI'
     >   //'RECTORY IN THE MACROLIB.')
         CALL LCMGET(IPADF,'FD_H'//SUFF(INL),COUROW(1,INL))
         IF(IPRINT.GT.3) THEN
           WRITE(6,'(/23H SPHEQU: VALUES OF FD_B,I2.2,13H PER MACRO-GR,
     >     8HOUPS ARE)') INL-1
           WRITE(6,'(1X,1P,10E13.5)') (COURIN(IGRCD,INL),IGRCD=1,NGCOND)
           WRITE(6,'(/23H SPHEQU: VALUES OF FD_H,I2.2,13H PER MACRO-GR,
     >     8HOUPS ARE)') INL-1
           WRITE(6,'(1X,1P,10E13.5)') (COUROW(IGRCD,INL),IGRCD=1,NGCOND)
         ENDIF
      ENDIF
   30 CONTINUE
*----
*  ITERATIVE STRATEGY USED TO COMPUTE THE SPH FACTORS
*----
      IPRIN2=MAX(0,IPRINT-5)
      CALL LCMOP(IPSYS2,'SPH$SYS',0,1,0)
      JPSYS2=LCMLID(IPSYS2,'GROUP',NGCOND)
      DO 330 INL=NWGTH+1,1,-1
*----
*  REMOVE DB2 LEAKAGE FROM SOURCES
*----
      IF(ILEAKS.NE.0) THEN
         DO 40 IGR=1,NGCOND
         DO 40 IKK=1,NMERGE
   40    SUNMER(IKK,IGR,IGR,INL)=SUNMER(IKK,IGR,IGR,INL)
     1                          -ZLEAK(IKK,IGR,INL)
      ENDIF
*----
*  SET SPH NORMALIZATION INFORMATION
*----
      IF(KSPH.LT.0) THEN
*        ASYMTTOTIC NORMALIZATION WITH RESPECT TO MIXTURE -KSPH.
         DO 120 IGR=1,NGCOND
         VOLTOT=0.0D0
         FLXTOT=0.0D0
         DO 110 IKK=1,NMERGE
         IF(IKK.EQ.-KSPH) THEN
            VOLTOT=VOLTOT+VOLMER(IKK)
            FLXTOT=FLXTOT+FLXMER(IKK,IGR,INL)*VOLMER(IKK)
         ENDIF
  110    CONTINUE
         IF(VOLTOT.EQ.0.0) CALL XABORT('SPHEQU: ASYMPTOTIC NORMALIZATI'
     >   //'ON FAILURE.')
         COURIN(IGR,INL)=REAL(FLXTOT/VOLTOT)
         CALL XDRSET(SPH(1,IGR,INL),NMERGE,1.0)
  120    CONTINUE
         IF(IPRINT.GT.3) THEN
            WRITE(6,910) SUFF(INL),(COURIN(IGR,INL),IGR=1,NGCOND)
            WRITE(6,'(/)')
         ENDIF
      ELSE IF(KSPH.EQ.1) THEN
*        AVERAGE FLUX NORMALIZATION.
         DO 135 IGR=1,NGCOND
         VOLTOT=0.0D0
         FLXTOT=0.0D0
         DO 130 IKK=1,NMERGE
         VOLTOT=VOLTOT+VOLMER(IKK)
  130    FLXTOT=FLXTOT+FLXMER(IKK,IGR,INL)*VOLMER(IKK)
         COURIN(IGR,INL)=REAL(FLXTOT/VOLTOT)
         CALL XDRSET(SPH(1,IGR,INL),NMERGE,1.0)
  135    CONTINUE
         IF(IPRINT.GT.3) THEN
            WRITE(6,910) SUFF(INL),(COURIN(IGR,INL),IGR=1,NGCOND)
            WRITE(6,'(/)')
         ENDIF
      ELSE IF((KSPH.EQ.2).OR.(KSPH.EQ.3).OR.(KSPH.EQ.5)) THEN
*        SELENGUT NORMALIZATION.
         DO 145 IGR=1,NGCOND
         VOLTOT=0.0D0
         FLXTOT=0.0D0
         DO 140 IKK=1,NMERGE
         VOLTOT=VOLTOT+VOLMER(IKK)
  140    FLXTOT=FLXTOT+FLXMER(IKK,IGR,INL)*VOLMER(IKK)
         FLXTOT=FLXTOT/VOLTOT
         DO 145 IKK=1,NMERGE
  145    SPH(IKK,IGR,INL)=REAL(FLXTOT)/COURIN(IGR,INL)
      ELSE IF(KSPH.EQ.4) THEN
*        GENERALIZED SELENGUT NORMALIZATION (EDF-TYPE).
         DO 148 IGR=1,NGCOND
         VOLTOT=0.0D0
         FLXTOT=0.0D0
         DO 146 IKK=1,NMERGE
         VOLTOT=VOLTOT+VOLMER(IKK)
  146    FLXTOT=FLXTOT+FLXMER(IKK,IGR,INL)*VOLMER(IKK)
         FLXTOT=FLXTOT/VOLTOT
         DO 147 IKK=1,NMERGE
  147    SPH(IKK,IGR,INL)=COUROW(IGR,INL)/COURIN(IGR,INL)
  148    COURIN(IGR,INL)=COURIN(IGR,INL)*REAL(FLXTOT)/COUROW(IGR,INL)
      ENDIF
      IF((NSPH.EQ.2).AND.(KSPH.NE.5)) GO TO 340
*----
*  SPH ITERATIONS.
*----
      ITER=0
      IF(C_ASSOCIATED(IPFLX)) THEN
        CALL LCMGET(IPFLX,'STATE-VECTOR',IPAR)
        IF(IPAR(1).NE.NGCOND) CALL XABORT('SPHEQU: INVALID NB OF GROUP'
     1  //'S IN THE INITIALIZATION FLUX.')
        IF(IPAR(2).NE.NUN2) CALL XABORT('SPHEQU: INVALID NB OF UNKNOWN'
     1  //'S IN THE INITIALIZATION FLUX.')
        JPFLX=LCMGID(IPFLX,'FLUX')
        DO 149 IGR=1,NGCOND
          CALL LCMGDL(JPFLX,IGR,FUNKNO(1,IGR))
  149   CONTINUE
        ITER=1
      ELSE IF((CDOOR.EQ.'BIVAC').OR.(CDOOR.EQ.'TRIVAC')) THEN
        DO 150 IGR=1,NGCOND
        CALL XDRSET(FUNKNO(1,IGR),NUN2,1.0)
  150   CONTINUE
      ELSE
        DO 155 IGR=1,NGCOND
        CALL XDRSET(FUNKNO(1,IGR),NUN2,0.0)
        DO 155 IREG=1,NREG2
        IMAT=MAT2(IREG)
        IF(IMAT.GT.0) FUNKNO(KEY2(IREG),IGR)=FLXMER(MERG2(IMAT),IGR,INL)
  155   CONTINUE
      ENDIF
      OLDERR=1.0
      NBIERR=0
  160 ITER=ITER+1
      IF(ITER.GE.MAXIT) THEN
        WRITE(6,'(/46H SPHEQU: MAX. NUMBER OF ITERATIONS IS REACHED.)')
        GO TO 320
      ENDIF
      ERROR=0.0
      ERR2=0.0
      DO 170 IREG=1,NREG2
      IF(MAT2(IREG).GT.NBMIX2) THEN
         CALL XABORT('SPHEQU: INVALID MACRO-MIXTURE INDEX.')
      ENDIF
  170 CONTINUE
*----
*  SET MACROSCOPIC CROSS SECTIONS IN THE IPSYS2 LCM OBJECT.
*----
      DO 210 IGR=1,NGCOND
      CALL XDRSET(SIGMS(0,1),(NBMIX2+1)*2,0.0)
      CALL XDRSET(SIGMA(0,1),(NBMIX2+1)*NANI,0.0)
      CALL XDRSET(SIGMD(0),NBMIX2+1,0.0)
      DO 180 IREG=1,NREG2
      IMAT=MAT2(IREG)
      IF(IMAT.EQ.0) GO TO 180
      IMERG=MERG2(IMAT)
      IF(LDIFF) SIGMD(IMAT)=DIFF(IMERG,IGR)*SPH(IMERG,IGR,INL)
      IF((INL.EQ.1).AND.(NWGTH.EQ.1)) THEN
*        PERFORM A LEAKAGE CORRECTION.
         DELTA=SIGT(IMERG,IGR,1)*SPH(IMERG,IGR,1)-SIGT(IMERG,IGR,2)*
     >   SPH(IMERG,IGR,2)
         SIGMA(IMAT,1)=SIGW(IMERG,IGR,1)*SPH(IMERG,IGR,1)-DELTA
         SIGMS(IMAT,1)=SIGT(IMERG,IGR,1)*SPH(IMERG,IGR,1)-DELTA
      ELSE
         SIGMA(IMAT,1)=SIGW(IMERG,IGR,INL)*SPH(IMERG,IGR,INL)
         SIGMS(IMAT,1)=SIGT(IMERG,IGR,INL)*SPH(IMERG,IGR,INL)
      ENDIF
  180 CONTINUE
      NPSYS(IGR)=IGR
      KPSYS2=LCMDIL(JPSYS2,IGR)
      CALL LCMPUT(KPSYS2,'DRAGON-TXSC',NBMIX2+1,2,SIGMS(0,1))
      CALL LCMPUT(KPSYS2,'DRAGON-S0XSC',NBMIX2+1,2,SIGMA(0,1))
      IF(LDIFF) THEN
         SIGMD(0)=1.0E10
         CALL LCMPUT(KPSYS2,'DRAGON-DIFF',NBMIX2+1,2,SIGMD(0))
      ENDIF
*----
*  TRANSPORT-PIJ EQUIVALENCE WITH BELL FACTOR ACCELERATION.
*----
      IF(IBELL.EQ.1) THEN
         LOK=(NSPH.EQ.3).OR.((NSPH.EQ.2).AND.(KSPH.EQ.5))
         LOK=LOK.AND.(NMERGE.EQ.NREG2)
         IF(.NOT.LOK) CALL XABORT('SPHEQU: THE BELL FACTOR ACCELERATIO'
     >   //'N TECHNIQUE IS NOT AVAILABLE.')
         IF(NUN2.NE.NREG2) CALL XABORT('SPHEQU: INVALID NUN2.')
         DO 200 IREG=1,NREG2
         IF(IREG.NE.KEY2(IREG)) CALL XABORT('SPHEQU: INVALID KEY2.')
  200    CONTINUE
         CALL SPHBEL(NGCOND,IGR,NMERGE,FLXMER(1,1,INL),
     1   SUNMER(1,1,IGR,INL),NREG2,NBMIX2,MAT2,VOL2,MERG2,
     2   SIGMA(0,1),SIGMS(0,1),SPH(1,IGR,INL),SUNKNO(1,IGR))
         CALL XDRSET(SIGMA(0,1),NBMIX2+1,0.0)
         CALL LCMPUT(KPSYS2,'DRAGON-S0XSC',NBMIX2+1,2,SIGMA(0,1))
      ENDIF
  210 CONTINUE
*----
*  ASSEMBLY OF PIJ OR SYSTEM MATRICES AT ITERATION ITER.
*----
      IF(.NOT.C_ASSOCIATED(IPTRK2)) THEN
         CALL XABORT('SPHEQU: MACRO-TRACKING NOT DEFINED.')
      ENDIF
      KNORM=1
      IPHASE=2
      IF(NSPH.EQ.4) IPHASE=1
      IF(IPHASE.EQ.2) THEN
         IPIJK=1
         LNORM=.FALSE.
         CALL DOORPV(CDOOR,JPSYS2,NPSYS,IPTRK2,IFTRAK,IPRIN2,NGCOND,
     >   NREG2,NBMIX2,NANI,MAT2,VOL2,KNORM,IPIJK,ILK,LNORM,CTITRE)
      ELSE
         CALL DOORAV(CDOOR,JPSYS2,NPSYS,IPTRK2,IFTRAK,IPRIN2,NGCOND,
     >   NREG2,NBMIX2,NANI,MAT2,VOL2,KNORM,ILK,CTITRE)
      ENDIF
*----
*  MACRO-FLUX CALCULATION AT ITERATION ITER.
*----
      IF(IBELL.EQ.1) THEN
*        TRANSPORT-PIJ EQUIVALENCE WITH BELL FACTOR ACCELERATION.
         CALL SPHTRA(JPSYS2,NPSYS,KSPH,NREG2,NGCOND,NBMIX2,MAT2,
     1   VOL2,COURIN(1,INL),SUNKNO,FUNKNO)
         GO TO 280
      ELSE IF((NSPH.EQ.4).AND.(CDOOR.EQ.'BIVAC')) THEN
         CALL SPHBIV(IPTRK2,JPSYS2,NPSYS,NREG2,NUN2,NMERGE,NGCOND,
     1   NBMIX2,MAT2,VOL2,KEY2,MERG2,SUNMER(1,1,1,INL),FLXMER(1,1,INL),
     2   SPH(1,1,INL),ITER,FUNKNO,SUNKNO)
      ELSE IF((NSPH.EQ.4).AND.(CDOOR.EQ.'TRIVAC')) THEN
         CALL SPHTRI(IPTRK2,JPSYS2,NPSYS,NREG2,NUN2,NMERGE,NGCOND,
     1   NBMIX2,MAT2,VOL2,KEY2,MERG2,SUNMER(1,1,1,INL),FLXMER(1,1,INL),
     2   SPH(1,1,INL),ITER,FUNKNO,SUNKNO)
      ELSE IF((NSPH.EQ.4).AND.(CDOOR.EQ.'SN')) THEN
*        TRANSPORT-SN EQUIVALENCE.
         CALL SPHSN(IPTRK2,NPSYS,NREG2,NUN2,NMERGE,NGCOND,NBMIX2,MAT2,
     1   VOL2,KEY2,MERG2,SUNMER(1,1,1,INL),FLXMER(1,1,INL),SPH(1,1,INL),
     2   ITER,FUNKNO,SUNKNO)
      ELSE
*        TRANSPORT-PIJ EQUIVALENCE.
         CALL SPHPIJ(NPSYS,NREG2,NUN2,NMERGE,NGCOND,NBMIX2,MAT2,VOL2,
     1   KEY2,MERG2,SUNMER(1,1,1,INL),FLXMER(1,1,INL),SPH(1,1,INL),
     2   ITER,FUNKNO,SUNKNO)
      ENDIF
*----
*  COMPUTE THE MACRO-FLUX USING THE VECTORIAL DOOR.
*----
      IDIR=0
      LEXAC=.FALSE.
      CALL DOORFV(CDOOR,JPSYS2,NPSYS,IPTRK2,IFTRAK,IPRIN2,NGCOND,NBMIX2,
     1 IDIR,NREG2,NUN2,IPHASE,LEXAC,MAT2,VOL2,KEY2,CTITRE,SUNKNO,FUNKNO)
*----
*  MACRO-FLUX NORMALIZATION.
*----
      IF(ILK) GO TO 280
      IF(KSPH.LT.0) THEN
*        ASYMTTOTIC NORMALIZATION WITH RESPECT TO MIXTURE -KSPH.
         IF(-KSPH.GT.NMERGE) CALL XABORT('SPHEQU: INVALID ASYMPTOTIC M'
     >   //'IXTURE SET.')
         DO 240 IGR=1,NGCOND
         IF(NPSYS(IGR).EQ.0) GO TO 240
         VOLTOT=0.0D0
         FLXTOT=0.0D0
         DO 220 IREG=1,NREG2
         IMAT=MAT2(IREG)
         IF(IMAT.EQ.0) GO TO 220
         IF(MERG2(IMAT).EQ.-KSPH) THEN
            VOLTOT=VOLTOT+VOL2(IREG)
            FLXTOT=FLXTOT+FUNKNO(KEY2(IREG),IGR)*VOL2(IREG)
         ENDIF
  220    CONTINUE
         IF(VOLTOT.GT.0) THEN
            FLXTOT=FLXTOT/VOLTOT
            FFF=COURIN(IGR,INL)/REAL(FLXTOT)
         ELSE
            FFF=1.0
         ENDIF
         IF(IPRIN2.GT.0) WRITE(6,960) IGR,FFF
         DO 230 IUN=1,NUN2
  230    FUNKNO(IUN,IGR)=FUNKNO(IUN,IGR)*FFF
  240    CONTINUE
      ELSE
*        AVERAGE OR SELENGUT FLUX NORMALIZATION.
         DO 270 IGR=1,NGCOND
         IF(NPSYS(IGR).EQ.0) GO TO 270
         VOLTOT=0.0D0
         FLXTOT=0.0D0
         DO 250 IREG=1,NREG2
         VOLTOT=VOLTOT+VOL2(IREG)
  250    FLXTOT=FLXTOT+FUNKNO(KEY2(IREG),IGR)*VOL2(IREG)
         FLXTOT=FLXTOT/VOLTOT
         IF(IPRIN2.GT.0) WRITE(6,960) IGR,COURIN(IGR,INL)/REAL(FLXTOT)
         DO 260 IUN=1,NUN2
  260    FUNKNO(IUN,IGR)=FUNKNO(IUN,IGR)*COURIN(IGR,INL)/REAL(FLXTOT)
  270    CONTINUE
      ENDIF
*----
*  COMPUTE THE IMPROVED SPH FACTORS.
*----
  280 DO 310 IGR=1,NGCOND
      IF(NPSYS(IGR).EQ.0) GO TO 310
      CALL XDRSET(VOLMER,NMERGE,0.0)
      CALL XDRSET(FACTOR,NMERGE,0.0)
      DO 290 IREG=1,NREG2
      IMAT=MAT2(IREG)
      IF(IMAT.EQ.0) GO TO 290
      IKK=MERG2(IMAT)
      VOLMER(IKK)=VOLMER(IKK)+VOL2(IREG)
      FACTOR(IKK)=FACTOR(IKK)+FUNKNO(KEY2(IREG),IGR)*VOL2(IREG)
  290 CONTINUE
      DO 300 IKK=1,NMERGE
      IF(VOLMER(IKK).EQ.0.0) GO TO 300
      FACTOR(IKK)=FACTOR(IKK)/VOLMER(IKK)
      SPHNEW=FLXMER(IKK,IGR,INL)/FACTOR(IKK)
      IF(SPHNEW.LT.0.0) THEN
         WRITE(6,980) IGR,IKK
         SPHNEW=1.0
      ENDIF
      ERRT=ABS((SPHNEW-SPH(IKK,IGR,INL))/SPHNEW)
      ERR2=ERR2+ERRT*ERRT
      ERROR=MAX(ERROR,ERRT)
      SPH(IKK,IGR,INL)=SPHNEW
  300 CONTINUE
      IF(IPRINT.GT.4) THEN
         WRITE(6,930) 'SPH'//SUFF(INL),IGR,(SPH(IKK,IGR,INL),IKK=1,
     >   NMERGE)
      ENDIF
      IF(IPRINT.GT.5) THEN
         WRITE(6,930) 'FUNKNO'//SUFF(INL),IGR,(FUNKNO(IUNK,IGR),
     >   IUNK=1,NUN2)
      ENDIF
  310 CONTINUE
      ERR2=SQRT(ERR2/(NMERGE*NGCOND))
      IF(IPRINT.GT.2) THEN
         WRITE(6,935) SUFF(INL),ITER,ERROR,ERR2
         IF(ERROR.GE.EPSPH) WRITE(6,940) ((IKK,IGR,SPH(IKK,IGR,INL),
     >   IKK=1,NMERGE),IGR=1,NGCOND)
      ENDIF
      IF(ERR2.LT.EPSPH) GO TO 320
      IF((ITER.GT.1).AND.(ERR2.GT.OLDERR)) THEN
         WRITE(6,970) ITER
         NBIERR=NBIERR+1
         IF(NBIERR.GE.MAXNBI) THEN
            WRITE(6,980) ITER
            GO TO 320
         ENDIF
      ENDIF
      OLDERR=ERR2
      GO TO 160
  320 WRITE(6,950) SUFF(INL),ITER
*----
*  RESET SOURCES TO NO DB2 LEAKAGE
*----
      IF(ILEAKS.NE.0) THEN
         DO 325 IGR=1,NGCOND
         DO 325 IKK=1,NMERGE
  325    SUNMER(IKK,IGR,IGR,INL)=SUNMER(IKK,IGR,IGR,INL)
     1                          +ZLEAK(IKK,IGR,INL)
      ENDIF
*
  330 CONTINUE
      CALL LCMCL(IPSYS2,2)
*----
*  SCRATCH STORAGE DEALLOCATION
*----
  340 DEALLOCATE(FACTOR,SUNKNO,FUNKNO,SUNMER,ZLEAK,DIFF,FLXMER,SIGW,
     1 SIGT,VOLMER,COUROW,COURIN,SIGMD,SIGMS,SIGMA)
      DEALLOCATE(NPSYS)
      RETURN
*
  910 FORMAT(/18H SPHEQU: AVERAGE P,A2,28H FLUXES PER MACRO-GROUPS ARE/
     > (1X,1P,10E13.5))
  930 FORMAT(/26H SPHEQU: VALUES OF VECTOR ,A,9H IN GROUP,I5,4H ARE/
     > (1X,1P,10E13.5))
  935 FORMAT(/15H SPHEQU: ORDER=,A2,4X,5HITER=,I3,4X,6HERROR=,1P,E10.3,
     > 1X,6HERR 2=,E10.3)
  940 FORMAT(4X,4HSPH(,I3,1H,,I3,2H)=,F9.5,:,4X,4HSPH(,I3,1H,,I3,2H)=,
     > F9.5,:,4X,4HSPH(,I3,1H,,I3,2H)=,F9.5,:,4X,4HSPH(,I3,1H,,I3,2H)=,
     > F9.5,:,4X,4HSPH(,I3,1H,,I3,2H)=,F9.5)
  950 FORMAT(/27H SPHEQU: CONVERGENCE OF SPH,A2,13H ALGORITHM IN,I5,
     > 12H ITERATIONS.)
  960 FORMAT(/43H SPHEQU: FLUX NORMALIZATION FACTOR IN GROUP,I4,1H=,1P,
     1 E13.5)
  970 FORMAT(1X,'Warning: oscillations in SPH at iteration ',i10)
  980 FORMAT(1X,'Warning: maximum of 3 error oscillations ',
     >'in SPH convergence reached at iteration ',i10)
      END
