C $Header: /u/gcmpack/MITgcm/pkg/kpp/kpp_do_diags.F,v 1.21 2005/05/25 04:03:09 edhill Exp $ C $Name: $ #include "KPP_OPTIONS.h" #undef MULTIPLE_RECORD_KPP_STATE_FILES C---+----1----+----2----+----3----+----4----+----5----+----6----+----7-|--+----| CBOP C !ROUTINE: KPP_DO_DIAGS C !INTERFACE: SUBROUTINE KPP_DO_DIAGS( myTime, myIter, myThid ) C !DESCRIPTION: C Create the KPP diagnostic output. C C The following CPP flag (MULTIPLE_RECORD_KPP_STATE_FILES) is C #define/#undefed here since it is specific to this routine and C very user-preference specific. C C If #undefed (default) the state files are written as in all C versions prior to checkpoint32, where a file is created per C variable, per time and per tile. This *has* to be the default C because most users use this mode and all utilities and scripts C (diagnostic) assume this form. It is also robust, as explained C below. C C If #defined, subsequent snap-shots are written as records in the C same file (no iteration number in filenames). C C Advantages: C - fewer files C - for small problems, is easy to copy the output around C Disadvantages: C - breaks a lot of diagnostic scripts C - for large or long problems this creates huge files C - is an unexpected, unsolicited change in behaviour which came C as a surprise (in c32) and inconvenience to several users C - can not accomodate changing the frequency of output C after a pickup (this is trivial in previous method C but needs new code and parameters in this new method) C !USES: IMPLICIT NONE #include "SIZE.h" #include "EEPARAMS.h" #include "PARAMS.h" #ifdef ALLOW_MNC #include "MNC_PARAMS.h" #endif #include "KPP.h" #include "KPP_PARAMS.h" #include "KPP_DIAGS.h" C !INPUT/OUTPUT PARAMETERS: _RL myTime INTEGER myIter INTEGER myThid #ifdef ALLOW_KPP C !LOCAL VARIABLES: CHARACTER*(MAX_LEN_MBUF) suff LOGICAL DIFFERENT_MULTIPLE EXTERNAL INTEGER bi, bj, K _RL DDTT INTEGER thisdate(4), prevdate(4) LOGICAL dumpFiles CEOP C---------------------------------------------------------------- C Dump snapshot of KPP variables. IF ( myIter.NE.nIter0 .AND. & DIFFERENT_MULTIPLE(kpp_dumpFreq,myTime,deltaTClock) & ) THEN IF (KPPmixingMaps) THEN CALL PLOT_FIELD_XYRL ( KPPhbl , 'KPPhbl' , & myIter, myThid ) CALL PLOT_FIELD_XYZRL ( KPPviscAz , 'KPPviscAz' , & Nr, myIter, myThid ) CALL PLOT_FIELD_XYZRL ( KPPdiffKzT, 'KPPdiffKzT', & Nr, myIter, myThid ) CALL PLOT_FIELD_XYZRL ( KPPghat , 'KPPghat' , & Nr, myIter, myThid ) ENDIF IF (KPPwriteState .AND. snapshot_mdsio) THEN #ifdef MULTIPLE_RECORD_KPP_STATE_FILES C Write each snap-shot as a new record in one file per variable C - creates relatively few files but these files can become huge C NOTE: file size and number problems are *SOLVED* by MNC CALL WRITE_REC_XYZ_RL('KPPviscAz',KPPviscAz,kpp_drctrec, & myIter,myThid) CALL WRITE_REC_XYZ_RL('KPPdiffKzT',KPPdiffKzT,kpp_drctrec, & myIter,myThid) CALL WRITE_REC_XYZ_RL('KPPdiffKzS',KPPdiffKzS,kpp_drctrec, & myIter,myThid) CALL WRITE_REC_XYZ_RL('KPPghat',KPPghat,kpp_drctrec, & myIter,myThid) CALL WRITE_REC_XY_RL('KPPhbl',KPPhbl,kpp_drctrec, & myIter,myThid) #else /* MULTIPLE_RECORD_KPP_STATE_FILES */ C Write each snap-shot as a new file - creates many files but C for large configurations is easier to transfer C NOTE: file size and number problems are *SOLVED* by MNC WRITE(suff,'(I10.10)') myIter CALL WRITE_FLD_XYZ_RL('KPPviscAz.',suff,KPPviscAz, & myIter,myThid) CALL WRITE_FLD_XYZ_RL('KPPdiffKzT.',suff,KPPdiffKzT, & myIter,myThid) CALL WRITE_FLD_XYZ_RL('KPPdiffKzS.',suff,KPPdiffKzS, & myIter,myThid) CALL WRITE_FLD_XYZ_RL('KPPghat.',suff,KPPghat, & myIter,myThid) CALL WRITE_FLD_XY_RL('KPPhbl.',suff,KPPhbl, & myIter,myThid) #endif /* MULTIPLE_RECORD_KPP_STATE_FILES */ ENDIF #ifdef ALLOW_MNC IF (KPPwriteState .AND. useMNC .AND. snapshot_mnc) THEN CALL MNC_CW_SET_UDIM('kpp_state', -1, myThid) CALL MNC_CW_RL_W_S('D','kpp_state',0,0,'T',myTime,myThid) CALL MNC_CW_SET_UDIM('kpp_state', 0, myThid) CALL MNC_CW_I_W_S('I','kpp_state',0,0,'iter',myIter,myThid) CALL MNC_CW_RL_W('D','kpp_state',0,0, & 'KPPviscAz', KPPviscAz, myThid) CALL MNC_CW_RL_W('D','kpp_state',0,0, & 'KPPdiffKzT', KPPdiffKzT, myThid) CALL MNC_CW_RL_W('D','kpp_state',0,0, & 'KPPdiffKzS', KPPdiffKzS, myThid) CALL MNC_CW_RL_W('D','kpp_state',0,0, & 'KPPghat', KPPghat, myThid) CALL MNC_CW_RL_W('D','kpp_state',0,0, & 'KPPhbl', KPPhbl, myThid) ENDIF #endif /* ALLOW_MNC */ C-- Increment record counter kpp_drctrec = kpp_drctrec + 1 ENDIF C---------------------------------------------------------------- C Do KPP time averaging. #ifdef ALLOW_TIMEAVE C Initialize averages to zero IF ( myIter.EQ.nIter0 ) THEN DO bj = myByLo(myThid), myByHi(myThid) DO bi = myBxLo(myThid), myBxHi(myThid) CALL TIMEAVE_RESET(KPPviscAztave, Nr,bi,bj,myThid) CALL TIMEAVE_RESET(KPPdiffKzTtave,Nr,bi,bj,myThid) CALL TIMEAVE_RESET(KPPghattave, Nr,bi,bj,myThid) CALL TIMEAVE_RESET(KPPdiffKzStave,Nr,bi,bj,myThid) CALL TIMEAVE_RESET(KPPhbltave, 1, bi,bj,myThid) DO k=1,Nr kpp_TimeAve(k,bi,bj)=0. ENDDO ENDDO ENDDO ELSE C Time Average KPP fields DDTT=deltaTclock DO bj = myByLo(myThid), myByHi(myThid) DO bi = myBxLo(myThid), myBxHi(myThid) CALL TIMEAVE_CUMULATE( & KPPviscAztave, KPPviscAz, Nr,DDTT,bi,bj,myThid) CALL TIMEAVE_CUMULATE( & KPPdiffKzTtave,KPPdiffKzT,Nr,DDTT,bi,bj,myThid) CALL TIMEAVE_CUMULATE( & KPPghattave, KPPghat, Nr,DDTT,bi,bj,myThid) CALL TIMEAVE_CUMULATE( & KPPdiffKzStave,KPPdiffKzS,Nr,DDTT,bi,bj,myThid) CALL TIMEAVE_CUMULATE( & KPPhbltave, KPPhbl, 1, DDTT,bi,bj,myThid) C Keep record of how much time has been integrated over DO k=1,Nr kpp_TimeAve(k,bi,bj)=kpp_TimeAve(k,bi,bj)+DDTT ENDDO ENDDO ENDDO ENDIF C Dump files and restart average computation if needed dumpFiles = .FALSE. IF ( myIter .NE. nIter0 ) THEN IF (DIFFERENT_MULTIPLE(KPP_taveFreq,myTime,deltaTClock)) & dumpFiles = .TRUE. #ifdef ALLOW_CAL IF ( calendarDumps .AND. ( & (KPP_taveFreq.GE. 2592000.AND.KPP_taveFreq.LE. 2678400).OR. & (KPP_taveFreq.GE.31104000.AND.KPP_taveFreq.LE.31968000))) & THEN C-- Convert approximate months (30-31 days) and years (360-372 days) C to exact calendar months and years. C- First determine calendar dates for this and previous time step. call CAL_GETDATE( myiter ,mytime ,thisdate,mythid ) call CAL_GETDATE( myiter-1,mytime-deltaTClock,prevdate,mythid ) dumpFiles = .FALSE. C- Monthly KPP_taveFreq: IF( KPP_taveFreq.GE. 2592000 .AND. KPP_taveFreq.LE. 2678400 & .AND. (thisdate(1)-prevdate(1)).GT.50 ) dumpFiles = .TRUE. C- Yearly KPP_taveFreq: IF( KPP_taveFreq.GE.31104000 .AND. KPP_taveFreq.LE.31968000 & .AND. (thisdate(1)-prevdate(1)).GT.5000 ) dumpFiles = .TRUE. ENDIF #endif ENDIF IF (dumpFiles) THEN C Normalize by integrated time DO bj = myByLo(myThid), myByHi(myThid) DO bi = myBxLo(myThid), myBxHi(myThid) CALL TIMEAVE_NORMALIZ(KPPviscAztave,kpp_timeave, & Nr, bi,bj,myThid) CALL TIMEAVE_NORMALIZ(KPPdiffKzTtave,kpp_timeave, & Nr, bi,bj,myThid) CALL TIMEAVE_NORMALIZ(KPPghattave,kpp_timeave, & Nr, bi,bj,myThid) CALL TIMEAVE_NORMALIZ(KPPdiffKzStave,kpp_timeave, & Nr, bi,bj,myThid) CALL TIMEAVE_NORMALIZ(KPPhbltave,kpp_timeave, & 1, bi,bj,myThid) ENDDO ENDDO IF (KPPwriteState .AND. timeave_mdsio) THEN #ifdef MULTIPLE_RECORD_KPP_STATE_FILES C Write each tave output as a new record in one file per variable C - creates relatively few files but these files can become huge C NOTE: file size and number problems are *SOLVED* by MNC CALL WRITE_REC_XYZ_RL('KPPviscAz-T',KPPviscAzTave, & kpp_drctrecTave,myIter,myThid) CALL WRITE_REC_XYZ_RL('KPPdiffKzT-T',KPPdiffKzTTave, & kpp_drctrecTave,myIter,myThid) CALL WRITE_REC_XYZ_RL('KPPdiffKzS-T',KPPdiffKzSTave, & kpp_drctrecTave,myIter,myThid) CALL WRITE_REC_XYZ_RL('KPPghat-T',KPPghatTave, & kpp_drctrecTave,myIter,myThid) CALL WRITE_REC_XY_RL('KPPhbl-T',KPPhblTave, & kpp_drctrecTave,myIter,myThid) C-- Increment record counter kpp_drctrecTave = kpp_drctrecTave + 1 #else /* MULTIPLE_RECORD_KPP_STATE_FILES */ C Write each tave output as a new file - creates many files but for C large configurations is easier to transfer C NOTE: file size and number problems are *SOLVED* by MNC WRITE(suff,'(I10.10)') myIter CALL WRITE_FLD_XYZ_RL('KPPviscAz-T.',suff,KPPviscAzTave, & myIter,myThid) CALL WRITE_FLD_XYZ_RL('KPPdiffKzT-T.',suff,KPPdiffKzTTave, & myIter,myThid) CALL WRITE_FLD_XYZ_RL('KPPdiffKzS-T.',suff,KPPdiffKzSTave, & myIter,myThid) CALL WRITE_FLD_XYZ_RL('KPPghat-T.',suff,KPPghatTave, & myIter,myThid) CALL WRITE_FLD_XY_RL('KPPhbl-T.',suff,KPPhblTave, & myIter,myThid) #endif /* MULTIPLE_RECORD_KPP_STATE_FILES */ ENDIF #ifdef ALLOW_MNC IF (KPPwriteState .AND. useMNC .AND. timeave_mnc) THEN CALL MNC_CW_SET_UDIM('kpp_timeave', -1, myThid) CALL MNC_CW_RL_W_S('D','kpp_timeave',0,0,'T',myTime,myThid) CALL MNC_CW_SET_UDIM('kpp_timeave', 0, myThid) CALL MNC_CW_I_W_S('I','kpp_timeave',0,0,'iter',myIter,myThid) CALL MNC_CW_RL_W('D','kpp_timeave',0,0, & 'KPPviscAz', KPPviscAzTave, myThid) CALL MNC_CW_RL_W('D','kpp_timeave',0,0, & 'KPPdiffKzT', KPPdiffKzTTave, myThid) CALL MNC_CW_RL_W('D','kpp_timeave',0,0, & 'KPPdiffKzS', KPPdiffKzSTave, myThid) CALL MNC_CW_RL_W('D','kpp_timeave',0,0, & 'KPPghat', KPPghatTave, myThid) CALL MNC_CW_RL_W('D','kpp_timeave',0,0, & 'KPPhbl', KPPhblTave, myThid) ENDIF #endif /* ALLOW_MNC */ C Reset averages to zero DO bj = myByLo(myThid), myByHi(myThid) DO bi = myBxLo(myThid), myBxHi(myThid) CALL TIMEAVE_RESET(KPPviscAztave, Nr,bi,bj,myThid) CALL TIMEAVE_RESET(KPPdiffKzTtave,Nr,bi,bj,myThid) CALL TIMEAVE_RESET(KPPghattave, Nr,bi,bj,myThid) CALL TIMEAVE_RESET(KPPdiffKzStave,Nr,bi,bj,myThid) CALL TIMEAVE_RESET(KPPhbltave, 1, bi,bj,myThid) DO k=1,Nr kpp_TimeAve(k,bi,bj)=0. ENDDO ENDDO ENDDO ENDIF #endif /* ALLOW_TIMEAVE */ #ifdef ALLOW_DIAGNOSTICS IF ( useDiagnostics ) THEN CALL DIAGNOSTICS_FILL(KPPviscAz ,'KPPviscA',0,Nr,0,1,1,myThid) CALL DIAGNOSTICS_FILL(KPPdiffKzS,'KPPdiffS',0,Nr,0,1,1,myThid) CALL DIAGNOSTICS_FILL(KPPdiffKzT,'KPPdiffT',0,Nr,0,1,1,myThid) CALL DIAGNOSTICS_FILL(KPPghat ,'KPPghat ',0,Nr,0,1,1,myThid) CALL DIAGNOSTICS_FILL(KPPhbl ,'KPPhbl ',0,1 ,0,1,1,myThid) CALL DIAGNOSTICS_FILL(KPPfrac ,'KPPfrac ',0,1 ,0,1,1,myThid) ENDIF #endif /* ALLOW_DIAGNOSTICS */ #endif /* ALLOW_KPP */ RETURN END