*DECK MACOPT
      SUBROUTINE MACOPT(IPMAC,IPOPT)
*
*-----------------------------------------------------------------------
*
*Purpose:
* update a Macrolib using control variables from a L_OPTIMIZE object.
*
*Copyright:
* Copyright (C) 2012 Ecole Polytechnique de Montreal.
*
*Author(s): A. Hebert
*
*Parameters: input
* IPMAC   pointer to the macrolib to be updated.
* IPOPT   pointer to the L_OPTIMIZE object open in read-only mode.
*
*-----------------------------------------------------------------------
*
      USE GANLIB
*----
*  SUBROUTINE ARGUMENTS
*----
      TYPE(C_PTR) IPMAC,IPOPT
*----
*  LOCAL VARIABLES
*----
      PARAMETER (NSTATE=40)
      TYPE(C_PTR) JPMAC,KPMAC
      INTEGER ISTATE(NSTATE)
*----
* ALLOCATABLE ARRAYS
*----
      REAL, ALLOCATABLE, DIMENSION(:) :: VARV,GAR
*----
*  GET L_OPTIMIZE INFORMATION
*----
      CALL XDISET(ISTATE,NSTATE,0)
      CALL LCMGET(IPOPT,'DLEAK-STATE',ISTATE)
      NGRP=ISTATE(1)
      NMIX=ISTATE(2)
      ITYPE=ISTATE(3)
      IDELTA=ISTATE(4)
      NGR1=ISTATE(5)
      NGR2=ISTATE(6)
      IBM1=ISTATE(7)
      IBM2=ISTATE(8)
      NPERT=(NGR2-NGR1+1)*(IBM2-IBM1+1)
*----
*  GET MACROLIB INFORMATION
*----
      CALL XDISET(ISTATE,NSTATE,0)
      CALL LCMGET(IPMAC,'STATE-VECTOR',ISTATE)
      IF(ISTATE(1).NE.NGRP) CALL XABORT('MACOPT: INVALID NGRP.')
      IF(ISTATE(2).NE.NMIX) CALL XABORT('MACOPT: INVALID NMIX.')
      ILEAK=ISTATE(9)
      IF(ITYPE.EQ.2) THEN
         ISTATE(10)=MAX(1,ISTATE(10))
         CALL LCMPUT(IPMAC,'STATE-VECTOR',NSTATE,1,ISTATE)
      ENDIF
*----
*  UPDATE MACROLIB
*----
      ALLOCATE(VARV(NPERT),GAR(3*NMIX))
      CALL LCMGET(IPOPT,'VAR-VALUE',VARV)
      JPMAC=LCMGID(IPMAC,'GROUP')
      IPERT=0
      DO 100 IGR=NGR1,NGR2
      KPMAC=LCMDIL(JPMAC,IGR)
      IF((IDELTA.EQ.1).AND.(ITYPE.EQ.1).AND.(ILEAK.EQ.1)) THEN
         CALL LCMGET(KPMAC,'DIFF',GAR)
         DO 10 IBM=IBM1,IBM2
         IPERT=IPERT+1
   10    GAR(IBM)=VARV(IPERT)
         CALL LCMPUT(KPMAC,'DIFF',NMIX,2,GAR)
      ELSE IF((IDELTA.EQ.1).AND.(ITYPE.EQ.1).AND.(ILEAK.EQ.2)) THEN
         CALL LCMGET(KPMAC,'DIFFX',GAR)
         CALL LCMGET(KPMAC,'DIFFY',GAR(NMIX+1))
         CALL LCMGET(KPMAC,'DIFFZ',GAR(2*NMIX+1))
         DO 20 IBM=IBM1,IBM2
         IPERT=IPERT+1
         GAR(IBM)=VARV(IPERT)
         GAR(NMIX+IBM)=VARV(IPERT)
   20    GAR(2*NMIX+IBM)=VARV(IPERT)
         CALL LCMPUT(KPMAC,'DIFFX',NMIX,2,GAR)
         CALL LCMPUT(KPMAC,'DIFFY',NMIX,2,GAR(NMIX+1))
         CALL LCMPUT(KPMAC,'DIFFZ',NMIX,2,GAR(2*NMIX+1))
      ELSE IF((IDELTA.EQ.1).AND.(ITYPE.EQ.2)) THEN
         CALL LCMLEN(KPMAC,'NTOT1',ILONG,ITYLCM)
         IF(ILONG.NE.0.0) THEN
            CALL LCMGET(KPMAC,'NTOT1',GAR)
         ELSE
            CALL LCMGET(KPMAC,'NTOT0',GAR)
         ENDIF
         DO 30 IBM=IBM1,IBM2
         IPERT=IPERT+1
   30    GAR(IBM)=VARV(IPERT)
         CALL LCMPUT(KPMAC,'NTOT1',NMIX,2,GAR)
      ELSE IF((IDELTA.EQ.2).AND.(ITYPE.EQ.1).AND.(ILEAK.EQ.1)) THEN
         CALL LCMGET(KPMAC,'DIFF',GAR)
         DO 40 IBM=IBM1,IBM2
         IPERT=IPERT+1
         FACT=VARV(IPERT)
   40    GAR(IBM)=GAR(IBM)*FACT
         CALL LCMPUT(KPMAC,'DIFF',NMIX,2,GAR)
      ELSE IF((IDELTA.EQ.2).AND.(ITYPE.EQ.1).AND.(ILEAK.EQ.2)) THEN
         CALL LCMGET(KPMAC,'DIFFX',GAR)
         CALL LCMGET(KPMAC,'DIFFY',GAR(NMIX+1))
         CALL LCMGET(KPMAC,'DIFFZ',GAR(2*NMIX+1))
         DO 50 IBM=IBM1,IBM2
         IPERT=IPERT+1
         FACT=VARV(IPERT)
         GAR(IBM)=GAR(IBM)*FACT
         GAR(NMIX+IBM)=GAR(NMIX+IBM)*FACT
   50    GAR(2*NMIX+IBM)=GAR(2*NMIX+IBM)*FACT
         CALL LCMPUT(KPMAC,'DIFFX',NMIX,2,GAR)
         CALL LCMPUT(KPMAC,'DIFFY',NMIX,2,GAR(NMIX+1))
         CALL LCMPUT(KPMAC,'DIFFZ',NMIX,2,GAR(2*NMIX+1))
      ELSE IF((IDELTA.EQ.2).AND.(ITYPE.EQ.2)) THEN
         CALL LCMLEN(KPMAC,'NTOT1',ILONG,ITYLCM)
         IF(ILONG.NE.0.0) THEN
            CALL LCMGET(KPMAC,'NTOT1',GAR)
         ELSE
            CALL LCMGET(KPMAC,'NTOT0',GAR)
         ENDIF
         DO 60 IBM=IBM1,IBM2
         IPERT=IPERT+1
         FACT=VARV(IPERT)
   60    GAR(IBM)=GAR(IBM)*FACT
         CALL LCMPUT(KPMAC,'NTOT1',NMIX,2,GAR)
      ENDIF
  100 CONTINUE
      DEALLOCATE(GAR,VARV)
      IF(IPERT.NE.NPERT) CALL XABORT('MACOPT: UPDATE FAILURE.')
      RETURN
      END
