diff --git a/cime_config/buildexe b/cime_config/buildexe index 476bee765..52640d30b 100755 --- a/cime_config/buildexe +++ b/cime_config/buildexe @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """ build model executable diff --git a/cime_config/buildnml b/cime_config/buildnml index 00b3dad35..40868bd27 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """Namelist creator for CIME's driver. """ import os, sys @@ -84,11 +84,6 @@ def _create_drv_namelists(case, infile, confdir, nmlgen, files): #---------------------------------------------------- nmlgen.init_defaults(infile, config) - if case.get_value('MEDIATOR_READ_RESTART'): - nmlgen.set_value('mediator_read_restart', value='.true.') - else: - nmlgen.set_value('mediator_read_restart', value='.false.') - #-------------------------------- # Overwrite: set brnch_retain_casename #-------------------------------- diff --git a/cime_config/config_component.xml b/cime_config/config_component.xml index 8f6030c52..95b0c801c 100644 --- a/cime_config/config_component.xml +++ b/cime_config/config_component.xml @@ -331,7 +331,7 @@ char - none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,end ndays run_begin_stop_restart env_run.xml @@ -363,7 +363,7 @@ char - none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,end $STOP_OPTION run_begin_stop_restart env_run.xml @@ -1862,6 +1862,26 @@ pes or cores per node for accounting purposes + + integer + 0 + + 1 + 1 + + mach_pes + env_mach_pes.xml + Number of GPUs per node used for simulation + + + + integer + 0 + mach_pes_last + env_mach_pes.xml + maximum number of GPUs allowed per node + + integer $MAX_MPITASKS_PER_NODE @@ -2293,7 +2313,7 @@ char - none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,end never run_drv_history env_run.xml @@ -2343,7 +2363,6 @@ machines/compilers. - diff --git a/cime_config/config_component_cesm.xml b/cime_config/config_component_cesm.xml index 49ed73ed7..8934f2410 100644 --- a/cime_config/config_component_cesm.xml +++ b/cime_config/config_component_cesm.xml @@ -18,10 +18,14 @@ Historic transient Twentieth century transient - CMIP5 rcp 2.6 forcing - CMIP5 rcp 4.5 forcing - CMIP5 rcp 6.0 forcing - CMIP5 rcp 8.5 forcing + CMIP6 SSP1-1.9 forcing + CMIP6 SSP1-2.6 forcing + CMIP6 SSP2-4.5 forcing + CMIP6 SSP3-7.0 forcing + CMIP6 SSP4-3.4 forcing + CMIP6 SSP4-6.0 forcing + CMIP6 SSP5-3.4 forcing + CMIP6 SSP5-8.5 forcing Biogeochemistry intercomponent with diagnostic CO2 with prognostic CO2 @@ -96,15 +100,6 @@ We will not document this further in this guide. - - logical - TRUE,FALSE - FALSE - run_flags - env_run.xml - turns on coupler bit-for-bit reproducibility with varying pe counts - - char none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end @@ -191,23 +186,39 @@ 144 288 288 - 72 - 48 - - - 24 - 24 - 24 - 24 - - - - - 24 - 24 - 48 - 48 - 1 + + + + 48 + 48 + 48 + 24 + 24 + + 72 + + + + 24 + 24 + + + + + + 24 + 144 + 24 + 24 + + + + 24 + 48 + 48 + + + 96 96 96 @@ -230,13 +241,11 @@ 72 144 288 - 48 - 48 - 24 - 24 - 1 - - + + + + + 1 run_coupling env_run.xml @@ -275,16 +284,14 @@ integer $ATM_NCPL - 24 24 - 4 + 1 24 24 - - - - + 48 + 48 1 + 24 run_coupling env_run.xml @@ -332,16 +339,16 @@ integer 8 - $ATM_NCPL - $ATM_NCPL - $ATM_NCPL - $ATM_NCPL - 1 - 8 - 8 - $ATM_NCPL - 1 - $ATM_NCPL + 1 + $ATM_NCPL + $ATM_NCPL + $ATM_NCPL + 1 + 8 + 8 + $ATM_NCPL + 1 + $ATM_NCPL run_coupling env_run.xml @@ -436,6 +443,153 @@ + + + + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets driver snapshot history file frequency (like REST_OPTION) + + + integer + + -999 + med_history + env_run.xml + Sets driver snapshot history file frequency (like REST_N) + + + + integer + + -999 + med_history + env_run.xml + yyyymmdd format, sets coupler snapshot history date (like REST_DATE) + + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + + + + char none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end @@ -443,11 +597,10 @@ nmonths - run_drv_history + med_history env_run.xml - Sets driver average history file frequency (like REST_OPTION) + Sets mediator average history file frequency (like REST_OPTION) - char @@ -455,18 +608,130 @@ 1 - run_drv_history + med_history env_run.xml - Sets driver average history file frequency (like REST_N) + Sets mediator average history file frequency (like REST_N) - integer -999 - run_drv_history + med_history + env_run.xml + yyyymmdd format, sets mediator average history date (like REST_DATE) + + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history + env_run.xml + Sets mediator average history file frequency (like REST_N) + + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + med_history + env_run.xml + Sets mediator average history file frequency (like REST_OPTION) + + + char + + -999 + med_history env_run.xml - yyyymmdd format, sets driver average history date (like REST_DATE) + Sets mediator average history file frequency (like REST_N) diff --git a/cime_config/config_component_ufs.xml b/cime_config/config_component_ufs.xml index 1516f97b0..bb32df7b5 100644 --- a/cime_config/config_component_ufs.xml +++ b/cime_config/config_component_ufs.xml @@ -422,6 +422,32 @@ + + char + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end + never + run_drv_history + env_run.xml + Sets driver snapshot history file frequency (like REST_OPTION) + + + integer + + -999 + run_drv_history + env_run.xml + Sets driver snapshot history file frequency (like REST_N) + + + + integer + + -999 + run_drv_history + env_run.xml + yyyymmdd format, sets coupler snapshot history date (like REST_DATE) + + char none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,nmonths,nmonth,nyears,nyear,date,ifdays0,end @@ -433,7 +459,6 @@ env_run.xml Sets driver average history file frequency (like REST_OPTION) - char @@ -445,7 +470,6 @@ env_run.xml Sets driver average history file frequency (like REST_N) - integer diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 71eca18ec..40827e598 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -1286,404 +1286,954 @@ - - - + + + - - logical - history - MED_attributes + + + + + + char + time + ALLCOMP_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end - logical to write an extra initial coupler history file + mediator history snapshot option (used with history_n and history_ymd) + set by HIST_OPTION in env_run.xml. + history_option alarms are: + [none/never], turns option off + [nstep/s] , history snapshot every history_n nsteps , relative to current run start time + [nsecond/s] , history snapshot every history_n nseconds, relative to current run start time + [nminute/s] , history snapshot every history_n nminutes, relative to current run start time + [nhour/s] , history snapshot every history_n nhours , relative to current run start time + [nday/s] , history snapshot every history_n ndays , relative to current run start time + [monthly/s] , history snapshot every month , relative to current run start time + [nmonth/s] , history snapshot every history_n nmonths , relative to current run start time + [nyear/s] , history snapshot every history_n nyears , relative to current run start time + [date] , history snapshot at history_ymd value + [ifdays0] , history snapshot at history_n calendar day value and seconds equal 0 + [end] , history snapshot at end - .false. + $HIST_OPTION - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + integer + time + ALLCOMP_attributes + + sets mediator snapshot history file frequency (like restart_n) + set by HIST_N in env_run.xml. + + + $HIST_N + + - - - - - - - - - - - + + integer + time + CLOCK_attributes + + date associated with history_option date. yyyymmdd format. + set by HIST_DATE in env_run.xml. + + + $HIST_DATE + + - - - + + + - + char - expdef - ALLCOMP_attributes + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end - name of the coupling field with scalar information + mediator history for atm import/export/fields snapshot option (used with history_n and history_ymd) - cpl_scalars + $HIST_OPTION_ATM - - + integer - expdef - ALLCOMP_attributes + time + MED_attributes - total number of scalars in the scalar coupling field + sets mediator snapshot history file frequency for atm import/export fields (like restart_n) - 4 + $HIST_N_ATM - - + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator time average history option (used with histavg_n and histavg_ymd) + + + $AVGHIST_OPTION_ATM + + + integer - expdef - ALLCOMP_attributes + time + MED_attributes - index of scalar containing global grid cell count in X dimension + Sets mediator time-average history file frequency (like restart_option) + + $AVGHIST_N_ATM + + + + + + logical + aux_hist + MED_attributes + Auxiliary mediator atm2med instantaneous history output every hour. + + .false. + + + + char + aux_hist + MED_attributes + Auxiliary mediator atm2med instantaneous history output every hour. + + Faxa_swndr:Faxa_swvdr:Faxa_swndf:Faxa_swvdf + + + + char + aux_hist + MED_attributes + history option type + + nhours + + + + char + aux_hist + MED_attributes + history option type + + 1 + + + + logical + aux_hist + MED_attributes + If true, use time average for aux file output. + + .false. + + + + char + aux_hist + MED_attributes + Auxiliary name identifier in history name + + atm.1h.inst + + + + integer + aux_hist + MED_attributes + Number of time sames per file. + + 24 + + + + + + logical + aux_hist + MED_attributes + Auxiliary atm2med history output averaged over 1 hour. + + .false. + + + + char + aux_hist + MED_attributes + Auxiliary atm2med history output averaged over 1 hour. + + Sa_u:Sa_v + + + + char + aux_hist + MED_attributes + history option type + + nhours + + + + char + aux_hist + MED_attributes + history option type + + 1 + + + + logical + aux_hist + MED_attributes + If true, use time average for aux file output. + + .true. + + + + char + aux_hist + MED_attributes + Number of time sames per file. + + 24 + + + + char + aux_hist + MED_attributes + Auxiliary name identifier in history name + + atm.1h.avrg + + + + + + logical + aux_hist + MED_attributes + + Auxiliary mediator atm2med precipitation history output every 3 hours + + + .false. + + + + char + aux_hist + MED_attributes + Auxiliary mediator atm2med precipitation history output every 3 hours + + Faxa_rainc:Faxa_rainl:Faxa_snowc:Faxa_snowl + + + + char + aux_hist + MED_attributes + history option type + + nhours + + + + char + aux_hist + MED_attributes + history option type + + 3 + + + + logical + aux_hist + MED_attributes + If true, use time average for aux file output. + + .true. + + + + char + aux_hist + MED_attributes + Number of time sames per file. + + 8 + + + + char + aux_hist + MED_attributes + Auxiliary name identifier in history name. + + atm.3hprec.avrg + + + + + + logical + aux_hist + MED_attributes + + Auxiliary mediator a2x precipitation history output every 3 hours + + + .false. + + + + char + aux_hist + MED_attributes + + Auxiliary mediator a2x precipitation history output every 3 hours + + + Sa_z:Sa_topo:Sa_u:Sa_v:Sa_tbot:Sa_ptem:Sa_shum:Sa_dens:Sa_pbot:Sa_pslv:Faxa_lwdn:Faxa_rainc:Faxa_rainl:Faxa_snowc:Faxa_snowl:Faxa_swndr:Faxa_swvdr:Faxa_swndf:Faxa_swvdf:Sa_co2diag:Sa_co2prog + + + + char + aux_hist + MED_attributes + history option type + + nhours + + + + char + aux_hist + MED_attributes + history option type + + 3 + + + + logical + aux_hist + MED_attributes + If true, use time average for aux file output. + + .true. + + + + char + aux_hist + MED_attributes + Number of time sames per file. + + 8 + + + + char + aux_hist + MED_attributes + Auxiliary name identifier in history name. + + atm.3h.avrg + + + + + + logical + aux_hist + MED_attributes + Auxiliary mediator a2x precipitation history output every 3 hours + + .false. + + + + char + aux_hist + MED_attributes + Auxiliary mediator a2x precipitation history output every 3 hours + + Faxa_bcph:Faxa_ocph:Faxa_dstwet:Faxa_dstdry:Sa_co2prog:Sa_co2diag + + + + char + aux_hist + MED_attributes + history option type + + ndays + + + + char + aux_hist + MED_attributes + history option type + + 1 + + + + logical + aux_hist + MED_attributes + If true, use time average for aux file output. + + .true. + + + + char + aux_hist + MED_attributes + Number of time sames per file. + + 1 + + + + char + aux_hist + MED_attributes + Auxiliary name identifier in history name + + atm.24h.avrg + + + + + + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator history for ice import/export/fields snapshot option (used with history_n and history_ymd) + + + $HIST_OPTION_ICE + + + + integer + time + MED_attributes + + sets mediator snapshot history file frequency for ice import/export fields (like restart_n) + + + $HIST_N_ICE + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator time average history option (used with histavg_n and histavg_ymd) + + + $AVGHIST_OPTION_ICE + + + + integer + time + MED_attributes + + Sets mediator time-average history file frequency (like restart_option) + + + $AVGHIST_N_ICE + + + + + + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator history for glc import/export/fields snapshot option (used with history_n and history_ymd) + + + $HIST_OPTION_GLC + + + + integer + time + MED_attributes + + sets mediator snapshot history file frequency for glc import/export fields (like restart_n) + + + $HIST_N_GLC + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator time average history option (used with histavg_n and histavg_ymd) + + + $AVGHIST_OPTION_GLC + + + + integer + time + MED_attributes + + Sets mediator time-average history file frequency (like restart_option) + + + $AVGHIST_N_GLC + + + + + + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator history for lnd import/export/fields snapshot option (used with history_n and history_ymd) + + + $HIST_OPTION_LND + + + + integer + time + MED_attributes + + sets mediator snapshot history file frequency for lnd import/export fields (like restart_n) + + + $HIST_N_LND + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator time average history option (used with histavg_n and histavg_ymd) + + + $AVGHIST_OPTION_LND + + + + integer + time + MED_attributes + + Sets mediator time-average history file frequency (like restart_option) + + + $AVGHIST_N_LND + + + + + + logical + aux_hist + MED_attributes + Auxiliary mediator l2x fields every lnd coupling interval + + .false. + + + + char + aux_hist + MED_attributes + Auxiliary mediator lnd2med output every lnd coupling interval + + all + + + + char + aux_hist + MED_attributes + history option type + + nsteps + + + + char + aux_hist + MED_attributes + history option type + + 1 + + + + logical + aux_hist + MED_attributes + If true, use time average for aux file output. + + .false. + + + + char + aux_hist + MED_attributes + Number of time sames per file. + + 1 + + + + char + aux_hist + MED_attributes + Auxiliary name identifier in history name + + lnd.ncpl.inst + + + + + + logical + aux_hist + MED_attributes + Auxiliary mediator lnd2med fields every year + + .false. + + + + char + aux_hist + MED_attributes + auxiliary file lnd2med sno fields averaged over a year + + Sl_tsrf_elev:Sl_topo_elev:Flgl_qice_elev + + + + char + aux_hist + MED_attributes + history option type + + nyears + + + + char + aux_hist + MED_attributes + history option type + + 1 + + + + logical + aux_hist + MED_attributes + If true, use time average for aux file output. + + .true. + + + + char + aux_hist + MED_attributes + Number of time sames per file. + + 1 + + + + char + aux_hist + MED_attributes + Auxiliary name identifier in history name + + lnd.1yr.avrg + + + + + + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator history for ocn import/export/fields snapshot option (used with history_n and history_ymd) + + + $HIST_OPTION_OCN + + + + integer + time + MED_attributes + + sets mediator snapshot history file frequency for ocn import/export fields (like restart_n) + + + $HIST_N_OCN + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator time average history option (used with histavg_n and histavg_ymd) + + + $AVGHIST_OPTION_OCN + + + + integer + time + MED_attributes + + Sets mediator time-average history file frequency (like restart_option) + + + $AVGHIST_N_OCN + + + + + + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator history for rof import/export/fields snapshot option (used with history_n and history_ymd) + + + $HIST_OPTION_ROF + + + + integer + time + MED_attributes + + sets mediator snapshot history file frequency for rof import/export fields (like restart_n) + + + $HIST_N_ROF + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end + + mediator time average history option (used with histavg_n and histavg_ymd) + + + $AVGHIST_OPTION_ROF + + + + integer + time + MED_attributes + + Sets mediator time-average history file frequency (like restart_option) + + + $AVGHIST_N_ROF + + + + + + logical + aux_hist + MED_attributes + Auxiliary mediator rof2med precipitation history output every 3 hours + + .false. + + + + char + aux_hist + MED_attributes + Auxiliary mediator rof2med precipitation history output. + + all + + + + char + aux_hist + MED_attributes + history option type + + ndays + + + + char + aux_hist + MED_attributes + history option type + + 1 + + + + char + aux_hist + MED_attributes + If true, use time average for aux file output. + + .true. + + + + char + aux_hist + MED_attributes + Number of time sames per file. 1 + + char + aux_hist + MED_attributes + Auxiliary name identifier in history name + + rof.24h.avrg + + - - integer - expdef - ALLCOMP_attributes + + + + + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end - index of scalar containing global grid cell count in Y dimension + mediator history for wav import/export/fields snapshot option (used with history_n and history_ymd) - 2 + $HIST_OPTION_WAV - - + integer - expdef - ALLCOMP_attributes + time + MED_attributes - index of scalar containing calendar day of nextsw computation from atm + sets mediator snapshot history file frequency for wav import/export fields (like restart_n) - 3 + $HIST_N_WAV - - - integer - expdef - ALLCOMP_attributes + + char + time + MED_attributes + none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end - index of scalar containing epbal precipitation factor from ocn (only for POP) + mediator time average history option (used with histavg_n and histavg_ymd) - 4 - 0 + $AVGHIST_OPTION_WAV - - + integer - expdef - ALLCOMP_attributes + time + MED_attributes - number of glc ice sheets + Sets mediator time-average history file frequency (like restart_option) - 1 + $AVGHIST_N_WAV + + + + logical mapping @@ -2005,6 +2555,55 @@ + + char + mapping + abs + MED_attributes + + land to glc mapping file for fluxes + + + $LND2GLC_FMAPNAME + + + + char + mapping + abs + MED_attributes + + land to glc mapping file for states + + + $LND2GLC_SMAPNAME + + + + char + mapping + abs + MED_attributes + + glc to land mapping file for fluxes + + + $GLC2LND_FMAPNAME + + + + char + mapping + abs + MED_attributes + + glc to land mapping file for states + + + $GLC2LND_SMAPNAME + + + char mapping @@ -2070,6 +2669,95 @@ + + + + + + char + expdef + ALLCOMP_attributes + + name of the coupling field with scalar information + + + cpl_scalars + + + + + integer + expdef + ALLCOMP_attributes + + total number of scalars in the scalar coupling field + + + 4 + + + + + integer + expdef + ALLCOMP_attributes + + index of scalar containing global grid cell count in X dimension + + + 1 + + + + + integer + expdef + ALLCOMP_attributes + + index of scalar containing global grid cell count in Y dimension + + + 2 + + + + + integer + expdef + ALLCOMP_attributes + + index of scalar containing calendar day of nextsw computation from atm + + + 3 + + + + + integer + expdef + ALLCOMP_attributes + + index of scalar containing epbal precipitation factor from ocn (only for POP) + + + 4 + 0 + + + + + integer + expdef + ALLCOMP_attributes + + number of glc ice sheets + + + 1 + + + logical flds @@ -2505,112 +3193,6 @@ - - char - time - CLOCK_attributes - none,never,nsteps,nstep,nseconds,nsecond,nminutes,nminute,nhours,nhour,ndays,nday,monthly,nmonths,nmonth,nyears,nyear,date,ifdays0,end - - coupler history snapshot option (used with history_n and history_ymd) - set by HIST_OPTION in env_run.xml. - history_option alarms are: - [none/never], turns option off - [nstep/s] , history snapshot every history_n nsteps , relative to current run start time - [nsecond/s] , history snapshot every history_n nseconds, relative to current run start time - [nminute/s] , history snapshot every history_n nminutes, relative to current run start time - [nhour/s] , history snapshot every history_n nhours , relative to current run start time - [nday/s] , history snapshot every history_n ndays , relative to current run start time - [monthly/s] , history snapshot every month , relative to current run start time - [nmonth/s] , history snapshot every history_n nmonths , relative to current run start time - [nyear/s] , history snapshot every history_n nyears , relative to current run start time - [date] , history snapshot at history_ymd value - [ifdays0] , history snapshot at history_n calendar day value and seconds equal 0 - [end] , history snapshot at end - - - $HIST_OPTION - - - - - integer - time - CLOCK_attributes - - sets coupler snapshot history file frequency (like restart_n) - set by HIST_N in env_run.xml. - - - $HIST_N - - - - - integer - time - CLOCK_attributes - - date associated with history_option date. yyyymmdd format. - set by HIST_DATE in env_run.xml. - - - $HIST_DATE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - char time diff --git a/cime_config/runseq/driver_config.py b/cime_config/runseq/driver_config.py index 8251eeebb..8ee1573b2 100644 --- a/cime_config/runseq/driver_config.py +++ b/cime_config/runseq/driver_config.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Inherit from the dictionary class class DriverConfig(dict): @@ -152,6 +152,9 @@ def __compute_rof(self, case, coupling_times): # If the prognostic flag is on, then should set med_to_rof to True if_prognostic = False med_to_rof = if_prognostic + elif case.get_value("PTS_MODE"): + run_rof = False + med_to_rof = False else: # this is active runoff - determine if the mode or the grid is null - and in that case # remove all interactions with rof from the run sequence diff --git a/cime_config/runseq/gen_runseq.py b/cime_config/runseq/gen_runseq.py index 29d1616bf..ab68327ec 100644 --- a/cime_config/runseq/gen_runseq.py +++ b/cime_config/runseq/gen_runseq.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 class RunSeq: def __init__(self, outfile): @@ -46,9 +46,9 @@ def leave_time_loop(self, leave_time, if_write_hist_rest=False ): if leave_time and self.__time_loop: _, active_depth = self.__time_loop.pop() if if_write_hist_rest or active_depth == 0: - self.__outfile.write (" MED med_phases_history_write \n" ) - self.__outfile.write (" MED med_phases_restart_write \n" ) - self.__outfile.write (" MED med_phases_profile \n" ) + self.__outfile.write (" MED med_phases_history_write \n" ) + self.__outfile.write (" MED med_phases_restart_write \n" ) + self.__outfile.write (" MED med_phases_profile \n" ) self.__outfile.write ("@ \n" ) def __exit_sequence(self): diff --git a/cime_config/runseq/runseq_D.py b/cime_config/runseq/runseq_D.py index 3d108fe30..916a8628b 100644 --- a/cime_config/runseq/runseq_D.py +++ b/cime_config/runseq/runseq_D.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os, shutil, sys from CIME.utils import expect diff --git a/cime_config/runseq/runseq_TG.py b/cime_config/runseq/runseq_TG.py index 861d127d7..a826d92df 100644 --- a/cime_config/runseq/runseq_TG.py +++ b/cime_config/runseq/runseq_TG.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os, shutil, sys from CIME.utils import expect @@ -36,7 +36,7 @@ def gen_runseq(case, coupling_times): runseq.add_action ("MED -> GLC :remapMethod=redist" , med_to_glc) runseq.add_action ("GLC" , run_glc) runseq.add_action ("GLC -> MED :remapMethod=redist" , run_glc) - runseq.add_action ("MED med_phases_history_write" , True) + runseq.add_action ("MED med_phases_history_write_all_inst", True) runseq.leave_time_loop(True) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index db323b3c2..6a72d3cff 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import os, shutil, sys from CIME.utils import expect @@ -49,13 +49,18 @@ def gen_runseq(case, coupling_times): post_glc = True # Note: assume that atm_cpl_dt, lnd_cpl_dt, ice_cpl_dt and wav_cpl_dt are the same - if lnd_cpl_time != atm_cpl_time: expect(False, "assume that lnd_cpl_time is equal to atm_cpl_time") if ice_cpl_time != atm_cpl_time: expect(False, "assume that ice_cpl_time is equal to atm_cpl_time") if wav_cpl_time != atm_cpl_time: expect(False, "assume that wav_cpl_time is equal to atm_cpl_time") + + # assume that atm coupling time is always less than or equal to ocean coupling time + if atm_cpl_time > ocn_cpl_time: + expect(False, "assume that atm_cpl_time is always less or equal to ocn_cpl_time") + + # assume that rof coupling time is always greater than or equal to ocean coupling time if rof_cpl_time < ocn_cpl_time: expect(False, "assume that rof_cpl_time is always greater than or equal to ocn_cpl_time") diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index c46635818..f6d88ab46 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -106,10 +106,6 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) end if ! unused fields from ice - but that are needed to be realized by the cice cap - call addfld(fldListFr(compice)%flds, 'Si_avsdf') - call addfld(fldListFr(compice)%flds, 'Si_avsdr') - call addfld(fldListFr(compice)%flds, 'Si_anidf') - call addfld(fldListFr(compice)%flds, 'Si_anidr') call addfld(fldListFr(compice)%flds, 'Faii_evap') call addfld(fldListFr(compice)%flds, 'mean_sw_pen_to_ocn') @@ -145,6 +141,18 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) end do deallocate(flds) + allocate(flds(4)) + flds = (/'avsdr ', 'avsdf ', & + 'anidr ', 'anidf '/) + do n = 1,size(flds) + fldname = 'Si_'//trim(flds(n)) + call addfld(fldListFr(compice)%flds, trim(fldname)) + call addfld(fldListTo(compatm)%flds, trim(fldname)) + call addmap(fldListFr(compice)%flds, trim(fldname), compatm, maptype, 'ifrac', 'unset') + call addmrg(fldListTo(compatm)%flds, trim(fldname), mrg_from=compice, mrg_fld=trim(fldname), mrg_type='copy') + end do + deallocate(flds) + ! to atm: unmerged surface temperatures from ocn call addfld(fldListFr(compocn)%flds, 'So_t') call addfld(fldListTo(compatm)%flds, 'So_t') diff --git a/mediator/med.F90 b/mediator/med.F90 index 53c8698eb..d1263429d 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -89,6 +89,14 @@ subroutine SetServices(gcomp, rc) use NUOPC_Mediator , only: mediator_label_SetRunClock => label_SetRunClock use NUOPC_Mediator , only: mediator_label_Finalize => label_Finalize use med_phases_history_mod , only: med_phases_history_write + use med_phases_history_mod , only: med_phases_history_write_atm + use med_phases_history_mod , only: med_phases_history_write_ice + use med_phases_history_mod , only: med_phases_history_write_glc + use med_phases_history_mod , only: med_phases_history_write_lnd + use med_phases_history_mod , only: med_phases_history_write_ocn + use med_phases_history_mod , only: med_phases_history_write_rof + use med_phases_history_mod , only: med_phases_history_write_wav + use med_phases_history_mod , only: med_phases_history_write_med use med_phases_restart_mod , only: med_phases_restart_write use med_phases_prep_atm_mod , only: med_phases_prep_atm use med_phases_prep_ice_mod , only: med_phases_prep_ice @@ -190,7 +198,7 @@ subroutine SetServices(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ - ! setup mediator history phase + ! setup mediator history phases for all output !------------------ call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & @@ -199,6 +207,94 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_history_write", specRoutine=med_phases_history_write, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !------------------ + ! setup mediator history phases for atm output + !------------------ + + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_history_write_atm"/), userRoutine=mediator_routine_Run, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & + specPhaseLabel="med_phases_history_write_atm", specRoutine=med_phases_history_write_atm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !------------------ + ! setup mediator history phases for ice output + !------------------ + + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_history_write_ice"/), userRoutine=mediator_routine_Run, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & + specPhaseLabel="med_phases_history_write_ice", specRoutine=med_phases_history_write_ice, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !------------------ + ! setup mediator history phases for glc output + !------------------ + + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_history_write_glc"/), userRoutine=mediator_routine_Run, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & + specPhaseLabel="med_phases_history_write_glc", specRoutine=med_phases_history_write_glc, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !------------------ + ! setup mediator history phases for lnd output + !------------------ + + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_history_write_lnd"/), userRoutine=mediator_routine_Run, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & + specPhaseLabel="med_phases_history_write_lnd", specRoutine=med_phases_history_write_lnd, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !------------------ + ! setup mediator history phases for ocn output + !------------------ + + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_history_write_ocn"/), userRoutine=mediator_routine_Run, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & + specPhaseLabel="med_phases_history_write_ocn", specRoutine=med_phases_history_write_ocn, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !------------------ + ! setup mediator history phases for rof output + !------------------ + + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_history_write_rof"/), userRoutine=mediator_routine_Run, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & + specPhaseLabel="med_phases_history_write_rof", specRoutine=med_phases_history_write_rof, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !------------------ + ! setup mediator history phases for wav output + !------------------ + + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_history_write_wav"/), userRoutine=mediator_routine_Run, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & + specPhaseLabel="med_phases_history_write_wav", specRoutine=med_phases_history_write_wav, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !------------------ + ! setup mediator history phases for med output + !------------------ + + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_history_write_med"/), userRoutine=mediator_routine_Run, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & + specPhaseLabel="med_phases_history_write_med", specRoutine=med_phases_history_write_med, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & specPhaselabel="med_phases_history_write", specRoutine=NUOPC_NoOp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -801,7 +897,7 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) 'rof_present','wav_present','glc_present','med_present'/), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - med_present = "false" + med_present = "true" atm_present = "false" lnd_present = "false" ocn_present = "false" @@ -881,7 +977,9 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompAttributeSet(gcomp, name="glc_present", value=trim(glc_present), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeSet(gcomp, name="med_present", value=med_present, rc=rc) + + ! Mediator is always present inside the mediator + call NUOPC_CompAttributeSet(gcomp, name="med_present", value="true", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (mastertask) then @@ -949,7 +1047,8 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) else transferOffer = 'cannot provide' end if - call NUOPC_Advertise(is_local%wrap%NStateImp(ncomp), standardName=stdname, shortname=shortname, name=shortname, & + call NUOPC_Advertise(is_local%wrap%NStateImp(ncomp), & + standardName=stdname, shortname=shortname, name=shortname, & TransferOfferGeomObject=transferOffer, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(subname//':Fr_'//trim(compname(ncomp))//': '//trim(shortname), ESMF_LOGMSG_INFO) @@ -967,7 +1066,8 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) else transferOffer = 'cannot provide' end if - call NUOPC_Advertise(is_local%wrap%NStateExp(ncomp), standardName=stdname, shortname=shortname, name=shortname, & + call NUOPC_Advertise(is_local%wrap%NStateExp(ncomp), & + standardName=stdname, shortname=shortname, name=shortname, & TransferOfferGeomObject=transferOffer, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite(subname//':To_'//trim(compname(ncomp))//': '//trim(shortname), ESMF_LOGMSG_INFO) @@ -1669,6 +1769,7 @@ subroutine completeFieldInitialization(State,rc) purpose="Instance", valueList=ungriddedLBound, rc=rc) call ESMF_AttributeGet(fieldList(n), name="UngriddedUBound", convention="NUOPC", & purpose="Instance", valueList=ungriddedUBound, rc=rc) + call ESMF_LogWrite(subname//" "//trim(fieldName) // "has ungriddedcount > 0 ",ESMF_LOGMSG_INFO, rc=rc) endif call ESMF_FieldEmptyComplete(fieldList(n), typekind=ESMF_TYPEKIND_R8, gridToFieldMap=gridToFieldMap, & @@ -2404,7 +2505,7 @@ subroutine DataInitialize(gcomp, rc) is_local%wrap%ny(n1) = nint(real_ny) write(msgString,'(2i8,2l4)') is_local%wrap%nx(n1), is_local%wrap%ny(n1) if (mastertask) then - write(logunit,*) 'global nx,ny sizes for '//trim(compname(n1))//":"//trim(msgString) + write(logunit,'(a)') 'global nx,ny sizes for '//trim(compname(n1))//":"//trim(msgString) end if call ESMF_LogWrite(trim(subname)//":"//trim(compname(n1))//":"//trim(msgString), ESMF_LOGMSG_INFO) end if @@ -2496,16 +2597,15 @@ subroutine DataInitialize(gcomp, rc) end subroutine DataInitialize !----------------------------------------------------------------------------- - subroutine SetRunClock(gcomp, rc) - use ESMF , only : ESMF_GridComp, ESMF_CLOCK, ESMF_Time, ESMF_TimeInterval - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_ClockGet, ESMF_ClockSet - use ESMF , only : ESMF_Success, ESMF_Failure - use ESMF , only : ESMF_Alarm, ESMF_ALARMLIST_ALL, ESMF_ClockGetAlarmList - use ESMF , only : ESMF_AlarmCreate, ESMF_AlarmSet, ESMF_ClockAdvance - use NUOPC , only : NUOPC_CompCheckSetClock, NUOPC_CompAttributeGet - use NUOPC_Mediator , only : NUOPC_MediatorGet + use ESMF , only : ESMF_GridComp, ESMF_CLOCK, ESMF_Time, ESMF_TimeInterval + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_ClockGet, ESMF_ClockSet + use ESMF , only : ESMF_Success, ESMF_Failure + use ESMF , only : ESMF_Alarm, ESMF_ALARMLIST_ALL, ESMF_ClockGetAlarmList + use ESMF , only : ESMF_AlarmCreate, ESMF_AlarmSet, ESMF_ClockAdvance + use NUOPC , only : NUOPC_CompCheckSetClock, NUOPC_CompAttributeGet + use NUOPC_Mediator , only : NUOPC_MediatorGet ! input/output variables type(ESMF_GridComp) :: gcomp diff --git a/mediator/med_io_mod.F90 b/mediator/med_io_mod.F90 index bb156258e..e95ecc11c 100644 --- a/mediator/med_io_mod.F90 +++ b/mediator/med_io_mod.F90 @@ -7,9 +7,9 @@ module med_io_mod use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, I8=>SHR_KIND_I8, R8=>SHR_KIND_R8 use med_kind_mod , only : R4=>SHR_KIND_R4 use shr_const_mod , only : fillvalue => SHR_CONST_SPVAL - use ESMF , only : ESMF_VM, ESMF_LogWrite, ESMF_LOGMSG_INFO - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_VMGetCurrent, ESMF_VMGet, ESMF_VMBroadCast, ESMF_GridComp + use ESMF , only : ESMF_VM, ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LogFoundError + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_END_ABORT, ESMF_LOGERR_PASSTHRU + use ESMF , only : ESMF_VMGetCurrent, ESMF_VMGet, ESMF_VMBroadCast, ESMF_Finalize use NUOPC , only : NUOPC_FieldDictionaryGetEntry use NUOPC , only : NUOPC_FieldDictionaryHasEntry use pio , only : file_desc_t, iosystem_desc_t @@ -70,16 +70,13 @@ module med_io_mod module procedure med_io_ymd2date_long end interface med_io_ymd2date - !------------------------------------------------------------------------------- ! module data - !------------------------------------------------------------------------------- - character(*),parameter :: prefix = "med_io_" character(*),parameter :: modName = "(med_io_mod) " character(*),parameter :: version = "cmeps0" + integer , parameter :: number_strlen = 8 integer , parameter :: file_desc_t_cnt = 20 ! Note - this is hard-wired for now - integer , parameter :: number_strlen = 2 - character(CL) :: wfilename = '' + character(CL) :: wfilename(0:file_desc_t_cnt) = '' type(file_desc_t) :: io_file(0:file_desc_t_cnt) integer :: pio_iotype integer :: pio_ioformat @@ -539,7 +536,7 @@ subroutine med_io_wopen(filename, vm, iam, clobber, file_ind, model_doi_url) if (.not. pio_file_is_open(io_file(lfile_ind))) then ! filename not open - wfilename = filename + wfilename(lfile_ind) = trim(filename) if (med_io_file_exists(vm, iam, filename)) then if (lclobber) then @@ -549,14 +546,12 @@ subroutine med_io_wopen(filename, vm, iam, clobber, file_ind, model_doi_url) nmode = ior(nmode,pio_ioformat) endif rcode = pio_createfile(io_subsystem, io_file(lfile_ind), pio_iotype, trim(filename), nmode) - if(iam==0) write(logunit,*) subname,' create file ',trim(filename) + if(iam==0) write(logunit,'(a)') trim(subname)//' creating file '//trim(filename) rcode = pio_put_att(io_file(lfile_ind),pio_global,"file_version",version) rcode = pio_put_att(io_file(lfile_ind),pio_global,"model_doi_url",lmodel_doi_url) else rcode = pio_openfile(io_subsystem, io_file(lfile_ind), pio_iotype, trim(filename), pio_write) - if (iam==0) then - write(logunit,*) subname,' open file ',trim(filename) - end if + if (iam==0) write(logunit,'(a)') trim(subname)//' opening file '//trim(filename) call pio_seterrorhandling(io_file(lfile_ind),PIO_BCAST_ERROR) rcode = pio_get_att(io_file(lfile_ind),pio_global,"file_version",lversion) call pio_seterrorhandling(io_file(lfile_ind),PIO_INTERNAL_ERROR) @@ -573,19 +568,21 @@ subroutine med_io_wopen(filename, vm, iam, clobber, file_ind, model_doi_url) nmode = ior(nmode,pio_ioformat) endif rcode = pio_createfile(io_subsystem, io_file(lfile_ind), pio_iotype, trim(filename), nmode) - if (iam==0) then - write(logunit,*) subname,' create file ',trim(filename) - end if + if (iam==0) write(logunit,'(a)') trim(subname) //' creating file '// trim(filename) rcode = pio_put_att(io_file(lfile_ind),pio_global,"file_version",version) rcode = pio_put_att(io_file(lfile_ind),pio_global,"model_doi_url",lmodel_doi_url) endif - elseif (trim(wfilename) /= trim(filename)) then + + elseif (trim(wfilename(lfile_ind)) /= trim(filename)) then ! filename is open, better match open filename - if(iam==0) write(logunit,*) subname,' different filename currently open ',trim(filename) - if(iam==0) write(logunit,*) subname,' different wfilename currently open ',trim(wfilename) - call ESMF_LogWrite(subname//'different file currently open '//trim(filename), ESMF_LOGMSG_INFO) + if (iam==0) then + write(logunit,'(a)') trim(subname)//' different filename currently open '//trim(filename) + write(logunit,'(a)') trim(subname)//' different wfilename currently open '//trim(wfilename(lfile_ind)) + end if + call ESMF_LogWrite(trim(subname)//'different file currently open '//trim(filename), ESMF_LOGMSG_INFO) rc = ESMF_FAILURE return + else ! filename is already open, just return endif @@ -619,18 +616,25 @@ subroutine med_io_close(filename, iam, file_ind, rc) if (.not. pio_file_is_open(io_file(lfile_ind))) then ! filename not open, just return - elseif (trim(wfilename) == trim(filename)) then + elseif (trim(wfilename(lfile_ind)) == trim(filename)) then ! filename matches, close it call pio_closefile(io_file(lfile_ind)) + !wfilename(lfile_ind) = '' else ! different filename is open, abort - if (iam==0) write(logunit,*) subname,' different filename currently open, aborting ',trim(filename) - if (iam==0) write(logunit,*) subname,' different wfilename currently open, aborting ',trim(wfilename) + if (iam==0) then + write(logunit,*) subname,' different wfilename and filename currently open, aborting ' + write(logunit,'(a)') 'filename = ',trim(filename) + write(logunit,'(a)') 'wfilename = ',trim(wfilename(lfile_ind)) + write(logunit,'(i6)')'lfile_ind = ',lfile_ind + end if call ESMF_LogWrite(subname//'different file currently open, aborting '//trim(filename), ESMF_LOGMSG_INFO) rc = ESMF_FAILURE - return + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if endif - wfilename = '' + end subroutine med_io_close !=============================================================================== @@ -729,7 +733,7 @@ end function med_io_sec2hms !=============================================================================== subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & - fillval, pre, tavg, use_float, file_ind, rc) + fillval, pre, flds, tavg, use_float, file_ind, rc) !--------------- ! Write FB to netcdf file @@ -755,6 +759,7 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & integer , optional, intent(in) :: nt ! time sample real(r8), optional, intent(in) :: fillval ! fill value character(len=*), optional, intent(in) :: pre ! prefix to variable name + character(len=*), optional, intent(in) :: flds(:) ! specific fields to write out logical, optional, intent(in) :: tavg ! is this a tavg logical, optional, intent(in) :: use_float ! write output as float rather than double integer, optional, intent(in) :: file_ind @@ -801,37 +806,24 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields integer :: gridToFieldMap(1) ! currently the size must equal 1 for rank 2 fields logical :: isPresent + character(CL), allocatable :: fieldNameList(:) character(*),parameter :: subName = '(med_io_write_FB) ' !------------------------------------------------------------------------------- - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif rc = ESMF_Success lfillvalue = fillvalue - if (present(fillval)) then - lfillvalue = fillval - endif - + if (present(fillval)) lfillvalue = fillval lpre = ' ' - if (present(pre)) then - lpre = trim(pre) - endif - - if (.not. ESMF_FieldBundleIsCreated(FB, rc=rc)) then - call ESMF_LogWrite(trim(subname)//" FB "//trim(lpre)//" not created", ESMF_LOGMSG_INFO) - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - endif - rc = ESMF_Success - return - endif - + if (present(pre)) lpre = trim(pre) lwhead = .true. - lwdata = .true. if (present(whead)) lwhead = whead + lwdata = .true. if (present(wdata)) lwdata = wdata + luse_float = .false. + if (present(use_float)) luse_float = use_float + lfile_ind = 0 + if (present(file_ind)) lfile_ind=file_ind if (.not.lwhead .and. .not.lwdata) then ! should we write a warning? @@ -841,17 +833,9 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & return endif - luse_float = .false. - if (present(use_float)) luse_float = use_float - - lfile_ind = 0 - if (present(file_ind)) lfile_ind=file_ind - - call ESMF_FieldBundleGet(FB, fieldCount=nf, rc=rc) - write(tmpstr,*) subname//' field count = '//trim(lpre),nf - call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - if (nf < 1) then - call ESMF_LogWrite(trim(subname)//" FB "//trim(lpre)//" empty", ESMF_LOGMSG_INFO) + ! Error check + if (.not. ESMF_FieldBundleIsCreated(FB, rc=rc)) then + call ESMF_LogWrite(trim(subname)//" FB "//trim(lpre)//" not created", ESMF_LOGMSG_INFO) if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif @@ -859,43 +843,60 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & return endif + ! Get number of fields + if (present(flds)) then + nf = size(flds) + else + call ESMF_FieldBundleGet(FB, fieldCount=nf, rc=rc) + write(tmpstr,*) subname//' field count = '//trim(lpre), nf + call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + if (nf < 1) then + call ESMF_LogWrite(trim(subname)//" FB "//trim(lpre)//" empty", ESMF_LOGMSG_INFO) + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + endif + rc = ESMF_Success + return + endif + allocate(fieldNameList(nf)) + call ESMF_FieldBundleGet(FB, fieldNameList=fieldNameList, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + + ! Get field bundle mesh from first field call FB_getFieldN(FB, 1, field, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field, mesh=mesh, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Get mesh distgrid and number of elements call ESMF_MeshGet(mesh, elementDistgrid=distgrid, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(mesh, spatialDim=ndims, numOwnedElements=nelements, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - write(tmpstr,*) subname, 'ndims, nelements = ', ndims, nelements call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + ! Set element coordinates if (.not. allocated(ownedElemCoords) .and. ndims > 0 .and. nelements > 0) then allocate(ownedElemCoords(ndims*nelements)) allocate(ownedElemCoords_x(ndims*nelements/2)) allocate(ownedElemCoords_y(ndims*nelements/2)) - call ESMF_MeshGet(mesh, ownedElemCoords=ownedElemCoords, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ownedElemCoords_x = ownedElemCoords(1::2) ownedElemCoords_y = ownedElemCoords(2::2) end if + ! Get tile info call ESMF_DistGridGet(distgrid, dimCount=dimCount, tileCount=tileCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(minIndexPTile(dimCount, tileCount), maxIndexPTile(dimCount, tileCount)) call ESMF_DistGridGet(distgrid, minIndexPTile=minIndexPTile, maxIndexPTile=maxIndexPTile, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! write(tmpstr,*) subname,' counts = ',dimcount,tilecount,minindexptile,maxindexptile ! call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - ! TODO: this is not getting the global size correct for a FB coming in that does not have ! all the global grid values in the distgrid - e.g. CTSM @@ -923,24 +924,28 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & !return endif + ! Write header if (lwhead) then - rcode = pio_def_dim(io_file(lfile_ind),trim(lpre)//'_nx',lnx,dimid2(1)) - rcode = pio_def_dim(io_file(lfile_ind),trim(lpre)//'_ny',lny,dimid2(2)) - + rcode = pio_def_dim(io_file(lfile_ind), trim(lpre)//'_nx', lnx, dimid2(1)) + rcode = pio_def_dim(io_file(lfile_ind), trim(lpre)//'_ny', lny, dimid2(2)) if (present(nt)) then dimid3(1:2) = dimid2 - rcode = pio_inq_dimid(io_file(lfile_ind),'time',dimid3(3)) + rcode = pio_inq_dimid(io_file(lfile_ind), 'time', dimid3(3)) dimid => dimid3 else dimid => dimid2 endif - write(tmpstr,*) subname,' dimid = ',dimid call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) do k = 1,nf - call FB_getNameN(FB, k, itemc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Determine field name + if (present(flds)) then + itemc = trim(flds(k)) + else + itemc = trim(fieldNameList(k)) + end if ! Determine rank of field with name itemc call ESMF_FieldBundleGet(FB, itemc, field=lfield, rc=rc) @@ -1031,7 +1036,6 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & ! Finish define mode if (lwdata) call med_io_enddef(filename, file_ind=lfile_ind) - end if if (lwdata) then @@ -1043,16 +1047,17 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & call ESMF_DistGridGet(distgrid, localDE=0, seqIndexList=dof, rc=rc) write(tmpstr,*) subname,' dof = ',ns,size(dof),dof(1),dof(ns) !,minval(dof),maxval(dof) call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - call pio_initdecomp(io_subsystem, pio_double, (/lnx,lny/), dof, iodesc) - ! call pio_writedof(lpre, (/lnx,lny/), int(dof,kind=PIO_OFFSET_KIND), mpicom) - deallocate(dof) do k = 1,nf - call FB_getNameN(FB, k, itemc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! Determine field name + if (present(flds)) then + itemc = trim(flds(k)) + else + itemc = trim(fieldNameList(k)) + end if call FB_getFldPtr(FB, itemc, & fldptr1=fldptr1, fldptr2=fldptr2, rank=rank, rc=rc) @@ -1091,7 +1096,7 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & end if ! end if not "hgt" end do ! end loop over fields in FB - ! Fill coordinate variables + ! Fill coordinate variables - why is this being done each time? name1 = trim(lpre)//'_lon' rcode = pio_inq_varid(io_file(lfile_ind), trim(name1), varid) call pio_setframe(io_file(lfile_ind),varid,frame) @@ -1169,7 +1174,6 @@ subroutine med_io_write_int(filename, iam, idata, dname, whead, wdata, file_ind, if (lwdata) then rcode = pio_inq_varid(io_file(lfile_ind),trim(dname),varid) rcode = pio_put_var(io_file(lfile_ind),varid,idata) - ! write(logunit,*) subname,' wrote AV ',trim(dname),lwhead,lwdata endif end subroutine med_io_write_int @@ -1234,15 +1238,11 @@ subroutine med_io_write_int1d(filename, iam, idata, dname, whead, wdata, file_in rcode = pio_def_var(io_file(lfile_ind),trim(dname),PIO_INT,dimid,varid) rcode = pio_put_att(io_file(lfile_ind),varid,"standard_name",trim(dname)) if (lwdata) call med_io_enddef(filename, file_ind=lfile_ind) - endif - - if (lwdata) then + else if (lwdata) then rcode = pio_inq_varid(io_file(lfile_ind),trim(dname),varid) rcode = pio_put_var(io_file(lfile_ind),varid,idata) endif - ! write(logunit,*) subname,' wrote AV ',trim(dname),lwhead,lwdata - end subroutine med_io_write_int1d !=============================================================================== @@ -1299,9 +1299,7 @@ subroutine med_io_write_r8(filename, iam, rdata, dname, whead, wdata, file_ind, rcode = pio_put_att(io_file(lfile_ind),varid,"standard_name",trim(dname)) if (lwdata) call med_io_enddef(filename, file_ind=lfile_ind) end if - endif - - if (lwdata) then + else if (lwdata) then rcode = pio_inq_varid(io_file(lfile_ind),trim(dname),varid) rcode = pio_put_var(io_file(lfile_ind),varid,rdata) endif @@ -1415,6 +1413,7 @@ subroutine med_io_write_char(filename, iam, rdata, dname, whead, wdata, file_ind if (present(wdata)) lwdata = wdata lfile_ind = 0 if (present(file_ind)) lfile_ind=file_ind + if (.not.lwhead .and. .not.lwdata) then ! should we write a warning? return @@ -1430,8 +1429,7 @@ subroutine med_io_write_char(filename, iam, rdata, dname, whead, wdata, file_ind end if rcode = pio_put_att(io_file(lfile_ind),varid,"standard_name",trim(dname)) if (lwdata) call med_io_enddef(filename, file_ind=lfile_ind) - endif - if (lwdata) then + else if (lwdata) then charvar = '' charvar = trim(rdata) rcode = pio_inq_varid(io_file(lfile_ind),trim(dname),varid) @@ -1491,17 +1489,18 @@ subroutine med_io_write_time(filename, iam, time_units, calendar, time_val, nt,& if (present(wdata)) lwdata = wdata lfile_ind = 0 if (present(file_ind)) lfile_ind=file_ind + if (.not.lwhead .and. .not.lwdata) then ! should we write a warning? return endif - ! Write out header - if (lwhead) then + if (lwhead) then ! Write out header + + ! define time rcode = pio_def_dim(io_file(lfile_ind),'time',PIO_UNLIMITED,dimid(1)) rcode = pio_def_var(io_file(lfile_ind),'time',PIO_DOUBLE,dimid,varid) rcode = pio_put_att(io_file(lfile_ind),varid,'units',trim(time_units)) - if (calendar == ESMF_CALKIND_360DAY) then calname = '360_day' else if (calendar == ESMF_CALKIND_GREGORIAN) then @@ -1519,6 +1518,7 @@ subroutine med_io_write_time(filename, iam, time_units, calendar, time_val, nt,& end if rcode = pio_put_att(io_file(lfile_ind),varid,'calendar',trim(calname)) + ! define time bounds if (present(tbnds)) then dimid2(2) = dimid(1) rcode = pio_put_att(io_file(lfile_ind),varid,'bounds','time_bnds') @@ -1526,28 +1526,33 @@ subroutine med_io_write_time(filename, iam, time_units, calendar, time_val, nt,& rcode = pio_def_var(io_file(lfile_ind),'time_bnds',PIO_DOUBLE,dimid2,varid) endif if (lwdata) call med_io_enddef(filename, file_ind=lfile_ind) - endif - ! Write out data - if (lwdata) then + else if (lwdata) then ! Write out data + + ! write time start = 1 count = 1 if (present(nt)) then start(1) = nt endif time_val_1d(1) = time_val - rcode = pio_inq_varid(io_file(lfile_ind),'time',varid) - rcode = pio_put_var(io_file(lfile_ind),varid,start,count,time_val_1d) + rcode = pio_inq_varid(io_file(lfile_ind), 'time', varid) + rcode = pio_put_var(io_file(lfile_ind), varid, start(1:1), count(1:1), time_val_1d) + + ! write time bounds if (present(tbnds)) then - rcode = pio_inq_varid(io_file(lfile_ind),'time_bnds',varid) - start = 1 - count = 1 + rcode = pio_inq_varid(io_file(lfile_ind), 'time_bnds', varid) + count(1) = 2 + count(2) = 1 + start(1) = 1 if (present(nt)) then start(2) = nt + else + start(2) = 1 endif - count(1) = 2 - rcode = pio_put_var(io_file(lfile_ind),varid,start,count,tbnds) + rcode = pio_put_var(io_file(lfile_ind), varid, start(1:2), count(1:2), tbnds) endif + endif end subroutine med_io_write_time diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90 index 893393d2c..ed55c9d31 100644 --- a/mediator/med_phases_history_mod.F90 +++ b/mediator/med_phases_history_mod.F90 @@ -11,38 +11,111 @@ module med_phases_history_mod ! the run sequence provided by freeFormat, this loop becomes the driver ! loop level directly. Therefore, setting the timeStep or runDuration ! for the outer most time loop results modifiying the driver clock - ! itself. However, for cases with concatenated loops on the upper level + ! itself. However, for cases with cocnatenated loops on the upper level ! of the run sequence in freeFormat, a single outer loop is added ! automatically during ingestion, and the driver clock is used for this ! loop instead. !----------------------------------------------------------------------------- use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - use ESMF , only : ESMF_Alarm - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag - use med_constants_mod , only : SecPerDay => med_constants_SecPerDay - use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_methods_mod , only : FB_reset => med_methods_FB_reset - use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_accum => med_methods_FB_accum - use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_VM, ESMF_VMGet + use ESMF , only : ESMF_Clock, ESMF_ClockGet, ESMF_ClockSet, ESMF_ClockAdvance, ESMF_ClockCreate + use ESMF , only : ESMF_ClockGetNextTime, ESMF_ClockGetAlarm, ESMF_ClockIsCreated + use ESMF , only : ESMF_Calendar + use ESMF , only : ESMF_Time, ESMF_TimeGet + use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalGet, ESMF_TimeIntervalSet + use ESMF , only : ESMF_Alarm, ESMF_AlarmCreate, ESMF_AlarmSet + use ESMF , only : ESMF_AlarmIsRinging, ESMF_AlarmRingerOff, ESMF_AlarmGet + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF , only : ESMF_FieldBundleIsCreated, ESMF_FieldBundleRemove + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR, ESMF_LogFoundError + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE, ESMF_MAXSTR, ESMF_LOGERR_PASSTHRU, ESMF_END_ABORT + use ESMF , only : ESMF_Finalize + use ESMF , only : operator(==), operator(-), operator(+), operator(/=), operator(<=) + use NUOPC , only : NUOPC_CompAttributeGet + use NUOPC_Model , only : NUOPC_ModelGet + use esmFlds , only : compmed, compatm, complnd, compocn, compice, comprof, compglc, compwav + use esmFlds , only : ncomps, compname, num_icesheets + use esmFlds , only : fldListFr, fldListTo + use med_constants_mod , only : SecPerDay => med_constants_SecPerDay + use med_constants_mod , only : czero => med_constants_czero + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_methods_mod , only : med_methods_FB_reset + use med_methods_mod , only : med_methods_FB_accum + use med_methods_mod , only : med_methods_FB_average + use med_methods_mod , only : med_methods_FB_fldchk + use med_methods_mod , only : med_methods_FB_init use med_internalstate_mod , only : InternalState, mastertask, logunit use med_time_mod , only : med_time_alarmInit use med_io_mod , only : med_io_write, med_io_wopen, med_io_enddef use med_io_mod , only : med_io_close, med_io_date2yyyymmdd, med_io_sec2hms use med_io_mod , only : med_io_ymd2date use perf_mod , only : t_startf, t_stopf - use esmFlds , only : ncomps implicit none private - public :: med_phases_history_alarm_init - public :: med_phases_history_write - - ! type(ESMF_Alarm) :: alarm_hist_inst - ! type(ESMF_Alarm) :: alarm_hist_avg - + ! Public routines called from the run sequence + public :: med_phases_history_write ! inst only + public :: med_phases_history_write_med ! inst only + public :: med_phases_history_write_atm ! inst, avg, aux + public :: med_phases_history_write_ice ! inst, avg, aux + public :: med_phases_history_write_glc ! inst, avg, aux + public :: med_phases_history_write_lnd ! inst, avg, aux + public :: med_phases_history_write_ocn ! inst, avg, aux + public :: med_phases_history_write_rof ! inst, avg, aux + public :: med_phases_history_write_wav ! inst, avg, aux + + ! Private routines + private :: med_phases_history_write_inst_comp ! write instantaneous file for a given component + private :: med_phases_history_write_avg_comp ! write averaged file for a given component + private :: med_phases_history_write_aux_comp ! write auxiliary file for a given component + private :: med_phases_history_write_hfile + private :: med_phases_history_write_hfileaux + private :: med_phases_history_get_filename + private :: med_phases_history_get_auxflds + private :: med_phases_history_output_alarminfo + private :: med_phases_history_ymds2rday_offset + + character(CL) :: case_name = 'unset' ! case name + character(CS) :: inst_tag = 'unset' ! instance tag + + ! Time averaging history files + type, public :: avgfile_type + type(ESMF_FieldBundle) :: FBaccum ! field bundle for time averaging + integer :: accumcnt ! field bundle accumulation counter + end type avgfile_type + type(avgfile_type) :: avgfiles_import(ncomps) + type(avgfile_type) :: avgfiles_export(ncomps) + type(avgfile_type) :: avgfiles_aoflux_ocn + type(avgfile_type) :: avgfiles_ocnalb_ocn + type(avgfile_type) :: avgfiles_aoflux_atm + type(avgfile_type) :: avgfiles_ocnalb_atm + type(ESMF_Clock) :: hclock_avg_comp(ncomps) + + ! Auxiliary history files + integer, parameter :: max_auxfiles = 10 + type, public :: auxfile_type + character(CS), allocatable :: flds(:) ! array of aux field names + character(CS) :: auxname ! name for history file creation + character(CL) :: histfile = '' ! current history file name + character(CS) :: alarmname ! name of write alarm + integer :: ntperfile ! maximum number of time samples per file + integer :: nt = 0 ! time in file + logical :: useavg ! if true, time average, otherwise instantaneous + type(ESMF_FieldBundle) :: FBaccum ! field bundle for time averaging + integer :: accumcnt ! field bundle accumulation counter + type(ESMF_Clock) :: hclock ! auxiliary history clock + end type auxfile_type + integer , public :: num_auxfiles(ncomps) = 0 + type(auxfile_type) , public :: auxfiles(max_auxfiles,ncomps) + + ! Instantaneous history files + type(ESMF_Clock) :: hclock_inst_all + type(ESMF_Clock) :: hclock_inst_comp(ncomps) + + logical :: debug_alarms = .true. character(*), parameter :: u_FILE_u = & __FILE__ @@ -50,429 +123,1443 @@ module med_phases_history_mod contains !=============================================================================== - subroutine med_phases_history_alarm_init(gcomp, rc) - + subroutine med_phases_history_write(gcomp, rc) ! -------------------------------------- - ! Initialize mediator history file alarms (module variables) + ! Write instantaneous mediator history file for all variables ! -------------------------------------- - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet - use ESMF , only : ESMF_Clock, ESMF_ClockGet, ESMF_ClockAdvance, ESMF_ClockSet - use ESMF , only : ESMF_Time - use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalGet - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : operator(==), operator(-) - use ESMF , only : ESMF_ALARMLIST_ALL, ESMF_Alarm, ESMF_AlarmSet - use NUOPC , only : NUOPC_CompAttributeGet - use NUOPC_Model, only : NUOPC_ModelGet - ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc ! local variables - type(ESMF_Alarm) :: alarm - type(ESMF_Clock) :: mclock, dclock - type(ESMF_TimeInterval) :: mtimestep, dtimestep - type(ESMF_Time) :: mCurrTime - type(ESMF_Time) :: mStartTime - type(ESMF_TimeInterval) :: timestep - integer :: alarmcount - integer :: timestep_length - character(CL) :: cvalue ! attribute string - character(CL) :: histinst_option ! freq_option setting (ndays, nsteps, etc) - character(CL) :: histavg_option ! freq_option setting (ndays, nsteps, etc) - integer :: histinst_n ! freq_n setting relative to freq_option - integer :: histavg_n ! freq_n setting relative to freq_option - character(len=*), parameter :: subname='(med_phases_history_alarm_init)' + character(CL) :: alarmname + type(ESMF_Clock) :: mclock + type(ESMF_Alarm) :: alarm + type(ESMF_Time) :: CurrTime + type(ESMF_Time) :: StartTime + type(ESMF_TimeInterval) :: timestep + integer :: timestep_length + character(CL) :: hist_option ! freq_option setting (ndays, nsteps, etc) + integer :: hist_n ! freq_n setting relative to freq_option + character(CL) :: cvalue ! attribute string + logical :: isPresent + logical :: isSet + logical :: first_time = .true. + character(len=*), parameter :: subname='(med_phases_history_write)' !--------------------------------------- - rc = ESMF_SUCCESS + call t_startf('MED:'//subname) - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif + alarmname = 'alarm_history_inst_all' + if (first_time) then + call NUOPC_CompAttributeGet(gcomp, name='history_option', isPresent=isPresent, isSet=isSet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + call NUOPC_CompAttributeGet(gcomp, name='history_option', value=hist_option, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(gcomp, name='history_n', value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) hist_n + else + ! If attribute is not present - don't write history output + hist_option = 'none' + hist_n = -999 + end if - ! ----------------------------- - ! Get model clock - ! ----------------------------- + if (hist_option /= 'none' .and. hist_option /= 'never') then + ! First create hclock from mclock - THIS CALL DOES NOT COPY ALARMS + call NUOPC_ModelGet(gcomp, modelClock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + hclock_inst_all = ESMF_ClockCreate(mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Set alarm for instantaneous history output + ! Advance history clock to trigger alarms then reset history clock back to mcurrtime + call ESMF_ClockGet(hclock_inst_all, startTime=StartTime, currTime=CurrTime, timeStep=timestep, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_time_alarmInit(hclock_inst_all, alarm, option=hist_option, opt_n=hist_n, & + reftime=StartTime, alarmname=trim(alarmname), rc=rc) + call ESMF_AlarmSet(alarm, clock=hclock_inst_all, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockAdvance(hclock_inst_all,rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockSet(hclock_inst_all, currTime=currtime) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Write diagnostic info + if (mastertask) then + call ESMF_TimeIntervalGet(timestep, s=timestep_length, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(logunit,'(a,2x,i8)') " initialized instantaneous history alarm "//& + trim(alarmname)//" with option "//trim(hist_option)//" and frequency ",hist_n + write(logunit,'(a,2x,i8)') " history clock timestep = ",timestep_length + end if + end if + + first_time = .false. + end if + + if (ESMF_ClockIsCreated(hclock_inst_all)) then + ! Advance the clock + call ESMF_ClockAdvance(hclock_inst_all, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Write the instantaneous history file for all relevant components + call med_phases_history_write_hfile(gcomp, 'all', hclock_inst_all, 'alarm_history_inst_all', .false., rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + call t_stopf('MED:'//subname) + + end subroutine med_phases_history_write + + !=============================================================================== + subroutine med_phases_history_write_med(gcomp, rc) + ! Write mediator history file for med variables - only instantaneous files are written + ! This writes out ocean albedoes and atm/ocean fluxes computed by the mediator + ! along with the fractions computed by the mediator + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + logical :: first_time = .true. + !--------------------------------------- + rc = ESMF_SUCCESS + call med_phases_history_write_inst_comp(gcomp, compmed, & + first_time, 'med_phases_history_write_inst_med', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (first_time) first_time = .false. + end subroutine med_phases_history_write_med - call NUOPC_ModelGet(gcomp, modelClock=mclock, rc=rc) + !=============================================================================== + subroutine med_phases_history_write_atm(gcomp, rc) + ! Write mediator history file for atm variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + logical :: first_time = .true. + !--------------------------------------- + rc = ESMF_SUCCESS + call med_phases_history_write_inst_comp(gcomp, compatm, & + first_time, 'med_phases_history_write_inst_atm', rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_avg_comp(gcomp, compatm, & + first_time, 'med_phases_history_write_avg_atm', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_aux_comp(gcomp, compatm, & + first_time, 'med_phases_history_write_aux_atm', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (first_time) first_time = .false. + end subroutine med_phases_history_write_atm - ! get start time - call ESMF_ClockGet(mclock, startTime=mStartTime, rc=rc) + !=============================================================================== + ! Write mediator history file for ice variables + subroutine med_phases_history_write_ice(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + logical :: first_time = .true. + !--------------------------------------- + rc = ESMF_SUCCESS + call med_phases_history_write_inst_comp(gcomp, compice, & + first_time, 'med_phases_history_write_inst_ice', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_avg_comp(gcomp, compice, & + first_time, 'med_phases_history_write_avg_ice', rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_aux_comp(gcomp, compice, & + first_time, 'med_phases_history_write_aux_ice', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (first_time) first_time = .false. + end subroutine med_phases_history_write_ice - ! ----------------------------- - ! Set alarm for instantaneous mediator history output - ! ----------------------------- + !=============================================================================== + ! Write mediator history file for glc variables + subroutine med_phases_history_write_glc(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + integer :: ns + character(len=CS) :: cns + logical :: first_time = .true. + !--------------------------------------- + rc = ESMF_SUCCESS + do ns = 1,num_icesheets + write(cns,*) ns + call med_phases_history_write_inst_comp(gcomp, compglc(ns), & + first_time, 'med_phases_history_write_inst_glc'//trim(cns), rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_avg_comp(gcomp, compglc(ns), & + first_time, 'med_phases_history_write_avg_glc'//trim(cns), rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_aux_comp(gcomp, compglc(ns), & + first_time, 'med_phases_history_write_aux_glc'//trim(cns), rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do + if (first_time) first_time = .false. + end subroutine med_phases_history_write_glc + + !=============================================================================== + ! Write mediator history file for lnd variables + subroutine med_phases_history_write_lnd(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + logical :: first_time = .true. + !--------------------------------------- + rc = ESMF_SUCCESS + call med_phases_history_write_inst_comp(gcomp, complnd, & + first_time, 'med_phases_history_write_inst_lnd', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_avg_comp(gcomp, complnd, & + first_time, 'med_phases_history_write_avg_lnd', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_aux_comp(gcomp, complnd, & + first_time, 'med_phases_history_write_aux_lnd', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (first_time) first_time = .false. + end subroutine med_phases_history_write_lnd - call NUOPC_CompAttributeGet(gcomp, name='history_option', value=histinst_option, rc=rc) + !=============================================================================== + ! Write mediator history file for ocn variables + subroutine med_phases_history_write_ocn(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + logical :: first_time = .true. + !--------------------------------------- + rc = ESMF_SUCCESS + call med_phases_history_write_inst_comp(gcomp, compocn, & + first_time, 'med_phases_history_write_inst_ocn', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_avg_comp(gcomp, compocn, & + first_time, 'med_phases_history_write_avg_ocn', rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeGet(gcomp, name='history_n', value=cvalue, rc=rc) + call med_phases_history_write_aux_comp(gcomp, compocn, & + first_time, 'med_phases_history_write_aux_ocn', rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) histinst_n + if (first_time) first_time = .false. + end subroutine med_phases_history_write_ocn - call med_time_alarmInit(mclock, alarm, option=histinst_option, opt_n=histinst_n, & - reftime=mStartTime, alarmname='alarm_history_inst', rc=rc) + !=============================================================================== + ! Write mediator history file for rof variables + subroutine med_phases_history_write_rof(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + logical :: first_time = .true. + !--------------------------------------- + rc = ESMF_SUCCESS + call med_phases_history_write_inst_comp(gcomp, comprof, & + first_time, 'med_phases_history_write_inst_rof', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_avg_comp(gcomp, comprof, & + first_time, 'med_phases_history_write_avg_rof', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_aux_comp(gcomp, comprof, & + first_time, 'med_phases_history_write_aux_rof', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (first_time) first_time = .false. + end subroutine med_phases_history_write_rof - call ESMF_AlarmSet(alarm, clock=mclock, rc=rc) + !=============================================================================== + ! Write mediator history file for wav variables + subroutine med_phases_history_write_wav(gcomp, rc) + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + logical :: first_time = .true. + !--------------------------------------- + rc = ESMF_SUCCESS + call med_phases_history_write_inst_comp(gcomp, compwav, & + first_time, 'med_phases_history_write_inst_wav', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_avg_comp(gcomp, compwav, & + first_time, 'med_phases_history_write_avg_wav', rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_aux_comp(gcomp, compwav, & + first_time, 'med_phases_history_write_aux_wav', rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (first_time) first_time = .false. + end subroutine med_phases_history_write_wav - ! ----------------------------- - ! Set alarm for averaged mediator history output - ! ----------------------------- + !=============================================================================== + subroutine med_phases_history_write_inst_comp(gcomp, compid, first_time, subname, rc) + ! Write instantaneous mediator history file for component compid - !TODO: add isSet and isPresent flags to reading these and other config attributes - !call NUOPC_CompAttributeGet(gcomp, name='histavg_option', value=histavg_option, rc=rc) - !if (ChkErr(rc,__LINE__,u_FILE_u)) return - !call NUOPC_CompAttributeGet(gcomp, name='histavg_n', value=cvalue, rc=rc) - !if (ChkErr(rc,__LINE__,u_FILE_u)) return - !read(cvalue,*) histavg_n + ! input/output variables + type(ESMF_GridComp) , intent(inout) :: gcomp + integer , intent(in) :: compid + logical , intent(in) :: first_time + character(len=*) , intent(in) :: subname + integer , intent(out) :: rc - !call med_time_alarmInit(mclock, alarm, option=histavg_option, opt_n=histavg_n, & - ! reftime=mStartTime, alarmname='alarm_history_avg', rc=rc) - !if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! local variables + character(CL) :: alarmname + type(ESMF_Clock) :: mclock + type(ESMF_Alarm) :: alarm + type(ESMF_Time) :: CurrTime + type(ESMF_Time) :: StartTime + type(ESMF_TimeInterval) :: timestep + integer :: timestep_length + character(CL) :: hist_option ! freq_option setting (ndays, nsteps, etc) + integer :: hist_n ! freq_n setting relative to freq_option + character(CL) :: hist_option_in + character(CL) :: hist_n_in + character(CL) :: cvalue ! attribute string + logical :: isPresent + logical :: isSet + !--------------------------------------- + rc = ESMF_SUCCESS + call t_startf('MED:'//subname) - !call ESMF_AlarmSet(alarm, clock=mclock, rc=rc) - !if (ChkErr(rc,__LINE__,u_FILE_u)) return + alarmname = 'alarm_history_inst_'//trim(compname(compid)) - !-------------------------------- - ! Advance model clock to trigger alarms then reset model clock back to currtime - !-------------------------------- + if (first_time) then - call ESMF_ClockGet(mclock, currTime=mCurrTime, timeStep=mtimestep, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeIntervalGet(mtimestep, s=timestep_length, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Determine attribute prefix + write(hist_option_in,'(a)') 'history_option_'//trim(compname(compid))//'_inst' + write(hist_n_in,'(a)') 'history_n_'//trim(compname(compid))//'_inst' - call ESMF_ClockAdvance(mclock,rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Determine instantaneous mediator output frequency and type + call NUOPC_CompAttributeGet(gcomp, name=trim(hist_option_in), isPresent=isPresent, isSet=isSet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + call NUOPC_CompAttributeGet(gcomp, name=trim(hist_option_in), value=hist_option, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(gcomp, name=trim(hist_n_in), value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) hist_n + else + ! If attribute is not present - don't write history output + hist_option = 'none' + hist_n = -999 + end if - call ESMF_ClockSet(mclock, currTime=mcurrtime, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (hist_option /= 'none' .and. hist_option /= 'never') then + ! First create hclock from mclock - THIS CALL DOES NOT COPY ALARMS + call NUOPC_ModelGet(gcomp, modelClock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + hclock_inst_comp(compid) = ESMF_ClockCreate(mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Set alarm for instantaneous history output + ! Advance history clock to trigger alarms then reset history clock back to mcurrtime + call ESMF_ClockGet(hclock_inst_comp(compid), startTime=StartTime, currTime=CurrTime, timeStep=timestep, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_time_alarmInit(hclock_inst_comp(compid), alarm, option=hist_option, opt_n=hist_n, & + reftime=StartTime, alarmname=trim(alarmname), rc=rc) + call ESMF_AlarmSet(alarm, clock=hclock_inst_comp(compid), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockAdvance(hclock_inst_comp(compid),rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockSet(hclock_inst_comp(compid), currTime=currtime) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Write diagnostic info + if (mastertask) then + call ESMF_TimeIntervalGet(timestep, s=timestep_length, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(logunit,'(a,2x,i8)') " initialized instantaneous history alarm "//& + trim(alarmname)//" with option "//trim(hist_option)//" and frequency ",hist_n + write(logunit,'(a,2x,i8)') " history clock timestep = ",timestep_length + end if + end if + end if - ! ----------------------------- - ! Write mediator diagnostic output - ! ----------------------------- + if (ESMF_ClockIsCreated(hclock_inst_comp(compid))) then + ! Advance the clock + call ESMF_ClockAdvance(hclock_inst_comp(compid), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (mastertask) then - write(logunit,*) - write(logunit,100) trim(subname)//" history clock timestep = ",timestep_length - write(logunit,100) trim(subname)//" set instantaneous mediator history alarm with option "//& - trim(histinst_option)//" and frequency ",histinst_n - !write(logunit,100) trim(subname)//" set averaged mediator history alarm with option "//& - ! trim(histavg_option)//" and frequency ",histavg_n -100 format(a,2x,i8) - write(logunit,*) + ! Write the instantaneous history file + call med_phases_history_write_hfile(gcomp, trim(compname(compid)), hclock_inst_comp(compid), & + trim(alarmname), .false., rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": exited", ESMF_LOGMSG_INFO) - endif + call t_stopf('MED:'//subname) - end subroutine med_phases_history_alarm_init + end subroutine med_phases_history_write_inst_comp !=============================================================================== + subroutine med_phases_history_write_avg_comp(gcomp, compid, first_time, subname, rc) - subroutine med_phases_history_write(gcomp, rc) + ! Write mediator average history file variables for component compid - ! -------------------------------------- - ! Write mediator history file - ! -------------------------------------- + ! input/output variables + type(ESMF_GridComp) , intent(inout) :: gcomp + integer , intent(in) :: compid + logical , intent(in) :: first_time + character(len=*) , intent(in) :: subname + integer , intent(out) :: rc + ! local variables + integer :: n + character(CL) :: alarmname + type(InternalState) :: is_local + type(ESMF_Clock) :: mclock + type(ESMF_Alarm) :: alarm + type(ESMF_Time) :: CurrTime + type(ESMF_Time) :: StartTime + type(ESMF_TimeInterval) :: timestep + integer :: timestep_length + character(CL) :: cvalue ! attribute string + character(CL) :: hist_option ! freq_option setting (ndays, nsteps, etc) + integer :: hist_n ! freq_n setting relative to freq_option + character(CL) :: hist_option_in + character(CL) :: hist_n_in + logical :: isPresent + logical :: isSet + !--------------------------------------- + + rc = ESMF_SUCCESS + call t_startf('MED:'//subname) + + alarmname = 'alarm_history_avg_'//trim(compname(compid)) + + if (first_time) then + + ! Determine attribute prefix + write(hist_option_in,'(a)') 'history_option_'//trim(compname(compid))//'_avg' + write(hist_n_in,'(a)') 'history_n_'//trim(compname(compid))//'_avg' + + ! Determine time average mediator output frequency and type + call NUOPC_CompAttributeGet(gcomp, name=trim(hist_option_in), isPresent=isPresent, isSet=isSet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + call NUOPC_CompAttributeGet(gcomp, name=trim(hist_option_in), value=hist_option, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(gcomp, name=trim(hist_n_in), value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) hist_n + else + hist_option = 'none' + hist_n = -999 + end if + + ! Create time average field bundles (module variables) + if (hist_option /= 'never' .and. hist_option /= 'none') then + + ! First create hclock from mclock - THIS CALL DOES NOT COPY ALARMS + call NUOPC_ModelGet(gcomp, modelClock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + hclock_avg_comp(compid) = ESMF_ClockCreate(mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Set alarm for time averaged history output + ! Advance history clock to trigger alarms then reset history clock back to mcurrtime + call ESMF_ClockGet(hclock_avg_comp(compid), startTime=StartTime, currTime=CurrTime, timeStep=timestep, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_time_alarmInit(hclock_avg_comp(compid), alarm, option=hist_option, opt_n=hist_n, & + reftime=StartTime, alarmname=trim(alarmname), rc=rc) + call ESMF_AlarmSet(alarm, clock=hclock_avg_comp(compid), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockAdvance(hclock_avg_comp(compid),rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockSet(hclock_avg_comp(compid), currTime=currtime) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (compid /= compmed) then ! component is not mediator + ! create accumulated import fields + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBimp(compid,compid),rc=rc)) then + if (.not. ESMF_FieldBundleIsCreated(avgfiles_import(compid)%FBaccum)) then + call med_methods_fb_init(avgfiles_import(compid)%FBaccum, is_local%wrap%flds_scalar_name, & + FBgeom=is_local%wrap%FBImp(compid,compid), STflds=is_local%wrap%NStateImp(compid), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_FB_reset(avgfiles_import(compid)%FBaccum, czero, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + avgfiles_import(compid)%accumcnt = 0 + end if + end if + ! accumulated export fields + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBexp(compid), rc=rc)) then + if (.not. ESMF_FieldBundleIsCreated(avgfiles_export(compid)%FBaccum)) then + call med_methods_fb_init(avgfiles_export(compid)%FBaccum, is_local%wrap%flds_scalar_name, & + FBgeom=is_local%wrap%FBExp(compid), STflds=is_local%wrap%NstateExp(compid), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_FB_reset(avgfiles_export(compid)%FBaccum, czero, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + avgfiles_export(compid)%accumcnt = 0 + end if + end if + else ! component is mediator + ! accumulated atm/ocn flux on ocn mesh + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_o, rc=rc)) then + if (.not. ESMF_FieldBundleIsCreated(avgfiles_aoflux_ocn%FBaccum)) then + call med_methods_fb_init(avgfiles_aoflux_ocn%FBaccum, is_local%wrap%flds_scalar_name, & + FBgeom=is_local%wrap%FBMed_aoflux_o, FBflds=is_local%wrap%FBMed_aoflux_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_FB_reset(avgfiles_aoflux_ocn%FBaccum, czero, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + avgfiles_aoflux_ocn%accumcnt = 0 + end if + end if + ! accumulated atm/ocn flux on atm mesh + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_a, rc=rc)) then + if (.not. ESMF_FieldBundleIsCreated(avgfiles_aoflux_atm%FBaccum)) then + call med_methods_fb_init(avgfiles_aoflux_atm%FBaccum, is_local%wrap%flds_scalar_name, & + FBgeom=is_local%wrap%FBMed_aoflux_a, FBflds=is_local%wrap%FBMed_aoflux_a, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_FB_reset(avgfiles_aoflux_atm%FBaccum, czero, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + avgfiles_aoflux_atm%accumcnt = 0 + end if + end if + ! accumulated ocean albedo on ocn mesh + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_o, rc=rc)) then + if (.not. ESMF_FieldBundleIsCreated(avgfiles_ocnalb_ocn%FBaccum)) then + call med_methods_fb_init(avgfiles_ocnalb_ocn%FBaccum, is_local%wrap%flds_scalar_name, & + FBgeom=is_local%wrap%FBMed_ocnalb_o, FBflds=is_local%wrap%FBMed_ocnalb_o, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_FB_reset(avgfiles_ocnalb_ocn%FBaccum, czero, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + avgfiles_ocnalb_ocn%accumcnt = 0 + end if + end if + ! accumulated ocean albedo on atm mesh + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_a, rc=rc)) then + if (.not. ESMF_FieldBundleIsCreated(avgfiles_ocnalb_atm%FBaccum)) then + call med_methods_fb_init(avgfiles_ocnalb_atm%FBaccum, is_local%wrap%flds_scalar_name, & + FBgeom=is_local%wrap%FBMed_ocnalb_a, FBflds=is_local%wrap%FBMed_ocnalb_a, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_methods_FB_reset(avgfiles_ocnalb_atm%FBaccum, czero, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + avgfiles_ocnalb_atm%accumcnt = 0 + end if + end if + end if + end if + + end if ! end of initialization (first_time) if block + + if (ESMF_ClockIsCreated(hclock_avg_comp(compid))) then + ! Update clock + call ESMF_ClockAdvance(hclock_avg_comp(compid), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet - use ESMF , only : ESMF_VM, ESMF_VMGet - use ESMF , only : ESMF_Clock, ESMF_ClockGet, ESMF_ClockGetNextTime, ESMF_ClockGetAlarm - use ESMF , only : ESMF_Calendar - use ESMF , only : ESMF_Time, ESMF_TimeGet - use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalGet - use ESMF , only : ESMF_Alarm, ESMF_AlarmIsRinging, ESMF_AlarmRingerOff, ESMF_AlarmGet - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_FieldBundleIsCreated, ESMF_MAXSTR, ESMF_ClockPrint, ESMF_AlarmIsCreated - use ESMF , only : operator(==), operator(-) - use ESMF , only : ESMF_ALARMLIST_ALL, ESMF_ClockGetAlarmList - use NUOPC , only : NUOPC_CompAttributeGet - use esmFlds , only : compatm, compocn, ncomps, compname - use esmFlds , only : fldListFr, fldListTo - use NUOPC_Model, only : NUOPC_ModelGet + ! Write history file + call med_phases_history_write_hfile(gcomp, trim(compname(compid)), hclock_avg_comp(compid), & + trim(alarmname), .false., rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + call t_stopf('MED:'//subname) + + end subroutine med_phases_history_write_avg_comp + + !=============================================================================== + subroutine med_phases_history_write_aux_comp(gcomp, compid, first_time, subname, rc) + + ! ----------------------------- + ! Write mediator history file for component compid + ! Initialize auxiliary history file + ! Each time this routine is called the routine SetRunClock in med.F90 is called + ! at the beginning and the mediator clock current time and time step is set to the + ! driver current time and time step + ! ----------------------------- ! input/output variables - type(ESMF_GridComp) :: gcomp - integer, intent(out) :: rc + type(ESMF_GridComp) , intent(inout) :: gcomp + integer , intent(in) :: compid + logical , intent(in) :: first_time + character(len=*) , intent(in) :: subname + integer , intent(out) :: rc ! local variables - type(ESMF_Clock) :: mclock, dclock - type(ESMF_TimeInterval) :: mtimestep, dtimestep - integer :: timestep_length + type(InternalState) :: is_local + type(ESMF_Clock) :: mclock ! mediator clock + type(ESMF_Time) :: starttime + type(ESMF_Time) :: currtime + type(ESMF_TimeInterval) :: timestep type(ESMF_Alarm) :: alarm - integer :: alarmCount + logical :: isPresent ! is attribute present + logical :: isSet ! is attribute set + character(CL) :: hist_option ! freq_option setting (ndays, nsteps, etc) + integer :: hist_n ! freq_n setting relative to freq_option + integer :: nfcnt + integer :: nfile + integer :: nfld + integer :: n,n1 + character(CL) :: prefix + character(CL) :: cvalue + character(CL) :: auxflds + integer :: fieldCount + logical :: found + logical :: enable_auxfile + character(CS), allocatable :: fieldNameList(:) + !--------------------------------------- + rc = ESMF_SUCCESS + call t_startf('MED:'//subname) + + if (first_time) then + + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Initialize number of aux files for this component to zero + nfcnt = 0 + do nfile = 1,max_auxfiles + + ! Determine attribute prefix + write(prefix,'(a,i0)') 'histaux_'//trim(compname(compid))//'2med_file',nfile + + ! Determine if will write the file + call NUOPC_CompAttributeGet(gcomp, name=trim(prefix)//'_enabled', isPresent=isPresent, isSet=isSet, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + call NUOPC_CompAttributeGet(gcomp, name=trim(prefix)//'_enabled', value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,'(l)') enable_auxfile + else + enable_auxfile = .false. + end if + + ! If file will be written - then initialize auxfiles(nfcnt,compid) + if (enable_auxfile) then + + ! Increment nfcnt + nfcnt = nfcnt + 1 + + ! Determine number of time samples per file + call NUOPC_CompAttributeGet(gcomp, name=trim(prefix)//'_ntperfile', value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) auxfiles(nfcnt,compid)%ntperfile + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine if will do time average for aux file + call NUOPC_CompAttributeGet(gcomp, name=trim(prefix)//'_useavg', value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) auxfiles(nfcnt,compid)%useavg + + ! Determine the colon delimited field names for this file + call NUOPC_CompAttributeGet(gcomp, name=trim(prefix)//'_flds', value=auxflds, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine fields that will be output to auxhist files + if (trim(auxflds) == 'all') then + + ! Output all fields sent to the mediator from ncomp to the auxhist files + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compid,compid), & + fieldCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(auxfiles(nfcnt,compid)%flds(fieldcount)) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compid,compid), & + fieldNameList=auxfiles(nfcnt,compid)%flds, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + else + + ! Translate the colon deliminted string (auxflds) into a character array (fieldnamelist) + ! Note that the following call allocates the memory for fieldnamelist + call med_phases_history_get_auxflds(auxflds, fieldnamelist, rc) + + ! TODO: print warning statement if remove field + ! TODO: if request field that is NOT in the field definition file - then quit + ! Remove all fields from fieldnamelist that are not in FBImp(compid,compid) + fieldCount = size(fieldnamelist) + do n = 1,fieldcount + if (.not. med_methods_FB_fldchk(is_local%wrap%FBImp(compid,compid), trim(fieldnamelist(n)), rc)) then + do n1 = n, fieldCount-1 + fieldnamelist(n1) = fieldnamelist(n1+1) + end do + fieldCount = fieldCount - 1 + end if + end do + + ! Create auxfiles(nfcnt,compid)%flds array + allocate(auxfiles(nfcnt,compid)%flds(fieldcount)) + do n = 1,fieldcount + auxfiles(nfcnt,compid)%flds(n) = trim(fieldnamelist(n)) + end do + + + ! Deallocate memory from fieldnamelist + deallocate(fieldnamelist) ! this was allocated in med_phases_history_get_auxflds + + end if ! end of if auxflds is set to 'all' + + if (mastertask) then + write(logunit,*) + write(logunit,'(a,i4,a)') ' Writing the following fields to auxfile ',nfcnt,& + ' for component '//trim(compname(compid)) + do nfld = 1,size(auxfiles(nfcnt,compid)%flds) + write(logunit,'(8x,a)') trim(auxfiles(nfcnt,compid)%flds(nfld)) + end do + end if + + ! Create FBaccum if averaging is on + if (auxfiles(nfcnt,compid)%useavg) then + + ! First duplicate all fields in FBImp(compid,compid) + call ESMF_LogWrite(trim(subname)// ": calling med_methods_fb_init for FBaccum(compid)", ESMF_LOGMSG_INFO) + call med_methods_fb_init(auxfiles(nfcnt,compid)%FBaccum, is_local%wrap%flds_scalar_name, & + FBgeom=is_local%wrap%FBImp(compid,compid), STflds=is_local%wrap%NStateImp(compid), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Now remove all fields from FBAccum that are not in the input flds list + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compid,compid), fieldCount=fieldCount, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(fieldNameList(fieldCount)) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(compid,compid), fieldNameList=fieldNameList, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(fieldnamelist) + found = .false. + do n1 = 1,size(auxfiles(nfcnt,compid)%flds) + if (trim(fieldnamelist(n)) == trim(auxfiles(nfcnt,compid)%flds(n1))) then + found = .true. + exit + end if + end do + if (.not. found) then + call ESMF_FieldBundleRemove(auxfiles(nfcnt,compid)%FBaccum, fieldnamelist(n:n), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + end do + deallocate(fieldnameList) + + ! Check that FBAccum has at least one field left - if not exit + call ESMF_FieldBundleGet(auxfiles(nfcnt,compid)%FBAccum, fieldCount=nfld, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (nfld == 0) then + call ESMF_LogWrite(subname//'FBAccum is zero for '//trim(auxfiles(nfcnt,compid)%auxname), & + ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) then + call ESMF_Finalize(endflag=ESMF_END_ABORT) + end if + end if + + end if + + ! Determine auxiliary file output frequency and type + call NUOPC_CompAttributeGet(gcomp, name=trim(prefix)//'_history_option', value=hist_option, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(gcomp, name=trim(prefix)//'_history_n', value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) hist_n + + ! First create hclock from mclock - THIS CALL DOES NOT COPY ALARMS + call NUOPC_ModelGet(gcomp, modelClock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + auxfiles(nfcnt,compid)%hclock = ESMF_ClockCreate(mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Set alarm for auxiliary history output + ! Advance history clock to trigger alarms then reset history clock back to mcurrtime + call NUOPC_CompAttributeGet(gcomp, name=trim(prefix)//'_auxname', & + value=auxfiles(nfcnt,compid)%auxname, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(auxfiles(nfcnt,compid)%alarmname,'(a,i0)') 'alarm_'//trim(prefix) + call ESMF_ClockGet(auxfiles(nfcnt,compid)%hclock, & + startTime=starttime, currTime=currtime, timeStep=timestep, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_time_alarmInit(auxfiles(nfcnt,compid)%hclock, alarm, option=hist_option, opt_n=hist_n, & + reftime=starttime, alarmname=trim(auxfiles(nfcnt,compid)%alarmname), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_AlarmSet(alarm, clock=auxfiles(nfcnt,compid)%hclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockAdvance(auxfiles(nfcnt,compid)%hclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockSet(auxfiles(nfcnt,compid)%hclock, currtime=currtime) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (mastertask) then + write(logunit,'(a,2x,i8)') " created auxiliary history alarm "//& + trim(auxfiles(nfcnt,compid)%alarmname)//" with option "//trim(hist_option)//" and frequency ",hist_n + end if + end if ! end of isPresent and isSet and if flag is on for file n + end do ! end of loop over nfile + + ! Set number of aux files for this component + num_auxfiles(compid) = nfcnt + + end if ! end of initialization (first time) block + + ! Write auxiliary history files for component compid + do n = 1,num_auxfiles(compid) + call ESMF_ClockAdvance(auxfiles(n,compid)%hclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_phases_history_write_hfileaux(gcomp, n, compid, auxfiles(n,compid), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do + call t_stopf('MED:'//subname) + + end subroutine med_phases_history_write_aux_comp + + !=============================================================================== + subroutine med_phases_history_write_hfile(gcomp, comptype, hclock, alarmname, doavg, rc) + + ! input/output variables + type(ESMF_GridComp) , intent(inout) :: gcomp + character(len=*) , intent(in) :: comptype + type(ESMF_Clock) , intent(in) :: hclock + character(len=*) , intent(in) :: alarmname + logical , intent(in) :: doavg + integer , intent(out) :: rc + + ! local variables + type(InternalState) :: is_local type(ESMF_VM) :: vm - type(ESMF_Time) :: currtime + type(ESMF_Clock) :: mclock + type(ESMF_Alarm) :: alarm type(ESMF_Time) :: starttime + type(ESMF_Time) :: currtime type(ESMF_Time) :: nexttime - type(ESMF_TimeInterval) :: timediff ! Used to calculate curr_time - type(ESMF_Calendar) :: calendar ! calendar type - character(len=64) :: currtimestr - character(len=64) :: nexttimestr - type(InternalState) :: is_local - character(CS) :: histavg_option ! Histavg option units - integer :: i,j,m,n,n1,ncnt - integer :: start_ymd ! Starting date YYYYMMDD - integer :: start_tod ! Starting time-of-day (s) - integer :: nx,ny ! global grid size - integer :: yr,mon,day,sec ! time units - real(r8) :: rval ! real tmp value - real(r8) :: dayssince ! Time interval since reference time - integer :: fk ! index - character(CL) :: time_units ! units of time variable - character(CL) :: case_name ! case name - character(CL) :: hist_file ! Local path to history filename - character(CS) :: cpl_inst_tag ! instance tag - character(CL) :: cvalue ! attribute string - real(r8) :: tbnds(2) ! CF1.0 time bounds - logical :: whead,wdata ! for writing restart/history cdf files + type(ESMF_Calendar) :: calendar ! calendar type + type(ESMF_TimeInterval) :: timediff(2) ! time bounds upper and lower relative to start + type(ESMF_TimeInterval) :: ringInterval ! alarm interval + real(r8) :: tbnds(2) ! CF1.0 time bounds + integer :: i,j,m,n + integer :: nx,ny ! global grid size + character(CL) :: time_units ! units of time variable + character(CL) :: hist_file + real(r8) :: days_since ! Time interval since reference time + real(r8) :: avg_time ! Time coordinate output + logical :: whead,wdata ! for writing restart/history cdf files integer :: iam - logical :: isPresent - type(ESMF_TimeInterval) :: RingInterval - integer :: ringInterval_length - logical :: first_time = .true. - character(len=*), parameter :: subname='(med_phases_history_write)' + logical :: write_now + integer :: yr,mon,day,sec ! time units + character(len=*), parameter :: subname='(med_phases_history_write_hfile)' !--------------------------------------- - call t_startf('MED:'//subname) - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif rc = ESMF_SUCCESS - !--------------------------------------- - ! --- Get the communicator and localpet - !--------------------------------------- - - call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMGet(vm, localPet=iam, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------- - ! --- Get the internal state - !--------------------------------------- - + ! Get the internal state nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeGet(gcomp, name='case_name', value=case_name, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompAttributeGet(gcomp, name='inst_suffix', isPresent=isPresent, rc=rc) + ! Get the history file alarm and determine if alarm is ringing + ! call NUOPC_ModelGet(gcomp, modelClock=mclock, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGetAlarm(hclock, alarmname=trim(alarmname), alarm=alarm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if(isPresent) then - call NUOPC_CompAttributeGet(gcomp, name='inst_suffix', value=cpl_inst_tag, rc=rc) + + if (ESMF_AlarmIsRinging(alarm, rc=rc)) then + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Set write_now flag + write_now = .true. + ! Turn ringer off + call ESMF_AlarmRingerOff(alarm, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Write diagnostic output + if (debug_alarms) then + call med_phases_history_output_alarminfo(hclock, alarm, alarmname, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if else - cpl_inst_tag = "" - endif + write_now = .false. + end if - call NUOPC_ModelGet(gcomp, modelClock=mclock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (first_time) then - call med_phases_history_alarm_init(gcomp, rc) + ! Accumulate if alarm is not on - other wise average + if (doavg) then + do n = 1,ncomps + if (comptype == 'all' .or. comptype == trim(compname(n))) then + ! accumulate + if (ESMF_FieldBundleIsCreated(avgfiles_import(n)%FBaccum)) then + call med_methods_FB_accum(avgfiles_import(n)%FBaccum, is_local%wrap%FBImp(n,n), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + avgfiles_import(n)%accumcnt = avgfiles_import(n)%accumcnt + 1 + end if + if (ESMF_FieldBundleIsCreated(avgfiles_export(n)%FBaccum)) then + call med_methods_FB_accum(avgfiles_export(n)%FBaccum, is_local%wrap%FBExp(n), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + avgfiles_export(n)%accumcnt = avgfiles_export(n)%accumcnt + 1 + end if + if (write_now) then + if (ESMF_FieldBundleIsCreated(avgfiles_import(n)%FBaccum)) then + call med_methods_FB_average(avgfiles_import(n)%FBaccum, avgfiles_import(n)%accumcnt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + avgfiles_import(n)%accumcnt = 0 + end if + if (ESMF_FieldBundleIsCreated(avgfiles_export(n)%FBaccum)) then + call med_methods_FB_average(avgfiles_export(n)%FBaccum, avgfiles_export(n)%accumcnt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + avgfiles_export(n)%accumcnt = 0 + end if + end if + end if + end do end if - !--------------------------------------- ! Check if history alarm is ringing - and if so write the mediator history file + if (write_now) then + + ! Determine history file name and time units + call med_phases_history_get_filename(gcomp, doavg, comptype, hist_file, time_units, days_since, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Set tbnds and avg_time if doing averaging + if (doavg) then + call ESMF_ClockGet(hclock, currtime=currtime, starttime=starttime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGetNextTime(hclock, nextTime=nexttime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_AlarmGet(alarm, ringInterval=ringInterval, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + timediff(2) = nexttime - starttime + timediff(1) = nexttime - ringinterval - starttime + call ESMF_TimeIntervalGet(timediff(2), d_r8=tbnds(2), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeIntervalGet(timediff(1), d_r8=tbnds(1), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + avg_time = 0.5_r8 * (tbnds(1) + tbnds(2)) + end if + + ! Create history file + call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMGet(vm, localPet=iam, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_io_wopen(hist_file, vm, iam, clobber=.true.) + do m = 1,2 + if (m == 1) then + whead = .true. + wdata = .false. + else if (m == 2) then + whead = .false. + wdata = .true. + call med_io_enddef(hist_file) + end if + + ! Write time values (tbnds does not appear in instantaneous output) + call ESMF_ClockGet(hclock, calendar=calendar, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (doavg) then + call med_io_write(hist_file, iam, time_units=time_units, calendar=calendar, time_val=avg_time, & + nt=1, tbnds=tbnds, whead=whead, wdata=wdata, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call med_io_write(hist_file, iam, time_units=time_units, calendar=calendar, time_val=days_since, & + nt=1, whead=whead, wdata=wdata, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! Write import and export field bundles + do n = 2,ncomps ! skip the mediator here + if (comptype == 'all' .or. comptype == trim(compname(n))) then + if (is_local%wrap%comp_present(n)) then + nx = is_local%wrap%nx(n) + ny = is_local%wrap%ny(n) + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBimp(n,n),rc=rc)) then + if (doavg) then + call med_io_write(hist_file, iam, avgfiles_import(n)%FBaccum, & + nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, & + pre=trim(compname(n))//'Imp', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call med_io_write(hist_file, iam, is_local%wrap%FBimp(n,n), & + nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, & + pre=trim(compname(n))//'Imp', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + endif + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBexp(n),rc=rc)) then + if (doavg) then + call med_io_write(hist_file, iam, avgfiles_export(n)%FBaccum, & + nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, & + pre=trim(compname(n))//'Exp', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call med_io_write(hist_file, iam, is_local%wrap%FBexp(n), & + nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, & + pre=trim(compname(n))//'Exp', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + endif + endif + end if + enddo + + ! Write mediator fractions + ! Also write atm/ocn fluxes and ocean albedoes if field bundles are created + if (.not. doavg) then + if (comptype == 'all' .or. comptype == 'med') then + do n = 2,ncomps ! skip the mediator here + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(n),rc=rc)) then + call med_io_write(hist_file, iam, is_local%wrap%FBFrac(n), & + nx=is_local%wrap%nx(n), ny=is_local%wrap%ny(n), nt=1, whead=whead, wdata=wdata, & + pre='Med_frac_'//trim(compname(n)), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end do + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_o,rc=rc)) then + call med_io_write(hist_file, iam, is_local%wrap%FBMed_ocnalb_o, & + nx=is_local%wrap%nx(compocn), ny=is_local%wrap%ny(compocn), nt=1, whead=whead, wdata=wdata, & + pre='Med_alb_ocn', rc=rc) + end if + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_o,rc=rc)) then + call med_io_write(hist_file, iam, is_local%wrap%FBMed_aoflux_o, & + nx=is_local%wrap%nx(compocn), ny=is_local%wrap%ny(compocn), nt=1, whead=whead, wdata=wdata, & + pre='Med_aoflux_ocn', rc=rc) + end if + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_a,rc=rc)) then + call med_io_write(hist_file, iam, is_local%wrap%FBMed_ocnalb_a, & + nx=is_local%wrap%nx(compatm), ny=is_local%wrap%ny(compatm), nt=1, whead=whead, wdata=wdata, & + pre='Med_alb_atm', rc=rc) + end if + if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_a,rc=rc)) then + call med_io_write(hist_file, iam, is_local%wrap%FBMed_aoflux_a, & + nx=is_local%wrap%nx(compatm), ny=is_local%wrap%ny(compatm), nt=1, whead=whead, wdata=wdata, & + pre='Med_aoflux_atm', rc=rc) + end if + end if + end if + + end do ! end of loop over m + + ! Close file + call med_io_close(hist_file, iam, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end if ! end of if-alarm is ringingblock + + end subroutine med_phases_history_write_hfile + + !=============================================================================== + subroutine med_phases_history_write_hfileaux(gcomp, nfile_index, comp_index, auxfile, rc) + + ! input/output variables + type(ESMF_GridComp) , intent(inout) :: gcomp + integer , intent(in) :: nfile_index + integer , intent(in) :: comp_index + type(auxfile_type) , intent(inout) :: auxfile + integer , intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + type(ESMF_VM) :: vm + type(ESMF_Clock) :: mclock + type(ESMF_Alarm) :: alarm + type(ESMF_Time) :: starttime + type(ESMF_Time) :: currtime + type(ESMF_Time) :: nexttime + type(ESMF_Calendar) :: calendar ! calendar type + type(ESMF_TimeInterval) :: timediff(2) ! time bounds upper and lower relative to start + type(ESMF_TimeInterval) :: ringInterval ! alarm interval + character(CS) :: timestr ! yr-mon-day-sec string + character(CL) :: time_units ! units of time variable + real(r8) :: avg_time ! Time coordinate output + integer :: nx,ny ! global grid size + logical :: whead,wdata ! for writing restart/history cdf files + logical :: write_now ! if true, write time sample to file + integer :: iam ! mpi task + integer :: start_ymd ! Starting date YYYYMMDD + integer :: yr,mon,day,sec ! time units + real(r8) :: tbnds(2) ! CF1.0 time bounds + character(len=*), parameter :: subname='(med_phases_history_write_hfileaux)' !--------------------------------------- - ! TODO: Add history averaging functionality and Determine if history average alarm is on - ! if (ESMF_AlarmIsRinging(AlarmHistAvg, rc=rc)) then - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! alarmIsOn = .true. - ! call ESMF_AlarmRingerOff( AlarmHist, rc=rc ) - ! if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! else - ! alarmisOn = .false. - ! endif + rc = ESMF_SUCCESS + + ! Get the communicator and localpet + call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMGet(vm, localPet=iam, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_ClockGetAlarm(mclock, alarmname='alarm_history_inst', alarm=alarm, rc=rc) + ! Determine time info + ! Use nexttime rather than currtime for the time difference form + ! start since that is the time at the end of the time step + call ESMF_ClockGet(auxfile%hclock, currtime=currtime, starttime=starttime, calendar=calendar, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGetNextTime(auxfile%hclock, nextTime=nexttime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGetAlarm(auxfile%hclock, alarmname=trim(auxfile%alarmname), alarm=alarm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (dbug_flag > 2) then + write_now = .false. + if (ESMF_AlarmIsRinging(alarm, rc=rc)) then + write_now = .true. + call ESMF_AlarmRingerOff( alarm, rc=rc ) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (debug_alarms) then + call med_phases_history_output_alarminfo(auxfile%hclock, alarm, auxfile%alarmname, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if call ESMF_AlarmGet(alarm, ringInterval=ringInterval, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeIntervalGet(ringInterval, s=ringinterval_length, rc=rc) + timediff(2) = currtime - starttime + timediff(1) = currtime - starttime - ringinterval + call ESMF_TimeIntervalGet(timediff(2), d_r8=tbnds(2), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_ClockGet(mclock, currtime=currtime, rc=rc) + call ESMF_TimeIntervalGet(timediff(1), d_r8=tbnds(1), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeGet(currtime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) + avg_time = 0.5_r8 * (tbnds(1) + tbnds(2)) + end if + + if (mastertask .and. debug_alarms) then + if (write_now) then + write(logunit,'(a)')' alarmname = '//trim(auxfile%alarmname)//' is ringing' + write(logunit,'(a,f13.5,a,f13.5)')' tbnds(1) = ',tbnds(1),' tbnds(2) = ',tbnds(2) + else + write(logunit,'(a)')' alarmname = '//trim(auxfile%alarmname)//' is not ringing' + end if + call ESMF_TimeGet(nexttime, yy=yr, mm=mon, dd=day, s=sec, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - write(currtimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec - call ESMF_ClockGetNextTime(mclock, nextTime=nexttime, rc=rc) + write(logunit,'(a,4(i6,2x))')' nexttime is ',yr,mon,day,sec + call ESMF_TimeGet(currtime, yy=yr, mm=mon, dd=day, s=sec, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeGet(nexttime, yy=yr, mm=mon, dd=day, s=sec, rc=rc) + write(logunit,'(a,4(i6,2x))')' currtime is ',yr,mon,day,sec + call ESMF_TimeGet(starttime, yy=yr, mm=mon, dd=day, s=sec, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (mastertask) then - write(nexttimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec - write(logunit,*) - write(logunit,*) trim(subname)//": history alarm ringinterval = ", ringInterval_length - write(logunit,' (a)') trim(subname)//": currtime = "//trim(currtimestr)//" nexttime = "//trim(nexttimestr) - write(logunit,*) trim(subname) //' history alarm is ringing = ', ESMF_AlarmIsRinging(alarm) - end if + write(logunit,'(a,4(i6,2x))')' starttime is ',yr,mon,day,sec end if - if (ESMF_AlarmIsRinging(alarm, rc=rc)) then + ! Do accumulation and average if required + if (auxfile%useavg) then + call med_methods_FB_accum(auxfile%FBaccum, is_local%wrap%FBImp(comp_index,comp_index), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + auxfile%accumcnt = auxfile%accumcnt + 1 - ! Turn ringer off - call ESMF_AlarmRingerOff( alarm, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (write_now) then + call med_methods_FB_average(auxfile%FBaccum, auxfile%accumcnt, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + auxfile%accumcnt = 0 + endif + end if - ! Get time info for history file - call ESMF_GridCompGet(gcomp, clock=mclock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Write time sample to file + if ( write_now ) then - call ESMF_ClockGet(mclock, currtime=currtime, starttime=starttime, calendar=calendar, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Increment number of time samples on file + auxfile%nt = auxfile%nt + 1 - call ESMF_ClockGetNextTime(mclock, nextTime=nexttime, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Set shorthand variables + nx = is_local%wrap%nx(comp_index) + ny = is_local%wrap%ny(comp_index) - call ESMF_TimeGet(currtime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - write(currtimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec + ! Write header + if (auxfile%nt == 1) then - call ESMF_TimeGet(nexttime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - write(nexttimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec - timediff = nexttime - starttime - call ESMF_TimeIntervalGet(timediff, d=day, s=sec, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - dayssince = day + sec/real(SecPerDay,R8) + ! determine history file name + call ESMF_ClockGet(auxfile%hclock, currtime=currtime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeGet(currtime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(timestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec + if (trim(case_name) == 'unset') then + call med_phases_history_set_casename(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + write(auxfile%histfile, "(8a)") & + trim(case_name),'.cpl',trim(inst_tag),'.hx.', trim(auxfile%auxname),'.',trim(timestr), '.nc' - call ESMF_TimeGet(starttime, yy=yr, mm=mon, dd=day, s=sec, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_io_ymd2date(yr,mon,day,start_ymd) - start_tod = sec - time_units = 'days since ' // trim(med_io_date2yyyymmdd(start_ymd)) // ' ' // med_io_sec2hms(start_tod, rc) + ! open file + call med_io_wopen(auxfile%histfile, vm, iam, file_ind=nfile_index, clobber=.true.) + + ! define time units + call ESMF_TimeGet(starttime, yy=yr, mm=mon, dd=day, s=sec, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_io_ymd2date(yr,mon,day,start_ymd) + time_units = 'days since ' // trim(med_io_date2yyyymmdd(start_ymd)) // ' ' // med_io_sec2hms(sec, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! define time variables + call med_io_write(auxfile%histfile, iam, time_units, calendar, avg_time, & + nt=auxfile%nt, tbnds=tbnds, whead=.true., wdata=.false., file_ind=nfile_index, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! define data variables with a time dimension (include the nt argument below) + call med_io_write(auxfile%histfile, iam, is_local%wrap%FBimp(comp_index,comp_index), & + nx=nx, ny=ny, nt=auxfile%nt, whead=.true., wdata=.false., pre=trim(compname(comp_index))//'Imp', & + flds=auxfile%flds, file_ind=nfile_index, use_float=.true., rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! end definition phase + call med_io_enddef(auxfile%histfile, file_ind=nfile_index) + + end if + + ! Write time variables for time nt + call med_io_write(auxfile%histfile, iam, time_units, calendar, avg_time, & + nt=auxfile%nt, tbnds=tbnds, whead=.false., wdata=.true., file_ind=nfile_index, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Use nexttimestr rather than currtimestr here since that is the time at the end of - ! the timestep and is preferred for history file names - write(hist_file,"(6a)") trim(case_name), '.cpl',trim(cpl_inst_tag),'.hi.', trim(nexttimestr),'.nc' + ! Write data variables for time nt + if (auxfile%useavg) then + call med_io_write(auxfile%histfile, iam, auxfile%FBaccum, & + nx=nx, ny=ny, nt=auxfile%nt, whead=.false., wdata=.true., pre=trim(compname(comp_index))//'Imp', & + flds=auxfile%flds, file_ind=nfile_index, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_methods_FB_reset(auxfile%FBaccum, value=czero, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + call med_io_write(auxfile%histfile, iam, is_local%wrap%FBimp(comp_index,comp_index), & + nx=nx, ny=ny, nt=auxfile%nt, whead=.false., wdata=.true., pre=trim(compname(comp_index))//'Imp', & + flds=auxfile%flds, file_ind=nfile_index, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if - if (mastertask) then - write(logunit,*) - write(logunit,' (a)') trim(subname)//": writing mediator history file "//trim(hist_file) - write(logunit,' (a)') trim(subname)//": currtime = "//trim(currtimestr) - write(logunit,' (a)') trim(subname)//": nexttime = "//trim(nexttimestr) + ! Close file + if (auxfile%nt == auxfile%ntperfile) then + call med_io_close(auxfile%histfile, iam, file_ind=nfile_index, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + auxfile%nt = 0 end if - call med_io_wopen(hist_file, vm, iam, clobber=.true.) - do m = 1,2 - whead=.false. - wdata=.false. - if (m == 1) then - whead=.true. - elseif (m == 2) then - wdata=.true. - call med_io_enddef(hist_file) - endif + end if ! end of write_now if-block - tbnds = dayssince + end subroutine med_phases_history_write_hfileaux - if (tbnds(1) >= tbnds(2)) then - call med_io_write(hist_file, iam, time_units=time_units, calendar=calendar, time_val=dayssince, & - whead=whead, wdata=wdata, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - call med_io_write(hist_file, iam, time_units=time_units, calendar=calendar, time_val=dayssince, & - whead=whead, wdata=wdata, tbnds=tbnds, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif + !=============================================================================== + subroutine med_phases_history_get_filename(gcomp, doavg, comptype, hist_file, time_units, days_since, rc) - do n = 1,ncomps - if (is_local%wrap%comp_present(n)) then - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBimp(n,n),rc=rc)) then - nx = is_local%wrap%nx(n) - ny = is_local%wrap%ny(n) - call med_io_write(hist_file, iam, is_local%wrap%FBimp(n,n), & - nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre=trim(compname(n))//'Imp', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBexp(n),rc=rc)) then - nx = is_local%wrap%nx(n) - ny = is_local%wrap%ny(n) - call med_io_write(hist_file, iam, is_local%wrap%FBexp(n), & - nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre=trim(compname(n))//'Exp', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif - ! write component mediator fractions - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBFrac(n),rc=rc)) then - nx = is_local%wrap%nx(n) - ny = is_local%wrap%ny(n) - call med_io_write(hist_file, iam, is_local%wrap%FBFrac(n), & - nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre='Med_frac_'//trim(compname(n)), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - ! write component mediator areas - nx = is_local%wrap%nx(n) - ny = is_local%wrap%ny(n) - call med_io_write(hist_file, iam, is_local%wrap%FBArea(n), & - nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre='MED_'//trim(compname(n)), rc=rc) - end if - enddo - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_o,rc=rc)) then - nx = is_local%wrap%nx(compocn) - ny = is_local%wrap%ny(compocn) - call med_io_write(hist_file, iam, is_local%wrap%FBMed_ocnalb_o, & - nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre='Med_alb_ocn', rc=rc) - end if - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_o,rc=rc) .and. & - ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(compatm,compocn))) then - ! This provides the atm input on the ocn mesh needed for that atm/ocn calculation - ! that currently is restricted to the ocn mesh - nx = is_local%wrap%nx(compocn) - ny = is_local%wrap%ny(compocn) - call med_io_write(hist_file, iam, is_local%wrap%FBImp(compatm,compocn), & - nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre='AtmImp_ocn', rc=rc) - end if - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_o,rc=rc)) then - nx = is_local%wrap%nx(compocn) - ny = is_local%wrap%ny(compocn) - call med_io_write(hist_file, iam, is_local%wrap%FBMed_aoflux_o, & - nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre='Med_aoflux_ocn', rc=rc) - end if - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_a,rc=rc)) then - nx = is_local%wrap%nx(compatm) - ny = is_local%wrap%ny(compatm) - call med_io_write(hist_file, iam, is_local%wrap%FBMed_ocnalb_a, & - nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre='Med_alb_atm', rc=rc) - end if - if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_aoflux_a,rc=rc)) then - nx = is_local%wrap%nx(compatm) - ny = is_local%wrap%ny(compatm) - call med_io_write(hist_file, iam, is_local%wrap%FBMed_aoflux_a, & - nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre='Med_aoflux_atm', rc=rc) - end if - enddo + ! input/output variables + type(ESMF_GridComp) , intent(inout) :: gcomp + logical , intent(in) :: doavg + character(len=*) , intent(in) :: comptype + character(len=*) , intent(out) :: hist_file + character(len=*) , intent(out) :: time_units + real(r8) , intent(out) :: days_since ! Time interval since reference time + integer , intent(out) :: rc - call med_io_close(hist_file, iam, rc=rc) + ! local variables + type(ESMF_Clock) :: mclock + type(ESMF_Time) :: currtime + type(ESMF_Time) :: starttime + type(ESMF_Time) :: nexttime + type(ESMF_TimeInterval) :: timediff ! Used to calculate curr_time + type(ESMF_Calendar) :: calendar ! calendar type + character(len=CS) :: currtimestr + character(len=CS) :: nexttimestr + integer :: start_ymd ! Starting date YYYYMMDD + integer :: yr,mon,day,sec ! time units + logical :: isPresent + character(len=CS) :: histstr + character(len=*), parameter :: subname='(med_phases_history_get_filename)' + !--------------------------------------- + + rc = ESMF_SUCCESS + + ! Get time unit attribute value for variables + call NUOPC_ModelGet(gcomp, modelClock=mclock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGet(mclock, currtime=currtime, starttime=starttime, calendar=calendar, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGetNextTime(mclock, nextTime=nexttime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeGet(currtime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(currtimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec + call ESMF_TimeGet(nexttime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(nexttimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec + timediff = nexttime - starttime + call ESMF_TimeIntervalGet(timediff, d=day, s=sec, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + days_since = day + sec/real(SecPerDay,R8) + call ESMF_TimeGet(starttime, yy=yr, mm=mon, dd=day, s=sec, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_io_ymd2date(yr,mon,day,start_ymd) + time_units = 'days since ' // trim(med_io_date2yyyymmdd(start_ymd)) // ' ' // med_io_sec2hms(sec, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Determine history file name + ! Use nexttimestr rather than currtimestr here since that is the time at the end of + ! the timestep and is preferred for history file names + if (doavg) then + histstr = 'ha.' + else + histstr = 'hi.' + end if + if (trim(comptype) /= 'all') then + histstr = trim(histstr) // trim(comptype) // '.' + end if + if (trim(case_name) == 'unset') then + call med_phases_history_set_casename(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + write(hist_file,"(6a)") trim(case_name),'.cpl.',trim(inst_tag),trim(histstr),trim(nexttimestr),'.nc' + if (mastertask) then + write(logunit,*) + write(logunit,' (a)') " writing mediator history file "//trim(hist_file) + write(logunit,' (a)') " currtime = "//trim(currtimestr)//" nexttime = "//trim(nexttimestr) + end if - endif + end subroutine med_phases_history_get_filename + + !=============================================================================== + subroutine med_phases_history_get_auxflds(str, flds, rc) + + ! input/output variables + character(len=*) , intent(in) :: str ! colon deliminted string to search + character(len=*) , allocatable , intent(out) :: flds(:) ! memory will be allocate for flds + integer , intent(out) :: rc + + ! local variables + integer :: i,k,n ! generic indecies + integer :: nflds ! allocatable size of flds + integer :: count ! counts occurances of char + integer :: kFlds ! number of fields in list + integer :: i0,i1 ! name = list(i0:i1) + integer :: nChar ! temporary + logical :: valid ! check if str is valid + !--------------------------------------- - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + rc = ESMF_SUCCESS + + ! check that this is a str is a valid colon dlimited list + valid = .true. + nChar = len_trim(str) + if (nChar < 1) then ! list is an empty string + valid = .false. + else if (str(1:1) == ':') then ! first char is delimiter + valid = .false. + else if (str(nChar:nChar) == ':') then ! last char is delimiter + valid = .false. + else if (index(trim(str)," ") > 0) then ! white-space in a field name + valid = .false. + end if + if (.not. valid) then + if (mastertask) write(logunit,*) "ERROR: invalid list = ",trim(str) + call ESMF_LogWrite("ERROR: invalid list = "//trim(str), ESMF_LOGMSG_ERROR) + rc = ESMF_FAILURE + return + end if + + ! get number of fields in a colon delimited string list + nflds = 0 + if (len_trim(str) > 0) then + count = 0 + do n = 1, len_trim(str) + if (str(n:n) == ':') count = count + 1 + end do + nflds = count + 1 endif - call t_stopf('MED:'//subname) - first_time = .false. + ! allocate memory for flds) + allocate(flds(nflds)) - end subroutine med_phases_history_write + do k = 1,nflds + ! start with whole list + i0 = 1 + i1 = len_trim(str) + + ! remove field names before kth field + do n = 2,k + i = index(str(i0:i1),':') + i0 = i0 + i + end do + + ! remove field names after kth field + if (k < nFlds) then + i = index(str(i0:i1),':') + i1 = i0 + i - 2 + end if + + ! set flds(k) + flds(k) = str(i0:i1)//" " + end do + + end subroutine med_phases_history_get_auxflds + + !=============================================================================== + subroutine med_phases_history_output_alarminfo(mclock, alarm, alarmname, rc) + + ! input/output variables + type(ESMF_Clock), intent(in) :: mclock + type(ESMF_Alarm), intent(in) :: alarm + character(len=*), intent(in) :: alarmname + integer , intent(out) :: rc + + ! local variables + type(ESMF_TimeInterval) :: ringInterval + integer :: ringInterval_length + type(ESMF_Time) :: currtime + type(ESMF_Time) :: nexttime + character(len=CS) :: currtimestr + character(len=CS) :: nexttimestr + integer :: yr,mon,day,sec ! time units + character(len=*), parameter :: subname='(med_phases_history_output_alarminfo)' + !--------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_AlarmGet(alarm, ringInterval=ringInterval, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeIntervalGet(ringInterval, s=ringinterval_length, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGet(mclock, currtime=currtime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeGet(currtime,yy=yr, mm=mon, dd=day, s=sec, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + write(currtimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec + call ESMF_ClockGetNextTime(mclock, nextTime=nexttime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeGet(nexttime, yy=yr, mm=mon, dd=day, s=sec, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (mastertask) then + write(nexttimestr,'(i4.4,a,i2.2,a,i2.2,a,i5.5)') yr,'-',mon,'-',day,'-',sec + write(logunit,*) + write(logunit,'(a,i8)') trim(subname)//": history alarmname "//trim(alarmname)//& + ' is ringing, interval length is ', ringInterval_length + write(logunit,'(a)') trim(subname)//": currtime = "//trim(currtimestr)//" nexttime = "//trim(nexttimestr) + end if + + end subroutine med_phases_history_output_alarminfo !=============================================================================== + subroutine med_phases_history_ymds2rday_offset(currtime, rdays_offset, & + years_offset, months_offset, days_offset, seconds_offset, rc) + + ! Given the current time and optional year, month, day and seconds offsets + ! from the current time: Return an offset from the current time given in fractional days. + ! For example, if day_offset = -2 and seconds_offset = -21600, rday_offset will be -2.25. + ! One or more of the following optional arguments should be provided: + + ! input/output variables + type(ESMF_Time) , intent(in) :: currtime ! current time + real(r8) , intent(out) :: rdays_offset ! offset from current time in fractional days + integer , intent(in), optional :: years_offset ! number of years offset from current time + integer , intent(in), optional :: months_offset ! number of months offset from current time + integer , intent(in), optional :: days_offset ! number of days offset from current time + integer , intent(in), optional :: seconds_offset ! number of seconds offset from current time + integer , intent(out) :: rc + + ! local variables + type(ESMF_TimeInterval) :: timeinterval + !--------------------------------------- + + rc = ESMF_SUCCESS + + call ESMF_TimeIntervalSet(timeinterval=timeinterval, startTime=currtime, & + YY=years_offset, MM=months_offset, D=days_offset, S=seconds_offset, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + call ESMF_TimeIntervalGet(timeinterval=timeinterval, d_r8=rdays_offset, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end subroutine med_phases_history_ymds2rday_offset + + !=============================================================================== + subroutine med_phases_history_set_casename(gcomp, rc) + + ! Set module variables case_name and inst_tag + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + logical :: isPresent + logical :: isSet + !--------------------------------------- + rc = ESMF_SUCCESS + + call NUOPC_CompAttributeGet(gcomp, name='case_name', value=case_name, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompAttributeGet(gcomp, name='inst_suffix', isPresent=isPresent, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if(isPresent) then + call NUOPC_CompAttributeGet(gcomp, name='inst_suffix', value=inst_tag, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else + inst_tag = "" + endif + + end subroutine med_phases_history_set_casename end module med_phases_history_mod diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index e26f3b5f1..c27dd281a 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -193,7 +193,7 @@ subroutine med_phases_prep_atm(gcomp, rc) end if ! Note - the following needs a custom merge since Faoo_fco2_ocn is scaled by (ifrac+ofrac) - ! in the merge to the atm + ! in the merge to the atm if ( FB_FldChk(is_local%wrap%FBExp(compatm) , 'Faoo_fco2_ocn', rc=rc) .and. & FB_FldChk(is_local%wrap%FBImp(compocn,compocn), 'Faoo_fco2_ocn', rc=rc)) then call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 4c0879a2c..93044dd01 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -167,7 +167,7 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! Initialize prepglc_clock ! ------------------------------- - ! Initialize prepglc_clock from mclock - THIS CALL DOES NOT COPY ALARMS + ! Initialize mediator prepglc_clock from mclock - THIS CALL DOES NOT COPY ALARMS call NUOPC_ModelGet(gcomp, modelClock=med_clock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return prepglc_clock = ESMF_ClockCreate(med_clock, rc=rc) @@ -605,9 +605,6 @@ subroutine med_phases_prep_glc(gcomp, rc) type(ESMF_Clock) :: med_clock type(ESMF_Time) :: med_currtime type(ESMF_Time) :: prepglc_currtime - type(ESMF_ALARM) :: glc_avg_alarm - character(len=CS) :: glc_avg_period - integer :: glc_cpl_dt integer :: yr_med, mon_med, day_med, sec_med integer :: yr_prepglc, mon_prepglc, day_prepglc, sec_prepglc type(ESMF_Alarm) :: alarm diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index 4f12f97ad..5046ed3bf 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -29,7 +29,7 @@ subroutine med_phases_prep_ice(gcomp, rc) use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldGet, ESMF_Field use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE use ESMF , only : ESMF_StateItem_Flag, ESMF_STATEITEM_NOTFOUND - use ESMF , only : ESMF_VMBroadCast + use ESMF , only : ESMF_VMBroadCast use med_utils_mod , only : chkerr => med_utils_ChkErr use med_methods_mod , only : FB_fldchk => med_methods_FB_FldChk use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose @@ -91,12 +91,12 @@ subroutine med_phases_prep_ice(gcomp, rc) ! Apply precipitation factor from ocean (that scales atm rain and snow to ice) if appropriate if (trim(coupling_mode) == 'cesm' .and. is_local%wrap%flds_scalar_index_precip_factor /= 0) then - ! Note that in med_internal_mod.F90 all is_local%wrap%flds_scalar_index_precip_factor + ! Note that in med_internal_mod.F90 all is_local%wrap%flds_scalar_index_precip_factor ! is initialized to 0. - ! In addition, in med.F90, if this attribute is not present as a mediator component attribute, - ! it is set to 0. + ! In addition, in med.F90, if this attribute is not present as a mediator component attribute, + ! it is set to 0. if (mastertask) then - call ESMF_StateGet(is_local%wrap%NstateImp(compocn), & + call ESMF_StateGet(is_local%wrap%NstateImp(compocn), & itemName=trim(is_local%wrap%flds_scalar_name), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(lfield, farrayPtr=dataptr_scalar_ocn, rc=rc) @@ -111,7 +111,7 @@ subroutine med_phases_prep_ice(gcomp, rc) end if call ESMF_VMBroadCast(is_local%wrap%vm, precip_fact, 1, 0, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - is_local%wrap%flds_scalar_precip_factor = precip_fact(1) + is_local%wrap%flds_scalar_precip_factor = precip_fact(1) if (dbug_flag > 5) then write(cvalue,*) precip_fact(1) call ESMF_LogWrite(trim(subname)//" precip_fact is "//trim(cvalue), ESMF_LOGMSG_INFO) diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 705d8a595..51724336d 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -438,12 +438,12 @@ subroutine med_phases_prep_ocn_custom_cesm(gcomp, rc) ! Apply precipitation factor from ocean (that scales atm rain and snow back to ocn ) if appropriate if (trim(coupling_mode) == 'cesm' .and. is_local%wrap%flds_scalar_index_precip_factor /= 0) then - ! Note that in med_internal_mod.F90 all is_local%wrap%flds_scalar_index_precip_factor + ! Note that in med_internal_mod.F90 all is_local%wrap%flds_scalar_index_precip_factor ! is initialized to 0. - ! In addition, in med.F90, if this attribute is not present as a mediator component attribute, - ! it is set to 0. + ! In addition, in med.F90, if this attribute is not present as a mediator component attribute, + ! it is set to 0. if (mastertask) then - call ESMF_StateGet(is_local%wrap%NstateImp(compocn), & + call ESMF_StateGet(is_local%wrap%NstateImp(compocn), & itemName=trim(is_local%wrap%flds_scalar_name), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(lfield, farrayPtr=dataptr_scalar_ocn, rc=rc) @@ -458,7 +458,7 @@ subroutine med_phases_prep_ocn_custom_cesm(gcomp, rc) end if call ESMF_VMBroadCast(is_local%wrap%vm, precip_fact, 1, 0, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - is_local%wrap%flds_scalar_precip_factor = precip_fact(1) + is_local%wrap%flds_scalar_precip_factor = precip_fact(1) if (dbug_flag > 5) then write(cvalue,*) precip_fact(1) call ESMF_LogWrite(trim(subname)//" precip_fact is "//trim(cvalue), ESMF_LOGMSG_INFO) diff --git a/mediator/med_phases_restart_mod.F90 b/mediator/med_phases_restart_mod.F90 index 642816420..353d8551c 100644 --- a/mediator/med_phases_restart_mod.F90 +++ b/mediator/med_phases_restart_mod.F90 @@ -9,6 +9,7 @@ module med_phases_restart_mod use med_constants_mod , only : SecPerDay => med_constants_SecPerDay use med_utils_mod , only : chkerr => med_utils_ChkErr use med_internalstate_mod , only : mastertask, logunit, InternalState + use med_phases_history_mod, only : num_auxfiles, auxfiles use med_time_mod , only : med_time_AlarmInit use esmFlds , only : ncomps, compname, compocn use perf_mod , only : t_startf, t_stopf @@ -155,7 +156,7 @@ subroutine med_phases_restart_write(gcomp, rc) character(len=CS) :: currtimestr character(len=CS) :: nexttimestr type(InternalState) :: is_local - integer :: i,j,m,n,n1,ncnt + integer :: m,n,nf,nc ! counters integer :: curr_ymd ! Current date YYYYMMDD integer :: curr_tod ! Current time-of-day (s) integer :: start_ymd ! Starting date YYYYMMDD @@ -374,11 +375,13 @@ subroutine med_phases_restart_write(gcomp, rc) if (is_local%wrap%comp_present(n)) then nx = is_local%wrap%nx(n) ny = is_local%wrap%ny(n) + if (dbug_flag > 5) then + write(tmpstr,*) subname,' nx,ny = ',trim(compname(n)),nx,ny + call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + end if ! Write import field bundles if (ESMF_FieldBundleIsCreated(is_local%wrap%FBimp(n,n),rc=rc)) then - !write(tmpstr,*) subname,' nx,ny = ',trim(compname(n)),nx,ny - !call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) call med_io_write(restart_file, iam, is_local%wrap%FBimp(n,n), & nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre=trim(compname(n))//'Imp', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -386,8 +389,10 @@ subroutine med_phases_restart_write(gcomp, rc) ! Write export field bundles if (ESMF_FieldBundleIsCreated(is_local%wrap%FBexp(n),rc=rc)) then - !write(tmpstr,*) subname,' nx,ny = ',trim(compname(n)),nx,ny - !call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + if (dbug_flag > 5) then + write(tmpstr,*) subname,' nx,ny = ',trim(compname(n)),nx,ny + call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + end if call med_io_write(restart_file, iam, is_local%wrap%FBexp(n), & nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre=trim(compname(n))//'Exp', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -395,8 +400,6 @@ subroutine med_phases_restart_write(gcomp, rc) ! Write fraction field bundles if (ESMF_FieldBundleIsCreated(is_local%wrap%FBfrac(n),rc=rc)) then - !write(tmpstr,*) subname,' nx,ny = ',trim(compname(n)),nx,ny - !call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) call med_io_write(restart_file, iam, is_local%wrap%FBfrac(n), & nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre=trim(compname(n))//'Frac', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -405,8 +408,6 @@ subroutine med_phases_restart_write(gcomp, rc) ! Write export field bundle accumulators if (ESMF_FieldBundleIsCreated(is_local%wrap%FBExpAccum(n),rc=rc)) then ! TODO: only write this out if actually have done accumulation - !write(tmpstr,*) subname,' nx,ny = ',trim(compname(n)),nx,ny - !call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) call med_io_write(restart_file, iam, is_local%wrap%FBExpAccum(n), & nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre=trim(compname(n))//'ExpAccum', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -415,8 +416,6 @@ subroutine med_phases_restart_write(gcomp, rc) ! Write import field bundle accumulators if (ESMF_FieldBundleIsCreated(is_local%wrap%FBImpAccum(n,n),rc=rc)) then ! TODO: only write this out if actually have done accumulation - !write(tmpstr,*) subname,' nx,ny = ',trim(compname(n)),nx,ny - !call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) call med_io_write(restart_file, iam, is_local%wrap%FBImpAccum(n,n), & nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre=trim(compname(n))//'ImpAccum', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -427,13 +426,30 @@ subroutine med_phases_restart_write(gcomp, rc) ! Write ocn albedo field bundle (CESM only) if (ESMF_FieldBundleIsCreated(is_local%wrap%FBMed_ocnalb_o,rc=rc)) then - nx = is_local%wrap%nx(compocn) - ny = is_local%wrap%ny(compocn) call med_io_write(restart_file, iam, is_local%wrap%FBMed_ocnalb_o, & - nx=nx, ny=ny, nt=1, whead=whead, wdata=wdata, pre='MedOcnAlb_o', rc=rc) + nx=is_local%wrap%nx(compocn), ny=is_local%wrap%ny(compocn), nt=1, & + whead=whead, wdata=wdata, pre='MedOcnAlb_o', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if + ! Write auxiliary files accumulation - + ! For now assume that any time averaged history file has only + ! one time sample - this will be generalized in the future + do nc = 2,ncomps + do nf = 1,num_auxfiles(nc) + if (auxfiles(nc,nf)%useavg .and. auxfiles(nc,nf)%accumcnt > 0) then + call med_io_write(restart_file, iam, auxfiles(nc,nf)%accumcnt, & + trim(compname(nc))//trim(auxfiles(nc,nf)%auxname)//'_accumcnt', & + whead=whead, wdata=wdata, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_io_write(restart_file, iam, auxfiles(nc,nf)%FBaccum, & + nx=is_local%wrap%nx(nc), ny=is_local%wrap%ny(nc), nt=1, whead=whead, wdata=wdata, & + pre=trim(compname(nc))//trim(auxfiles(nc,nf)%auxname), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end do + end do + enddo ! Close file diff --git a/mediator/med_time_mod.F90 b/mediator/med_time_mod.F90 index 09dbaffb9..fbdf51541 100644 --- a/mediator/med_time_mod.F90 +++ b/mediator/med_time_mod.F90 @@ -15,9 +15,9 @@ module med_time_mod use ESMF , only : operator(<), operator(/=), operator(+) use ESMF , only : operator(-), operator(*) , operator(>=) use ESMF , only : operator(<=), operator(>), operator(==) - use NUOPC , only : NUOPC_CompAttributeGet use med_constants_mod , only : dbug_flag => med_constants_dbug_flag use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_internalstate_mod, only : mastertask, logunit implicit none private ! default private @@ -246,6 +246,10 @@ subroutine med_time_alarmInit( clock, alarm, option, & enddo endif + if (mastertask) then + write(logunit,'(a)') trim(subname) //' creating alarm '// trim(lalarmname) + end if + alarm = ESMF_AlarmCreate( name=lalarmname, clock=clock, ringTime=NextAlarm, & ringInterval=AlarmInterval, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/nuopc_cap_share/nuopc_shr_methods.F90 b/nuopc_cap_share/nuopc_shr_methods.F90 index 8d3283a4f..8cbf91056 100644 --- a/nuopc_cap_share/nuopc_shr_methods.F90 +++ b/nuopc_cap_share/nuopc_shr_methods.F90 @@ -60,8 +60,7 @@ module nuopc_shr_methods optNYear = "nyear" , & optMonthly = "monthly" , & optYearly = "yearly" , & - optDate = "date" , & - optIfdays0 = "ifdays0" + optDate = "date" ! Module data integer, parameter :: SecPerDay = 86400 ! Seconds per day @@ -572,22 +571,6 @@ subroutine alarmInit( clock, alarm, option, & if (chkerr(rc,__LINE__,u_FILE_u)) return update_nextalarm = .false. - case (optIfdays0) - if (.not. present(opt_ymd)) then - call shr_sys_abort(subname//trim(option)//' requires opt_ymd') - end if - if (.not.present(opt_n)) then - call shr_sys_abort(subname//trim(option)//' requires opt_n') - end if - if (opt_n <= 0) then - call shr_sys_abort(subname//trim(option)//' invalid opt_n') - end if - call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=opt_n, s=0, calendar=cal, rc=rc ) - if (chkerr(rc,__LINE__,u_FILE_u)) return - update_nextalarm = .true. - case (optNSteps) if (.not.present(opt_n)) then call shr_sys_abort(subname//trim(option)//' requires opt_n') @@ -808,7 +791,6 @@ subroutine timeInit( Time, ymd, cal, tod, rc) ! local variables integer :: year, mon, day ! year, month, day as integers integer :: tdate ! temporary date - integer :: date ! coded-date (yyyymmdd) character(len=*), parameter :: subname='(timeInit)' !------------------------------------------------------------------------------- @@ -818,9 +800,9 @@ subroutine timeInit( Time, ymd, cal, tod, rc) call shr_sys_abort( subname//'ERROR yymmdd is a negative number or time-of-day out of bounds' ) end if - tdate = abs(date) + tdate = abs(ymd) year = int(tdate/10000) - if (date < 0) year = -year + if (ymd < 0) year = -year mon = int( mod(tdate,10000)/ 100) day = mod(tdate, 100)