Back to home page

MITgcm

 
 

    


File indexing completed on 2022-08-15 05:09:08 UTC

view on githubraw file Latest commit cf705a6c on 2022-08-14 22:40:32 UTC
3c287b198c Jean*0001 #include "AUTODIFF_OPTIONS.h"
4240547d2d Mart*0002 #ifdef ALLOW_MOM_COMMON
                0003 # include "MOM_COMMON_OPTIONS.h"
                0004 #endif /* ALLOW_MOM_COMMON */
3c287b198c Jean*0005 
                0006 C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----|
                0007 CBOP 0
                0008 C !ROUTINE: AUTODIFF_READPARMS
                0009 
                0010 C !INTERFACE:
                0011       SUBROUTINE AUTODIFF_READPARMS( myThid )
                0012 
                0013 C     !DESCRIPTION:
                0014 C     Initialize AUTODIFF variables and constants.
                0015 
                0016 C     !USES:
                0017       IMPLICIT NONE
                0018 #include "SIZE.h"
                0019 #include "EEPARAMS.h"
                0020 #include "PARAMS.h"
                0021 #include "AUTODIFF_PARAMS.h"
0d75a51072 Mart*0022 #ifdef ALLOW_GENERIC_ADVDIFF
                0023 # include "GAD.h"
                0024 #endif/* ALLOW_GENERIC_ADVDIFF */
                0025 #ifdef ALLOW_SEAICE
                0026 # include "SEAICE_SIZE.h"
                0027 # include "SEAICE_PARAMS.h"
                0028 #endif /* ALLOW_SEAICE */
3c287b198c Jean*0029 
                0030 C     !INPUT PARAMETERS:
                0031       INTEGER myThid
                0032 CEOP
                0033 
                0034 #ifdef ALLOW_AUTODIFF
                0035 
                0036 C     !LOCAL VARIABLES:
                0037 C     msgBuf     :: Informational/error message buffer
                0038 C     iUnit      :: Work variable for IO unit number
                0039       CHARACTER*(MAX_LEN_MBUF) msgBuf
                0040       INTEGER iUnit
6b07e0a584 Jean*0041       INTEGER errCount
0d75a51072 Mart*0042 #ifdef ALLOW_GENERIC_ADVDIFF
                0043       LOGICAL validAdvScheme
                0044 #endif /* ALLOW_GENERIC_ADVDIFF */
cf705a6c8e Mart*0045 C     retired parameter
                0046       INTEGER nRetired
                0047       LOGICAL useSmoothCorrel2DinAdMode
3c287b198c Jean*0048 
                0049       NAMELIST /AUTODIFF_PARM01/
59af019e97 Jean*0050      &       dumpAdVarExch, mon_AdVarExch,
e4b3cf1fc6 Jean*0051      &       dumpAdByRec,
0d75a51072 Mart*0052      &       useApproxAdvectionInAdMode,
b5f6e47484 Gael*0053      &       useKPPinAdMode, useGGL90inAdMode,
                0054      &       useGMRediInAdMode, useSALT_PLUMEinAdMode,
8efbdea137 Gael*0055      &       useSEAICEinAdMode, useSmoothCorrel2DinAdMode,
4240547d2d Mart*0056      &       inAdExact, SEAICEapproxLevInAd,
                0057      &       viscFacInAd, viscFacInFw, SIregFacInAd, SIregFacInFw,
aecc8b0f47 Mart*0058      &       SEAICEuseFREEDRIFTswitchInAd, SEAICEuseDYNAMICSswitchInAd,
                0059      &       cg2dFullAdjoint
3c287b198c Jean*0060 
ec9dec43dc Gael*0061       IF ( .NOT.useAUTODIFF ) THEN
                0062 C-    pkg AUTODIFF is not used
                0063         _BEGIN_MASTER(myThid)
                0064 C-    Track pkg activation status:
                0065 C     print a (weak) warning if data.autodiff is found
                0066          CALL PACKAGES_UNUSED_MSG( 'useAUTODIFF', ' ', ' ' )
                0067         _END_MASTER(myThid)
                0068         RETURN
                0069       ENDIF
                0070 
3c287b198c Jean*0071       _BEGIN_MASTER(myThid)
6b07e0a584 Jean*0072       errCount = 0
3c287b198c Jean*0073 
                0074 C--   Default values for AUTODIFF
59af019e97 Jean*0075       dumpAdVarExch      = 2
                0076       mon_AdVarExch      = 2
                0077 C-    to recover old ad-monitor & ad-dump behaviour:
6b7bb6bd41 Jean*0078 c     dumpAdVarExch      = 1
                0079 c     mon_AdVarExch      = 0
e4b3cf1fc6 Jean*0080 C--   default : write one file per record
816e6857b6 Gael*0081       dumpAdByRec        = .FALSE.
3c287b198c Jean*0082       useKPPinAdMode     = .TRUE.
                0083       useGMRediInAdMode  = .TRUE.
                0084       useSEAICEinAdMode  = .TRUE.
b5f6e47484 Gael*0085       useGGL90inAdMode   = .TRUE.
                0086       useSALT_PLUMEinAdMode = .TRUE.
aecc8b0f47 Mart*0087       cg2dFullAdjoint    = .FALSE.
3c287b198c Jean*0088       inAdExact          = .TRUE.
0d75a51072 Mart*0089       useApproxAdvectionInAdMode = .FALSE.
a661e4ae05 Gael*0090       SEAICEapproxLevInAd = 0
4240547d2d Mart*0091       viscFacInFw        = 1. _d 0
a661e4ae05 Gael*0092       viscFacInAd        = 1. _d 0
dc54d31829 Ian *0093       SIregFacInAd       = UNSET_RL
914da317ef jm-c 0094       SIregFacInFw       = UNSET_RL
6b07e0a584 Jean*0095 
e6026aeb57 Patr*0096 C-- pkg/seaice related switches
6b07e0a584 Jean*0097       SEAICEuseFREEDRIFTswitchInAd = .FALSE.
                0098       SEAICEuseDYNAMICSswitchInAd  = .FALSE.
cf705a6c8e Mart*0099       useSmoothCorrel2DinAdMode    = .TRUE.
3c287b198c Jean*0100 
                0101       WRITE(msgBuf,'(A)') 'AUTODIFF_READPARMS: opening data.autodiff'
                0102       CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
                0103      &                    SQUEEZE_RIGHT, myThid )
                0104       CALL OPEN_COPY_DATA_FILE(
                0105      I                     'data.autodiff', 'AUTODIFF_READPARMS',
                0106      O                     iUnit,
                0107      I                     myThid )
                0108 
                0109 C     Read parameters from open data file
                0110       READ(UNIT=iUnit,NML=AUTODIFF_PARM01)
                0111       WRITE(msgBuf,'(A)')
                0112      &    'AUTODIFF_READPARMS: finished reading data.autodiff'
                0113       CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
                0114      &                    SQUEEZE_RIGHT, myThid )
                0115 C     Close the open data file
7a77863887 Mart*0116 #ifdef SINGLE_DISK_IO
3c287b198c Jean*0117       CLOSE(iUnit)
7a77863887 Mart*0118 #else
                0119       CLOSE(iUnit,STATUS='DELETE')
                0120 #endif /* SINGLE_DISK_IO */
3c287b198c Jean*0121 
0d75a51072 Mart*0122 C--   Flags for approximate adjoint. Flag inAdMode is set/unset in
                0123 C     autodiff_inadmode_set/unset_ad.F. Wherever inAdMode is used it requires
                0124 C     using inAdExact or useApproxAdvectionInAdMode along with it.
                0125       IF ( .NOT.inAdExact ) THEN
                0126 C     reset to recover old behavior, in case that is ever needed
                0127        useApproxAdvectionInAdMode = .TRUE.
                0128        WRITE(msgBuf,'(A)') '**WARNING** AUTODIFF_READPARMS: '//
                0129      &      'resetting useApproxAdvectionInAdMode to .TRUE., '//
                0130      &      'because inAdExact=.FALSE.'
                0131        CALL PRINT_MESSAGE( msgBuf, errorMessageUnit,
                0132      &                     SQUEEZE_RIGHT, myThid )
3c287b198c Jean*0133       ENDIF
                0134       inAdMode   = .FALSE.
                0135 
                0136 C--   packages which can be switched off in adjoint mode (approximate adjoint):
                0137 C     store value of usePKG as it will be reset in S/R ADAUTODIFF_INADMODE_UNSET
                0138       useKPPinFwdMode    = useKPP
                0139       useGMRediInFwdMode = useGMRedi
                0140       useSEAICEinFwdMode = useSEAICE
6b07e0a584 Jean*0141       useGGL90inFwdMode  = useGGL90
b5f6e47484 Gael*0142       useSALT_PLUMEinFwdMode = useSALT_PLUME
3c287b198c Jean*0143 
                0144 C     store value of usePKG as it will be set in S/R ADAUTODIFF_INADMODE_SET
                0145       useKPPinAdMode    = useKPPinAdMode    .AND. useKPP
                0146       useGMRediInAdMode = useGMRediInAdMode .AND. useGMRedi
                0147       useSEAICEinAdMode = useSEAICEinAdMode .AND. useSEAICE
6b07e0a584 Jean*0148       useGGL90inAdMode  = useGGL90inAdMode  .AND. useGGL90
b5f6e47484 Gael*0149       useSALT_PLUMEinAdMode = useSALT_PLUMEinAdMode .AND. useSALT_PLUME
3c287b198c Jean*0150 
4240547d2d Mart*0151 C     set this parameter to something we want to be able specify in a namelist
                0152       viscFacAdj = viscFacInFw
                0153 
a661e4ae05 Gael*0154 #ifdef ALLOW_SEAICE
                0155 c     level of approximation in seaice thermodynamics adjoint
                0156       if (useSEAICEinFwdMode.AND.(.NOT.useSEAICEinAdMode))
                0157      &   SEAICEapproxLevInAd=MIN(SEAICEapproxLevInAd,0)
                0158       if (useSEAICEinAdMode)
                0159      &   SEAICEapproxLevInAd=MAX(SEAICEapproxLevInAd,0)
                0160 #endif
                0161 
cf705a6c8e Mart*0162 C-    Retired parameters
                0163       nRetired = 0
                0164       IF ( .NOT. useSmoothCorrel2DinAdMode ) THEN
                0165        nRetired = nRetired + 1
                0166        WRITE(msgBuf,'(A,A)')
                0167      &  'S/R AUTODIFF_READPARMS: "useSmoothCorrel2DinAdMode" ',
                0168      &  'is no longer allowed in file "data.autodiff"'
                0169        CALL PRINT_ERROR( msgBuf, myThid )
                0170        WRITE(msgBuf,'(A)')
                0171      &  'S/R AUTODIFF_READPARMS: use "pkg/smooth" instead'
                0172        CALL PRINT_ERROR( msgBuf, myThid )
                0173       ENDIF
                0174       IF ( nRetired .GT. 0 ) THEN
                0175        CALL ALL_PROC_DIE( 0 )
                0176        STOP 'ABNORMAL END: S/R AUTODIFF_READPARMS'
                0177       ENDIF
                0178 
0d75a51072 Mart*0179 C--   Print out some key parameters :
8cbe658cd1 Jean*0180       WRITE(msgBuf,'(A)') '// ==================================='
                0181       CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
                0182      &                    SQUEEZE_RIGHT, myThid )
                0183       WRITE(msgBuf,'(A)') '// AUTODIFF parameters :'
                0184       CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
                0185      &                    SQUEEZE_RIGHT, myThid )
                0186       WRITE(msgBuf,'(A)') '// ==================================='
                0187       CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
                0188      &                    SQUEEZE_RIGHT, myThid )
                0189        CALL WRITE_0D_L( inAdExact, INDEX_NONE,
                0190      &  'inAdExact =', ' /* get an exact adjoint (no approximation) */')
0d75a51072 Mart*0191        CALL WRITE_0D_L( useApproxAdvectionInAdMode, INDEX_NONE,
                0192      & 'useApproxAdvectionInAdMode =',' /* approximate AD-advection */')
aecc8b0f47 Mart*0193        CALL WRITE_0D_L( cg2dFullAdjoint, INDEX_NONE,
                0194      &   'cg2dFullAdjoint =',
                0195      &   ' /* use full hand written cg2d adjoint (no approximation) */')
8cbe658cd1 Jean*0196        CALL WRITE_0D_L( useKPPinAdMode, INDEX_NONE,
                0197      &   'useKPPinAdMode =',      ' /* use KPP in adjoint mode */')
                0198        CALL WRITE_0D_L( useGMRediInAdMode, INDEX_NONE,
                0199      &  'useGMRediInAdMode =', ' /* use GMRedi in adjoint mode */')
                0200        CALL WRITE_0D_L( useSEAICEinAdMode, INDEX_NONE,
                0201      &  'useSEAICEinAdMode =', ' /* use SEAICE in adjoint mode */')
b5f6e47484 Gael*0202        CALL WRITE_0D_L( useGGL90inAdMode, INDEX_NONE,
                0203      &   'useGGL90inAdMode =',      ' /* use GGL90 in adjoint mode */')
                0204        CALL WRITE_0D_L( useSALT_PLUMEinAdMode, INDEX_NONE,
                0205      &   'useSALT_PLUMEinAdMode =',
                0206      &   ' /* use SALT_PLUME in adjoint mode */')
8cbe658cd1 Jean*0207 #ifdef ALLOW_SEAICE
6b07e0a584 Jean*0208        CALL WRITE_0D_L( SEAICEuseDYNAMICSswitchInAd, INDEX_NONE,
                0209      &  'SEAICEuseDYNAMICSswitchInAd =',
                0210      &            ' /* switch On/Off SEAICE Dyn in AD mode */')
                0211        CALL WRITE_0D_L( SEAICEuseFREEDRIFTswitchInAd, INDEX_NONE,
                0212      &  'SEAICEuseFREEDRIFTswitchInAd=',
                0213      &            ' /* switch On/Off Free-Drift in AD mode */')
a661e4ae05 Gael*0214        CALL WRITE_0D_I( SEAICEapproxLevInAd, INDEX_NONE,
                0215      &  'SEAICEapproxLevInAd =',
                0216      &  ' /* -1:SEAICE_FAKE, >0:other adjoint approximation */')
8cbe658cd1 Jean*0217 #endif /* ALLOW_SEAICE */
59af019e97 Jean*0218        CALL WRITE_0D_I( dumpAdVarExch, INDEX_NONE,
                0219      &  'dumpAdVarExch =', ' /* control adexch before dumpinp */')
                0220        CALL WRITE_0D_I( mon_AdVarExch, INDEX_NONE,
                0221      &  'mon_AdVarExch =', ' /* control adexch before monitor */')
4240547d2d Mart*0222        CALL WRITE_0D_RL( viscFacInFw, INDEX_NONE,
                0223      &  'viscFacInFw =', ' /* viscosity factor for forward model */')
a661e4ae05 Gael*0224        CALL WRITE_0D_RL( viscFacInAd, INDEX_NONE,
                0225      &  'viscFacInAd =', ' /* viscosity factor for adjoint */')
4dd39c50d9 Mart*0226        CALL WRITE_0D_RL( SIregFacInAd, INDEX_NONE,
                0227      &  'SIregFacInAd =', ' /* sea ice factor for adjoint model */')
                0228        CALL WRITE_0D_RL( SIregFacInFw, INDEX_NONE,
                0229      &  'SIregFacInFw =', ' /* sea ice factor for forward model */')
8cbe658cd1 Jean*0230       WRITE(msgBuf,'(A)') ' '
                0231       CALL PRINT_MESSAGE( msgBuf, standardMessageUnit,
                0232      &                    SQUEEZE_RIGHT, myThid )
                0233 
                0234 C--   Check parameters :
4240547d2d Mart*0235       IF ( viscFacInAd .NE. 1. _d 0 .OR. viscFacInFw .NE. 1. _d 0 ) THEN
                0236 #ifndef AUTODIFF_ALLOW_VISCFACADJ
                0237        WRITE(msgBuf,'(2A)') 'AUTODIFF_READPARMS: ',
                0238      &'To use viscFacInFw/viscFacInAd, define AUTODIFF_ALLOW_VISCFACADJ'
                0239        CALL PRINT_ERROR( msgBuf, myThid )
                0240        errCount = errCount + 1
                0241 #endif /* AUTODIFF_ALLOW_VISCFACADJ */
                0242 #if (!defined ALLOW_3D_VISCAH && !defined ALLOW_3D_VISCA4)
                0243        WRITE(msgBuf,'(2A)') 'AUTODIFF_READPARMS: ',
                0244      &      'To use viscFacInFw/viscFacInAd, '//
                0245      &      'define ALLOW_3D_VISCA4 and/or ALLOW_3D_VISCA4'
                0246        CALL PRINT_ERROR( msgBuf, myThid )
                0247        errCount = errCount + 1
                0248 #endif /* ALLOW_3D_VISCA */
                0249 #ifdef ALLOW_3D_VISCAH
                0250        IF ( viscAhDfile .EQ. ' ' .AND. viscAhZfile .EQ. ' ' ) THEN
                0251         WRITE(msgBuf,'(2A)') '** WARNING ** AUTODIFF_READPARMS: ',
                0252      &       'For viscFacInFw/viscFacInAd to have any effect, '//
                0253      &       'specify at least one of viscAh[D/Z]file'
                0254         CALL PRINT_MESSAGE( msgBuf, errorMessageUnit,
                0255      &       SQUEEZE_RIGHT, myThid )
                0256        ENDIF
                0257 #endif /* ALLOW_3D_VISCAH */
                0258 #ifdef ALLOW_3D_VISCA4
                0259        IF ( viscA4Dfile .EQ. ' ' .AND. viscA4Zfile .EQ. ' ' ) THEN
                0260         WRITE(msgBuf,'(2A)') '** WARNING ** AUTODIFF_READPARMS: ',
                0261      &       'For viscFacInFw/viscFacInAd to have any effect, '//
                0262      &       'specify at least one of viscA4[D/Z]file'
                0263         CALL PRINT_MESSAGE( msgBuf, errorMessageUnit,
                0264      &       SQUEEZE_RIGHT, myThid )
                0265        ENDIF
                0266 #endif /* ALLOW_3D_VISCA4 */
                0267       ENDIF
6b07e0a584 Jean*0268 #ifdef ALLOW_SEAICE
                0269       IF ( SEAICEuseFREEDRIFTswitchInAd .AND. .NOT.useSEAICE ) THEN
                0270         WRITE(msgBuf,'(2A)') 'AUTODIFF_READPARMS: ',
                0271      &  'SEAICEuseFREEDRIFTswitchInAd not usable without useSEAICE'
                0272         CALL PRINT_ERROR( msgBuf, myThid )
                0273         errCount = errCount + 1
                0274       ENDIF
                0275       IF ( SEAICEuseDYNAMICSswitchInAd .AND. .NOT.useSEAICE ) THEN
                0276         WRITE(msgBuf,'(2A)') 'AUTODIFF_READPARMS: ',
                0277      &  'SEAICEuseDYNAMICSswitchInAd not usable without useSEAICE'
                0278         CALL PRINT_ERROR( msgBuf, myThid )
                0279         errCount = errCount + 1
                0280       ENDIF
                0281 #else /* ALLOW_SEAICE */
                0282       SEAICEuseFREEDRIFTswitchInAd = .FALSE.
                0283       SEAICEuseDYNAMICSswitchInAd  = .FALSE.
                0284 #endif /* ALLOW_SEAICE */
8cbe658cd1 Jean*0285 
0d75a51072 Mart*0286       IF ( useApproxAdvectionInAdMode ) THEN
                0287 #ifdef ALLOW_GENERIC_ADVDIFF
                0288 C     so far this only works for flux limited DST3 scheme
                0289        validAdvScheme = .FALSE.
                0290        validAdvScheme = validAdvScheme
                0291      &      .OR. tempAdvScheme.EQ.ENUM_DST3_FLUX_LIMIT
                0292      &      .OR. saltAdvScheme.EQ.ENUM_DST3_FLUX_LIMIT
                0293 #ifdef ALLOW_SEAICE
                0294        IF ( useSEAICE ) validAdvScheme = validAdvScheme
                0295      &      .OR. SEAICEadvScheme .EQ.ENUM_DST3_FLUX_LIMIT
                0296      &      .OR. SEAICEadvSchArea.EQ.ENUM_DST3_FLUX_LIMIT
                0297      &      .OR. SEAICEadvSchHeff.EQ.ENUM_DST3_FLUX_LIMIT
                0298      &      .OR. SEAICEadvSchSnow.EQ.ENUM_DST3_FLUX_LIMIT
                0299      &      .OR. SEAICEadvSchSalt.EQ.ENUM_DST3_FLUX_LIMIT
                0300 #endif /* ALLOW_SEAICE */
                0301        IF ( .NOT. validAdvScheme ) THEN
                0302         WRITE(msgBuf,'(3A)') 'AUTODIFF_READPARMS: ',
                0303      &       'useApproxAdvectionInAdMode = .TRUE. ',
                0304      &       'only makes sense if at least '
                0305         CALL PRINT_ERROR( msgBuf, myThid )
                0306         WRITE(msgBuf,'(2A,I2,A)') 'AUTODIFF_READPARMS: ',
                0307      &       'one advection scheme is ', ENUM_DST3_FLUX_LIMIT,
                0308      &       '. Current settings are:'
                0309         CALL PRINT_ERROR( msgBuf, myThid )
                0310         WRITE(msgBuf,'(2A,I2)') 'AUTODIFF_READPARMS: ',
                0311      &       'tempAdvScheme    = ', tempAdvScheme
                0312         CALL PRINT_ERROR( msgBuf, myThid )
                0313         WRITE(msgBuf,'(2A,I2)') 'AUTODIFF_READPARMS: ',
                0314      &       'saltAdvScheme    = ', saltAdvScheme
                0315         CALL PRINT_ERROR( msgBuf, myThid )
                0316 #ifdef ALLOW_SEAICE
                0317         IF ( useSEAICE ) THEN
                0318          WRITE(msgBuf,'(2A,I2)') 'AUTODIFF_READPARMS: ',
                0319      &        'SEAICEadvScheme  = ', SEAICEadvScheme
                0320          CALL PRINT_ERROR( msgBuf, myThid )
                0321          WRITE(msgBuf,'(2A,I2)') 'AUTODIFF_READPARMS: ',
                0322      &        'SEAICEadvSchArea = ', SEAICEadvSchArea
                0323          CALL PRINT_ERROR( msgBuf, myThid )
                0324          WRITE(msgBuf,'(2A,I2)') 'AUTODIFF_READPARMS: ',
                0325      &        'SEAICEadvSchHeff = ', SEAICEadvSchHeff
                0326          CALL PRINT_ERROR( msgBuf, myThid )
                0327          WRITE(msgBuf,'(2A,I2)') 'AUTODIFF_READPARMS: ',
                0328      &        'SEAICEadvSchSnow = ', SEAICEadvSchSnow
                0329          CALL PRINT_ERROR( msgBuf, myThid )
                0330          WRITE(msgBuf,'(2A,I2)') 'AUTODIFF_READPARMS: ',
                0331      &        'SEAICEadvSchSalt = ', SEAICEadvSchSalt
                0332          CALL PRINT_ERROR( msgBuf, myThid )
                0333         ENDIF
                0334 #endif /* ALLOW_SEAICE */
                0335         errCount = errCount + 1
                0336        ENDIF
                0337 #else
                0338        WRITE(msgBuf,'(2A)') 'AUTODIFF_READPARMS: ',
                0339      &  'useApproxAdvectionInAdMode=.TRUE. without pkg/generic_advdiff'
                0340        CALL PRINT_ERROR( msgBuf, myThid )
                0341        errCount = errCount + 1
                0342 #endif /* ALLOW_GENERIC_ADVDIFF */
                0343       ENDIF
                0344 
6b07e0a584 Jean*0345       IF ( errCount.GE.1 ) THEN
                0346         WRITE(msgBuf,'(A,I3,A)')
                0347      &   'AUTODIFF_READPARMS: detected', errCount,' fatal error(s)'
                0348         CALL PRINT_ERROR( msgBuf, myThid )
                0349         CALL ALL_PROC_DIE( 0 )
                0350         STOP 'ABNORMAL END: S/R AUTODIFF_READPARMS'
                0351       ENDIF
8cbe658cd1 Jean*0352 
3c287b198c Jean*0353       _END_MASTER(myThid)
                0354 
                0355 C--   Everyone else must wait for the parameters to be loaded
                0356       _BARRIER
                0357 
                0358 #endif /* ALLOW_AUTODIFF */
                0359 
                0360       RETURN
                0361       END