diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 56d960517..4c5d6f02f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -16,18 +16,26 @@ Any User Interface Changes (namelist or namelist defaults changes)? - [ ] No Testing performed if application target is CESM:(either UFS-S2S or CESM testing is required): -- [ ] (required) CIME_DRIVER=nuopc scripts_regression_tests.py +- [ ] (recommended) CIME_DRIVER=nuopc scripts_regression_tests.py - machines: - details (e.g. failed tests): -- [ ] (required) CESM testlist_drv.xml +- [ ] (recommended) CESM testlist_drv.xml - machines and compilers: - details (e.g. failed tests): - [ ] (optional) CESM prealpha test - machines and compilers - details (e.g. failed tests): +- [ ] (other) please described in detail + - machines and compilers + - details (e.g. failed tests): Testing performed if application target is UFS-S2S: -- [ ] (required) UFS-S2S testing +- [ ] (recommended) UFS-S2S testing + - description: + - details (e.g. failed tests): + +Testing performed if application target is UFS-HAFS: +- [ ] (recommended) UFS-HAFS testing - description: - details (e.g. failed tests): @@ -40,3 +48,7 @@ Hashes used for testing: - repository to check out: - branch: - hash: +- [ ] UFS-HAFS, then umbrella repostiory to check out and associated hash: + - repository to check out: + - branch: + - hash: diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 3bbc58483..1ea7ea455 100644 --- a/cime_config/namelist_definition_drv.xml +++ b/cime_config/namelist_definition_drv.xml @@ -18,15 +18,6 @@ - - char - nuopc - DRIVER_attributes - - $ESMF_PROFILING_LEVEL - - - char nuopc @@ -393,6 +384,15 @@ + + char + nuopc + ALLCOMP_attributes + + $ESMF_PROFILING_LEVEL + + + char orbital diff --git a/cime_config/runseq/runseq_D.py b/cime_config/runseq/runseq_D.py index 5b7bcdf39..3d108fe30 100644 --- a/cime_config/runseq/runseq_D.py +++ b/cime_config/runseq/runseq_D.py @@ -31,32 +31,38 @@ def gen_runseq(case, coupling_times): runseq.enter_time_loop(ocn_cpl_time, newtime=((ocn_cpl_time))) - runseq.add_action("MED med_phases_prep_ocn_accum_avg", med_to_ocn) - runseq.add_action("MED -> OCN :remapMethod=redist" , med_to_ocn) + runseq.add_action("MED med_phases_prep_ocn_avg" , med_to_ocn) + runseq.add_action("MED -> OCN :remapMethod=redist" , med_to_ocn) runseq.enter_time_loop(atm_cpl_time, newtime=((atm_cpl_time < ocn_cpl_time))) - runseq.add_action ("MED med_phases_prep_ocn_map" , med_to_ocn) - runseq.add_action ("MED med_phases_aofluxes_run" , run_ocn and run_atm and (med_to_ocn or med_to_atm)) - runseq.add_action ("MED med_phases_prep_ocn_merge" , med_to_ocn) - runseq.add_action ("MED med_phases_prep_ocn_accum_fast" , med_to_ocn) - runseq.add_action ("MED med_phases_ocnalb_run" , med_to_ocn) - runseq.add_action ("MED med_phases_prep_ice" , med_to_ice) - runseq.add_action ("MED -> ICE :remapMethod=redist" , med_to_ice) - runseq.add_action ("ICE" , run_ice) - runseq.add_action ("ROF" , run_rof) - runseq.add_action ("ATM" , run_atm) - runseq.add_action ("ICE -> MED :remapMethod=redist" , run_ice) - runseq.add_action ("MED med_fraction_set" , run_ice) - runseq.add_action ("ROF -> MED :remapMethod=redist" , run_rof) - runseq.add_action ("ATM -> MED :remapMethod=redist" , run_atm) - runseq.add_action ("MED med_phases_history_write" , atm_cpl_time == ocn_cpl_time) + runseq.add_action ("MED med_phases_aofluxes_run" , run_ocn and run_atm and (med_to_ocn or med_to_atm)) + runseq.add_action ("MED med_phases_prep_ocn_accum" , med_to_ocn) + runseq.add_action ("MED med_phases_ocnalb_run" , med_to_ocn) + + runseq.add_action ("MED med_phases_prep_ice" , med_to_ice) + runseq.add_action ("MED -> ICE :remapMethod=redist" , med_to_ice) + + runseq.add_action ("ICE" , run_ice) + runseq.add_action ("ROF" , run_rof) + runseq.add_action ("ATM" , run_atm) + + runseq.add_action ("ICE -> MED :remapMethod=redist" , run_ice) + runseq.add_action("MED med_phases_post_ice" , run_ice) + + runseq.add_action ("ROF -> MED :remapMethod=redist" , run_rof) + runseq.add_action("MED med_phases_post_rof" , run_rof) + + runseq.add_action ("ATM -> MED :remapMethod=redist" , run_atm) + runseq.add_action ("MED med_phases_history_write" , atm_cpl_time == ocn_cpl_time) + runseq.add_action ("MED med_phases_post_atm" , run_atm) runseq.leave_time_loop(run_rof and (atm_cpl_time < ocn_cpl_time)) - runseq.add_action ("OCN", run_ocn) - runseq.add_action ("OCN -> MED :remapMethod=redist" , run_ocn) - runseq.add_action ("MED med_phases_history_write" , atm_cpl_time < ocn_cpl_time) + runseq.add_action ("OCN" , run_ocn) + runseq.add_action ("OCN -> MED :remapMethod=redist" , run_ocn) + runseq.add_action ("MED med_phases_history_write" , atm_cpl_time < ocn_cpl_time) + runseq.add_action ("MED med_phases_post_ocn" , run_ocn) runseq.leave_time_loop(True) diff --git a/cime_config/runseq/runseq_NEMS.py b/cime_config/runseq/runseq_NEMS.py deleted file mode 100644 index f44209c41..000000000 --- a/cime_config/runseq/runseq_NEMS.py +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/env python - -import os, shutil, sys - -_CIMEROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..","..","..","..") -sys.path.append(os.path.join(_CIMEROOT, "scripts", "Tools")) - -from standard_script_setup import * -#pylint: disable=undefined-variable -logger = logging.getLogger(__name__) - -def gen_runseq(case, coupling_times): - - rundir = case.get_value("RUNDIR") - caseroot = case.get_value("CASEROOT") - - atm_cpl_dt = coupling_times["atm_cpl_dt"] - ocn_cpl_dt = coupling_times["ocn_cpl_dt"] - - outfile = open(os.path.join(caseroot, "CaseDocs", "nuopc.runseq"), "w") - - if case.get_value("CONTINUE_RUN") or case.get_value("MEDIATOR_READ_RESTART"): - logger.info("NUOPC run sequence: warm start (concurrent)") - - outfile.write ("runSeq:: \n") - outfile.write ("@" + str(ocn_cpl_dt) + " \n") - outfile.write (" MED med_phases_prep_ocn_accum_avg \n") - outfile.write (" MED -> OCN :remapMethod=redist \n") - outfile.write (" OCN \n") - outfile.write (" @" + str(atm_cpl_dt) + " \n") - outfile.write (" MED med_phases_prep_atm \n") - outfile.write (" MED med_phases_prep_ice \n") - outfile.write (" MED -> ATM :remapMethod=redist \n") - outfile.write (" MED -> ICE :remapMethod=redist \n") - outfile.write (" ATM \n") - outfile.write (" ICE \n") - outfile.write (" ATM -> MED :remapMethod=redist \n") - outfile.write (" ICE -> MED :remapMethod=redist \n") - outfile.write (" MED med_fraction_set \n") - outfile.write (" MED med_phases_prep_ocn_map \n") - outfile.write (" MED med_phases_aofluxes_run \n") - outfile.write (" MED med_phases_prep_ocn_merge \n") - outfile.write (" MED med_phases_prep_ocn_accum_fast \n") - outfile.write (" MED med_phases_history_write \n") - outfile.write (" MED med_phases_profile \n") - outfile.write (" @ \n") - outfile.write (" OCN -> MED :remapMethod=redist \n") - outfile.write (" MED med_phases_restart_write \n") - outfile.write ("@ \n") - outfile.write (":: \n") - - else: - logger.info("NUOPC run sequence: cold start (sequential)") - outfile.write ("runSeq:: \n") - outfile.write ("@" + str(ocn_cpl_dt) + " \n") - outfile.write (" @" + str(atm_cpl_dt) + " \n") - outfile.write (" MED med_phases_prep_atm \n") - outfile.write (" MED -> ATM :remapMethod=redist \n") - outfile.write (" ATM \n") - outfile.write (" ATM -> MED :remapMethod=redist \n") - outfile.write (" MED med_phases_prep_ice \n") - outfile.write (" MED -> ICE :remapMethod=redist \n") - outfile.write (" ICE \n") - outfile.write (" ICE -> MED :remapMethod=redist \n") - outfile.write (" MED med_fraction_set \n") - outfile.write (" MED med_phases_prep_ocn_map \n") - outfile.write (" MED med_phases_aofluxes_run \n") - outfile.write (" MED med_phases_prep_ocn_merge \n") - outfile.write (" MED med_phases_prep_ocn_accum_fast \n") - outfile.write (" MED med_phases_history_write \n") - outfile.write (" MED med_phases_profile \n") - outfile.write (" @ \n") - outfile.write (" MED med_phases_prep_ocn_accum_avg \n") - outfile.write (" MED -> OCN :remapMethod=redist \n") - outfile.write (" OCN \n") - outfile.write (" OCN -> MED :remapMethod=redist \n") - outfile.write (" MED med_phases_restart_write \n") - outfile.write ("@ \n") - outfile.write (":: \n") - - outfile.close() - shutil.copy(os.path.join(caseroot, "CaseDocs", "nuopc.runseq"), rundir) diff --git a/cime_config/runseq/runseq_TG.py b/cime_config/runseq/runseq_TG.py index 13b60a653..861d127d7 100644 --- a/cime_config/runseq/runseq_TG.py +++ b/cime_config/runseq/runseq_TG.py @@ -31,9 +31,8 @@ def gen_runseq(case, coupling_times): runseq.add_action ("LND" , run_lnd) runseq.add_action ("LND -> MED :remapMethod=redist" , run_lnd) - runseq.add_action ("MED med_fraction_set" , run_lnd) - runseq.add_action ("MED med_phases_prep_glc_accum" , med_to_glc) - runseq.add_action ("MED med_phases_prep_glc_avg" , med_to_glc) + runseq.add_action ("MED med_phases_post_lnd" , run_lnd) + runseq.add_action ("MED med_phases_prep_glc" , med_to_glc) 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) diff --git a/cime_config/runseq/runseq_general.py b/cime_config/runseq/runseq_general.py index 4b277dee3..3bc307488 100644 --- a/cime_config/runseq/runseq_general.py +++ b/cime_config/runseq/runseq_general.py @@ -35,6 +35,18 @@ def gen_runseq(case, coupling_times): run_rof, med_to_rof, rof_cpl_time = driver_config['rof'] run_wav, med_to_wav, wav_cpl_time = driver_config['wav'] + comp_glc = case.get_value("COMP_GLC") + run_glc = False + post_glc = False + if (comp_glc == 'cism'): + run_glc = True + if case.get_value("CISM_EVOLVE"): + post_glc = True + else: + post_glc = False + elif (comp_glc == 'xglc'): + run_glc = True + post_glc = True # Note: assume that atm_cpl_dt, lnd_cpl_dt, ice_cpl_dt and wav_cpl_dt are the same @@ -65,105 +77,114 @@ def gen_runseq(case, coupling_times): runseq.enter_time_loop(rof_cpl_time, newtime=rof_outer_loop) #------------------ - runseq.add_action("MED med_phases_prep_rof_avg" , med_to_rof and rof_outer_loop) - runseq.add_action("MED -> ROF :remapMethod=redist" , med_to_rof and rof_outer_loop) - runseq.add_action("ROF" , rof_outer_loop) - #------------------ runseq.enter_time_loop(ocn_cpl_time, newtime=ocn_outer_loop) #------------------ - runseq.add_action("MED med_phases_prep_ocn_accum_avg" , med_to_ocn and ocn_outer_loop) - runseq.add_action("MED -> OCN :remapMethod=redist" , med_to_ocn and ocn_outer_loop) + runseq.add_action("MED med_phases_prep_ocn_avg" , med_to_ocn and ocn_outer_loop) + runseq.add_action("MED -> OCN :remapMethod=redist" , med_to_ocn and ocn_outer_loop) #------------------ runseq.enter_time_loop(atm_cpl_time, newtime=inner_loop) #------------------ if (cpl_seq_option == 'RASM'): - runseq.add_action("MED med_phases_prep_ocn_map" , med_to_ocn) if cpl_add_aoflux: - runseq.add_action("MED med_phases_aofluxes_run" , run_ocn and run_atm and (med_to_ocn or med_to_atm)) - runseq.add_action("MED med_phases_prep_ocn_merge" , med_to_ocn) - runseq.add_action("MED med_phases_prep_ocn_accum_fast" , med_to_ocn) - runseq.add_action("MED med_phases_ocnalb_run" , (run_ocn and run_atm and (med_to_ocn or med_to_atm)) and not xcompset) - runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode) - - runseq.add_action("MED med_phases_prep_lnd" , med_to_lnd) - runseq.add_action("MED -> LND :remapMethod=redist" , med_to_lnd) - runseq.add_action("MED med_phases_prep_ice" , med_to_ice) - runseq.add_action("MED -> ICE :remapMethod=redist" , med_to_ice) - runseq.add_action("MED med_phases_diag_ice_med2ice" , run_ice and diag_mode) - runseq.add_action("MED med_phases_prep_wav" , med_to_wav) - runseq.add_action("MED -> WAV :remapMethod=redist" , med_to_wav) - runseq.add_action("MED med_phases_prep_rof_avg" , med_to_rof and not rof_outer_loop) - runseq.add_action("MED -> ROF :remapMethod=redist" , med_to_rof and not rof_outer_loop) - runseq.add_action("MED med_phases_prep_ocn_accum_avg" , med_to_ocn and not ocn_outer_loop) - runseq.add_action("MED -> OCN :remapMethod=redist" , med_to_ocn and not ocn_outer_loop) - runseq.add_action("ICE" , run_ice) - runseq.add_action("LND" , run_lnd) - runseq.add_action("ROF" , run_rof and not rof_outer_loop) - runseq.add_action("WAV" , run_wav) - runseq.add_action("OCN" , run_ocn and not ocn_outer_loop) + runseq.add_action("MED med_phases_aofluxes_run" , run_ocn and run_atm and (med_to_ocn or med_to_atm)) + runseq.add_action("MED med_phases_prep_ocn_accum" , med_to_ocn) + runseq.add_action("MED med_phases_ocnalb_run" , (run_ocn and run_atm and (med_to_ocn or med_to_atm)) and not xcompset) + runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode) + + runseq.add_action("MED med_phases_prep_lnd" , med_to_lnd) + runseq.add_action("MED -> LND :remapMethod=redist" , med_to_lnd) + + runseq.add_action("MED med_phases_prep_ice" , med_to_ice) + runseq.add_action("MED -> ICE :remapMethod=redist" , med_to_ice) + runseq.add_action("MED med_phases_diag_ice_med2ice" , run_ice and diag_mode) + + runseq.add_action("MED med_phases_prep_wav" , med_to_wav) + runseq.add_action("MED -> WAV :remapMethod=redist" , med_to_wav) + + runseq.add_action("MED med_phases_prep_rof" , med_to_rof and not rof_outer_loop) + runseq.add_action("MED -> ROF :remapMethod=redist" , med_to_rof and not rof_outer_loop) + + runseq.add_action("MED med_phases_prep_ocn_avg" , med_to_ocn and not ocn_outer_loop) + runseq.add_action("MED -> OCN :remapMethod=redist" , med_to_ocn and not ocn_outer_loop) + + runseq.add_action("ICE" , run_ice) + runseq.add_action("LND" , run_lnd) + runseq.add_action("ROF" , run_rof and not rof_outer_loop) + runseq.add_action("WAV" , run_wav) + runseq.add_action("OCN" , run_ocn and not ocn_outer_loop) if coupling_mode == 'hafs': - runseq.add_action("OCN -> MED :remapMethod=redist:ignoreUnmatchedIndices=true" , run_ocn and not ocn_outer_loop) + runseq.add_action("OCN -> MED :remapMethod=redist:ignoreUnmatchedIndices=true", run_ocn and not ocn_outer_loop) else: - runseq.add_action("OCN -> MED :remapMethod=redist" , run_ocn and not ocn_outer_loop) + runseq.add_action("OCN -> MED :remapMethod=redist", run_ocn and not ocn_outer_loop) + runseq.add_action("MED med_phases_post_ocn", run_ocn and not ocn_outer_loop) if (cpl_seq_option == 'TIGHT'): - runseq.add_action("MED med_phases_prep_ocn_map" , med_to_ocn) if cpl_add_aoflux: - runseq.add_action("MED med_phases_aofluxes_run" , run_ocn and run_atm) - runseq.add_action("MED med_phases_prep_ocn_merge" , med_to_ocn) - runseq.add_action("MED med_phases_prep_ocn_accum_fast" , med_to_ocn) - runseq.add_action("MED med_phases_ocnalb_run" , (run_ocn and run_atm) and not xcompset) - runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode) - - runseq.add_action("LND -> MED :remapMethod=redist" , run_lnd) - runseq.add_action("ICE -> MED :remapMethod=redist" , run_ice) - runseq.add_action("MED med_phases_diag_ice_ice2med" , run_ice and diag_mode) - runseq.add_action("MED med_fraction_set" , run_ice) - - runseq.add_action("MED med_phases_prep_rof_accum" , med_to_rof) - runseq.add_action("MED med_phases_prep_glc_accum" , med_to_glc) - runseq.add_action("MED med_phases_prep_atm" , med_to_atm) - runseq.add_action("MED -> ATM :remapMethod=redist" , med_to_atm) - runseq.add_action("ATM" , run_atm) - runseq.add_action("ATM -> MED :remapMethod=redist" , run_atm) - runseq.add_action("WAV -> MED :remapMethod=redist" , run_wav) - runseq.add_action("ROF -> MED :remapMethod=redist" , run_rof and not rof_outer_loop) - runseq.add_action("MED med_phases_diag_atm" , run_atm and diag_mode) - runseq.add_action("MED med_phases_diag_lnd" , run_lnd and diag_mode) - runseq.add_action("MED med_phases_diag_rof" , run_rof and diag_mode) - runseq.add_action("MED med_phases_diag_glc" , run_glc and diag_mode) - runseq.add_action("MED med_phases_diag_accum" , diag_mode) - runseq.add_action("MED med_phases_diag_print" , diag_mode) + runseq.add_action("MED med_phases_aofluxes_run" , run_ocn and run_atm) + runseq.add_action("MED med_phases_prep_ocn_accum" , med_to_ocn) + runseq.add_action("MED med_phases_ocnalb_run" , (run_ocn and run_atm) and not xcompset) + runseq.add_action("MED med_phases_diag_ocn" , run_ocn and diag_mode) + + runseq.add_action("LND -> MED :remapMethod=redist" , run_lnd) + runseq.add_action("MED med_phases_post_lnd" , run_lnd) + + runseq.add_action("ICE -> MED :remapMethod=redist" , run_ice) + runseq.add_action("MED med_phases_diag_ice_ice2med" , run_ice and diag_mode) + runseq.add_action("MED med_phases_post_ice" , run_ice) + + runseq.add_action("MED med_phases_prep_atm" , med_to_atm) + runseq.add_action("MED -> ATM :remapMethod=redist" , med_to_atm) + runseq.add_action("ATM" , run_atm) + runseq.add_action("ATM -> MED :remapMethod=redist" , run_atm) + runseq.add_action("MED med_phases_post_atm" , run_atm) + + runseq.add_action("WAV -> MED :remapMethod=redist", run_wav) + runseq.add_action("MED med_phases_post_wav" , run_wav) + + runseq.add_action("ROF -> MED :remapMethod=redist", run_rof and not rof_outer_loop) + runseq.add_action("MED med_phases_post_rof" , run_rof and not rof_outer_loop) + + runseq.add_action("MED med_phases_diag_atm" , run_atm and diag_mode) + runseq.add_action("MED med_phases_diag_lnd" , run_lnd and diag_mode) + runseq.add_action("MED med_phases_diag_rof" , run_rof and diag_mode) + runseq.add_action("MED med_phases_diag_glc" , run_glc and diag_mode) + runseq.add_action("MED med_phases_diag_accum" , diag_mode) + runseq.add_action("MED med_phases_diag_print" , diag_mode) + #------------------ runseq.leave_time_loop(inner_loop) #------------------ - runseq.add_action("OCN" , run_ocn and ocn_outer_loop) - + runseq.add_action("OCN", run_ocn and ocn_outer_loop) if coupling_mode == 'hafs': - runseq.add_action("OCN -> MED :remapMethod=redist:ignoreUnmatchedIndices=true" , run_ocn and ocn_outer_loop) + runseq.add_action("OCN -> MED :remapMethod=redist:ignoreUnmatchedIndices=true", run_ocn and ocn_outer_loop) else: - runseq.add_action("OCN -> MED :remapMethod=redist" , run_ocn and ocn_outer_loop) - + runseq.add_action("OCN -> MED :remapMethod=redist", run_ocn and ocn_outer_loop) + runseq.add_action("MED med_phases_post_ocn", run_ocn and ocn_outer_loop) #------------------ runseq.leave_time_loop(ocn_outer_loop) #------------------ - runseq.add_action("ROF -> MED :remapMethod=redist" , run_rof and rof_outer_loop) + runseq.add_action("MED med_phases_prep_rof" , med_to_rof and rof_outer_loop) + runseq.add_action("MED -> ROF :remapMethod=redist", med_to_rof and rof_outer_loop) + runseq.add_action("ROF" , run_rof and rof_outer_loop) + runseq.add_action("ROF -> MED :remapMethod=redist", run_rof and rof_outer_loop) + runseq.add_action("MED med_phases_post_rof" , run_rof and rof_outer_loop) #------------------ runseq.leave_time_loop(rof_outer_loop) #------------------ - runseq.add_action("MED med_phases_prep_glc_avg" , med_to_glc) + runseq.add_action("MED med_phases_prep_glc" , med_to_glc) runseq.add_action("MED -> GLC :remapMethod=redist" , med_to_glc) runseq.add_action("GLC" , run_glc and med_to_glc) runseq.add_action("GLC -> MED :remapMethod=redist" , run_glc) + runseq.add_action("MED med_phases_post_glc" , run_glc and post_glc) shutil.copy(os.path.join(caseroot, "CaseDocs", "nuopc.runseq"), rundir) diff --git a/mediator/CMakeLists.txt b/mediator/CMakeLists.txt index be5b89670..91f2921e9 100644 --- a/mediator/CMakeLists.txt +++ b/mediator/CMakeLists.txt @@ -1,18 +1,22 @@ project(cmeps Fortran) set(SRCFILES esmFldsExchange_cesm_mod.F90 med_fraction_mod.F90 - med_methods_mod.F90 med_phases_prep_ice_mod.F90 - med_phases_restart_mod.F90 esmFldsExchange_hafs_mod.F90 - med_internalstate_mod.F90 med_phases_aofluxes_mod.F90 - med_phases_prep_lnd_mod.F90 med_time_mod.F90 - esmFldsExchange_nems_mod.F90 med_io_mod.F90 - med_phases_history_mod.F90 med_phases_prep_ocn_mod.F90 - med_utils_mod.F90 esmFlds.F90 med_kind_mod.F90 - med_phases_ocnalb_mod.F90 med_phases_prep_rof_mod.F90 - med_constants_mod.F90 med_map_mod.F90 - med_phases_prep_atm_mod.F90 med_phases_prep_wav_mod.F90 - med.F90 med_merge_mod.F90 med_phases_prep_glc_mod.F90 - med_phases_profile_mod.F90 med_diag_mod.F90) + med_methods_mod.F90 med_phases_prep_ice_mod.F90 + med_phases_restart_mod.F90 esmFldsExchange_hafs_mod.F90 + med_internalstate_mod.F90 med_phases_aofluxes_mod.F90 + med_phases_prep_lnd_mod.F90 med_time_mod.F90 + esmFldsExchange_nems_mod.F90 med_io_mod.F90 + med_phases_history_mod.F90 med_phases_prep_ocn_mod.F90 + med_utils_mod.F90 esmFlds.F90 med_kind_mod.F90 + med_phases_ocnalb_mod.F90 med_phases_prep_rof_mod.F90 + med_constants_mod.F90 med_map_mod.F90 + med_phases_prep_atm_mod.F90 med_phases_prep_wav_mod.F90 + med.F90 med_merge_mod.F90 med_phases_prep_glc_mod.F90 + med_phases_profile_mod.F90 med_diag_mod.F90 + med_phases_post_ocn_mod.F90 + med_phases_post_atm_mod.F90 med_phases_post_ice_mod.F90 + med_phases_post_lnd_mod.F90 med_phases_post_glc_mod.F90 + med_phases_post_rof_mod.F90 med_phases_post_wav_mod.F90) foreach(FILE ${SRCFILES}) if(EXISTS "${CASEROOT}/SourceMods/src.cmeps/${FILE}") @@ -32,4 +36,4 @@ target_include_directories (cmeps PUBLIC "${CMAKE_BINARY_DIR}/nems/util") target_include_directories (cmeps PUBLIC ${PIO_Fortran_INCLUDE_DIR}) install(TARGETS cmeps - LIBRARY DESTINATION lib) + LIBRARY DESTINATION lib) diff --git a/mediator/Makefile b/mediator/Makefile index f1c9b5ea1..a3de3ce6c 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -22,13 +22,13 @@ OBJ = $(patsubst %.F90, %.o, $(wildcard *.F90)) all default: $(LIBRARY) $(LIBRARY): $(OBJ) - $(AR) $(ARFLAGS) $@ $? + $(AR) $(ARFLAGS) $@ $? %.o: %.F90 - $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(CPPDEFS) -I${PIO_INCLUDE_DIR} -I../nems/util $*.F90 + $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(CPPDEFS) -I${PIO_INCLUDE_DIR} -I../nems/util $*.F90 clean: - $(RM) -f $(LIBRARY) *.i90 *.o *.mod + $(RM) -f $(LIBRARY) *.i90 *.o *.mod med_kind_mod.o : med_constants_mod.o : med_kind_mod.o @@ -40,7 +40,9 @@ med.o : med_kind_mod.o med_phases_profile_mod.o med_utils_mod.o med_phases_prep_ med_phases_prep_ice_mod.o med_fraction_mod.o med_map_mod.o med_constants_mod.o med_phases_prep_wav_mod.o \ med_phases_prep_lnd_mod.o med_phases_history_mod.o med_phases_ocnalb_mod.o med_phases_restart_mod.o \ med_time_mod.o med_internalstate_mod.o med_phases_prep_atm_mod.o esmFldsExchange_cesm_mod.o esmFldsExchange_nems_mod.o \ - esmFldsExchange_hafs_mod.o med_phases_prep_glc_mod.o esmFlds.o med_io_mod.o med_methods_mod.o med_phases_prep_ocn_mod.o + esmFldsExchange_hafs_mod.o med_phases_prep_glc_mod.o esmFlds.o med_io_mod.o med_methods_mod.o med_phases_prep_ocn_mod.o \ + med_phases_post_atm_mod.o med_phases_post_ice_mod.o med_phases_post_lnd_mod.o med_phases_post_glc_mod.o med_phases_post_rof_mod.o \ + med_phases_post_wav_mod.o med_fraction_mod.o : med_kind_mod.o med_utils_mod.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o med_methods_mod.o esmFlds.o med_internalstate_mod.o : med_kind_mod.o esmFlds.o med_io_mod.o : med_kind_mod.o med_methods_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o @@ -57,6 +59,13 @@ med_phases_prep_lnd_mod.o : med_kind_mod.o med_internalstate_mod.o med_map_mod.o med_phases_prep_ocn_mod.o : med_kind_mod.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o med_merge_mod.o med_methods_mod.o esmFlds.o med_utils_mod.o med_phases_prep_rof_mod.o : med_kind_mod.o med_internalstate_mod.o med_map_mod.o med_constants_mod.o med_merge_mod.o med_methods_mod.o esmFlds.o med_utils_mod.o med_phases_prep_wav_mod.o : med_kind_mod.o med_utils_mod.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o med_methods_mod.o med_merge_mod.o esmFlds.o +med_phases_post_atm_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o +med_phases_post_ice_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o +med_phases_post_lnd_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o +med_phases_post_glc_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o +med_phases_post_ocn_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o +med_phases_post_rof_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o +med_phases_post_wav_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o med_phases_profile_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o med_internalstate_mod.o med_time_mod.o med_phases_restart_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_io_mod.o med_time_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o diff --git a/mediator/esmFlds.F90 b/mediator/esmFlds.F90 index 2daf8eb02..8747cdaca 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -63,10 +63,10 @@ module esmflds 'nstod_consd',& 'nstod_consf',& 'patch_uv3d ',& - 'glc2ocn_ice',& - 'glc2ocn_liq',& 'rof2ocn_ice',& - 'rof2ocn_liq'/) + 'rof2ocn_liq',& + 'glc2ocn_ice',& + 'glc2ocn_liq'/) !----------------------------------------------- ! Set coupling mode diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 05346bc7e..09c7c0dc5 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -150,12 +150,15 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call NUOPC_CompAttributeGet(gcomp, name='atm2ice_fmapname', value=atm2ice_fmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ice_fmapname = '// trim(atm2ice_fmap) + call NUOPC_CompAttributeGet(gcomp, name='atm2ice_smapname', value=atm2ice_smap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ice_smapname = '// trim(atm2ice_smap) + call NUOPC_CompAttributeGet(gcomp, name='atm2ice_vmapname', value=atm2ice_vmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ice_vmapname = '// trim(atm2ice_vmap) + call NUOPC_CompAttributeGet(gcomp, name='glc2ice_rmapname', value=glc2ice_rmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'glc2ice_rmapname = '// trim(glc2ice_rmap) @@ -164,27 +167,35 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_fmapname', value=atm2ocn_fmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ocn_fmapname = '// trim(atm2ocn_fmap) + call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_smapname', value=atm2ocn_smap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ocn_smapname = '// trim(atm2ocn_smap) + call NUOPC_CompAttributeGet(gcomp, name='atm2ocn_vmapname', value=atm2ocn_vmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'atm2ocn_vmapname = '// trim(atm2ocn_vmap) + call NUOPC_CompAttributeGet(gcomp, name='glc2ocn_liq_rmapname', value=glc2ocn_liq_rmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'glc2ocn_liq_rmapname = '// trim(glc2ocn_liq_rmap) + call NUOPC_CompAttributeGet(gcomp, name='glc2ocn_ice_rmapname', value=glc2ocn_ice_rmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'glc2ocn_ice_rmapname = '// trim(glc2ocn_ice_rmap) + call NUOPC_CompAttributeGet(gcomp, name='wav2ocn_smapname', value=wav2ocn_smap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'wav2ocn_smapname = '// trim(wav2ocn_smap) + call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_fmapname', value=rof2ocn_fmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'rof2ocn_fmapname = '// trim(rof2ocn_fmap) + call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_liq_rmapname', value=rof2ocn_liq_rmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'rof2ocn_liq_rmapname = '// trim(rof2ocn_liq_rmap) + call NUOPC_CompAttributeGet(gcomp, name='rof2ocn_ice_rmapname', value=rof2ocn_ice_rmap, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (mastertask) write(logunit, '(a)') trim(subname)//'rof2ocn_ice_rmapname = '// trim(rof2ocn_ice_rmap) diff --git a/mediator/med.F90 b/mediator/med.F90 index 7ea0c1376..19f73a59e 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -63,6 +63,11 @@ module MED __FILE__ logical :: profile_memory = .false. + character(len=8) :: atm_present, lnd_present + character(len=8) :: ice_present, rof_present + character(len=8) :: glc_present, med_present + character(len=8) :: ocn_present, wav_present + !----------------------------------------------------------------------------- contains !----------------------------------------------------------------------------- @@ -87,14 +92,17 @@ subroutine SetServices(gcomp, rc) use med_phases_prep_ice_mod , only: med_phases_prep_ice use med_phases_prep_lnd_mod , only: med_phases_prep_lnd use med_phases_prep_wav_mod , only: med_phases_prep_wav - use med_phases_prep_glc_mod , only: med_phases_prep_glc_accum - use med_phases_prep_glc_mod , only: med_phases_prep_glc_avg - use med_phases_prep_rof_mod , only: med_phases_prep_rof_accum - use med_phases_prep_rof_mod , only: med_phases_prep_rof_avg - use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_map - use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_merge - use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_accum_fast - use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_accum_avg + use med_phases_prep_glc_mod , only: med_phases_prep_glc + use med_phases_prep_rof_mod , only: med_phases_prep_rof + use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_accum + use med_phases_prep_ocn_mod , only: med_phases_prep_ocn_avg + use med_phases_post_atm_mod , only: med_phases_post_atm + use med_phases_post_ice_mod , only: med_phases_post_ice + use med_phases_post_lnd_mod , only: med_phases_post_lnd + use med_phases_post_glc_mod , only: med_phases_post_glc + use med_phases_post_ocn_mod , only: med_phases_post_ocn + use med_phases_post_rof_mod , only: med_phases_post_rof + use med_phases_post_wav_mod , only: med_phases_post_wav use med_phases_ocnalb_mod , only: med_phases_ocnalb_run use med_phases_aofluxes_mod , only: med_phases_aofluxes_run use med_diag_mod , only: med_phases_diag_accum, med_phases_diag_print @@ -222,7 +230,7 @@ subroutine SetServices(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ - ! prep routines for atm + ! prep and post routines for atm !------------------ call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & @@ -232,56 +240,64 @@ subroutine SetServices(gcomp, rc) specPhaseLabel="med_phases_prep_atm", specRoutine=med_phases_prep_atm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_post_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_post_atm", specRoutine=med_phases_post_atm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + !------------------ - ! prep routines for ocn + ! prep and post routines for ocn !------------------ call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_ocn_map"/), userRoutine=mediator_routine_Run, rc=rc) + phaseLabelList=(/"med_phases_prep_ocn_accum"/), 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_prep_ocn_map", specRoutine=med_phases_prep_ocn_map, rc=rc) + specPhaseLabel="med_phases_prep_ocn_accum", specRoutine=med_phases_prep_ocn_accum, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & - specPhaselabel="med_phases_prep_ocn_map", specRoutine=NUOPC_NoOp, rc=rc) + specPhaselabel="med_phases_prep_ocn_accum", specRoutine=NUOPC_NoOp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_ocn_merge"/), userRoutine=mediator_routine_Run, rc=rc) + phaseLabelList=(/"med_phases_prep_ocn_avg"/), 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_prep_ocn_merge", specRoutine=med_phases_prep_ocn_merge, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & - specPhaselabel="med_phases_prep_ocn_merge", specRoutine=NUOPC_NoOp, rc=rc) + specPhaseLabel="med_phases_prep_ocn_avg", specRoutine=med_phases_prep_ocn_avg, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_ocn_accum_fast"/), userRoutine=mediator_routine_Run, rc=rc) + phaseLabelList=(/"med_phases_post_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_prep_ocn_accum_fast", specRoutine=med_phases_prep_ocn_accum_fast, rc=rc) + specPhaseLabel="med_phases_post_ocn", specRoutine=med_phases_post_ocn, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & - specPhaselabel="med_phases_prep_ocn_accum_fast", specRoutine=NUOPC_NoOp, rc=rc) + specPhaselabel="med_phases_post_ocn", specRoutine=NUOPC_NoOp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !------------------ + ! prep and post routines for ice + !------------------ call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_ocn_accum_avg"/), userRoutine=mediator_routine_Run, rc=rc) + phaseLabelList=(/"med_phases_prep_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_prep_ocn_accum_avg", specRoutine=med_phases_prep_ocn_accum_avg, rc=rc) + specPhaseLabel="med_phases_prep_ice", specRoutine=med_phases_prep_ice, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - !------------------ - ! prep routines for ice - !------------------ - + ! note that med_fraction_set is now called from post_ice call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_ice"/), userRoutine=mediator_routine_Run, rc=rc) + phaseLabelList=(/"med_phases_post_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_prep_ice", specRoutine=med_phases_prep_ice, rc=rc) + specPhaseLabel="med_phases_post_ice", specRoutine=med_phases_post_ice, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_post_ice", specRoutine=NUOPC_NoOp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ @@ -295,29 +311,40 @@ subroutine SetServices(gcomp, rc) specPhaseLabel="med_phases_prep_lnd", specRoutine=med_phases_prep_lnd, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_post_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_post_lnd", specRoutine=med_phases_post_lnd, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_post_lnd", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + !------------------ - ! prep routines for rof + ! prep and post routines for rof !------------------ call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_rof_avg"/), userRoutine=mediator_routine_Run, rc=rc) + phaseLabelList=(/"med_phases_prep_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_prep_rof_avg", specRoutine=med_phases_prep_rof_avg, rc=rc) + specPhaseLabel="med_phases_prep_rof", specRoutine=med_phases_prep_rof, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! post routine for rof (mapping to lnd, ocn, ice) call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_rof_accum"/), userRoutine=mediator_routine_Run, rc=rc) + phaseLabelList=(/"med_phases_post_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_prep_rof_accum", specRoutine=med_phases_prep_rof_accum, rc=rc) + specPhaseLabel="med_phases_post_rof", specRoutine=med_phases_post_rof, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & - specPhaselabel="med_phases_prep_rof_accum", specRoutine=NUOPC_NoOp, rc=rc) + specPhaselabel="med_phases_post_rof", specRoutine=NUOPC_NoOp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ - ! prep routines for wav + ! prep and post routines for wav !------------------ call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & @@ -327,25 +354,36 @@ subroutine SetServices(gcomp, rc) specPhaseLabel="med_phases_prep_wav", specRoutine=med_phases_prep_wav, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + phaseLabelList=(/"med_phases_post_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_post_wav", specRoutine=med_phases_post_wav, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_post_wav", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + !------------------ - ! prep routines for glc + ! prep and post routines for glc !------------------ call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_glc_avg"/), userRoutine=mediator_routine_Run, rc=rc) + phaseLabelList=(/"med_phases_prep_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_prep_glc_avg", specRoutine=med_phases_prep_glc_avg, rc=rc) + specPhaseLabel="med_phases_prep_glc", specRoutine=med_phases_prep_glc, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! post routine for glc (mapping to lnd, ocn, ice) call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_glc_accum"/), userRoutine=mediator_routine_Run, rc=rc) + phaseLabelList=(/"med_phases_post_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_prep_glc_accum", specRoutine=med_phases_prep_glc_accum, rc=rc) + specPhaseLabel="med_phases_post_glc", specRoutine=med_phases_post_glc, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & - specPhaselabel="med_phases_prep_glc_accum", specRoutine=NUOPC_NoOp, rc=rc) + specPhaselabel="med_phases_post_glc", specRoutine=NUOPC_NoOp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ @@ -560,16 +598,22 @@ subroutine InitializeP0(gcomp, importState, exportState, clock, rc) logUnit = 6 endif - ! Obtain Verbosity + ! Obtain verbosity level call ESMF_AttributeGet(gcomp, name="Verbosity", value=cvalue, defaultValue="max", & convention="NUOPC", purpose="Instance", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": Mediator verbosity is "//trim(cvalue), ESMF_LOGMSG_INFO) + if (mastertask) then + write(logunit,'(a)')trim(subname)//": Mediator verbosity is set to "//trim(cvalue) + end if - call ESMF_AttributeGet(gcomp, name="Profiling", value=cvalue, & - convention="NUOPC", purpose="Instance", rc=rc) + ! Obtain profiling level + call NUOPC_CompAttributeGet(gcomp, name="Profiling", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": Mediator profiling is set to "//trim(cvalue), ESMF_LOGMSG_INFO) + if (isPresent .and. isSet) then + if (mastertask) then + write(logunit,'(a)') trim(subname)//": Mediator profiling is set to "//trim(cvalue) + end if + end if ! Obtain dbug_flag setting if present; otherwise use default value in med_constants call NUOPC_CompAttributeGet(gcomp, name='dbug_flag', value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) @@ -616,10 +660,6 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) character(len=8) :: cnum type(InternalState) :: is_local integer :: stat - character(len=8) :: atm_present, lnd_present - character(len=8) :: ice_present, rof_present - character(len=8) :: glc_present, med_present - character(len=8) :: ocn_present, wav_present character(len=CS) :: attrList(8) character(len=*),parameter :: subname=' (module_MED:InitializeIPDv03p1) ' !----------------------------------------------------------- @@ -1647,8 +1687,14 @@ subroutine DataInitialize(gcomp, rc) use NUOPC , only : NUOPC_CompAttributeGet use med_fraction_mod , only : med_fraction_init, med_fraction_set use med_phases_restart_mod , only : med_phases_restart_read - use med_phases_prep_glc_mod , only : med_phases_prep_glc_init use med_phases_prep_atm_mod , only : med_phases_prep_atm + use med_phases_post_atm_mod , only : med_phases_post_atm + use med_phases_post_ice_mod , only : med_phases_post_ice + use med_phases_post_lnd_mod , only : med_phases_post_lnd_init + use med_phases_post_glc_mod , only : med_phases_post_glc + use med_phases_post_ocn_mod , only : med_phases_post_ocn + use med_phases_post_rof_mod , only : med_phases_post_rof + use med_phases_post_wav_mod , only : med_phases_post_wav use med_phases_ocnalb_mod , only : med_phases_ocnalb_run use med_phases_aofluxes_mod , only : med_phases_aofluxes_run use med_phases_profile_mod , only : med_phases_profile @@ -1716,7 +1762,7 @@ subroutine DataInitialize(gcomp, rc) !---------------------------------------------------------- ! Initialize mediator present flags !---------------------------------------------------------- - + if (mastertask) then write(logunit,'(a)') trim(subname) // "Initializing present flags" end if @@ -1761,7 +1807,7 @@ subroutine DataInitialize(gcomp, rc) ! This defines the med_coupling_allowed is a starting point for what is ! allowed in this coupled system. It will be revised further after the system - ! starts, but any coupling set to false will never be allowed. + ! starts, but any coupling set to false will never be allowed. ! are allowed, just update the table below. if (mastertask) then @@ -1809,7 +1855,7 @@ subroutine DataInitialize(gcomp, rc) med_coupling_allowed(compocn,compwav) = .true. med_coupling_allowed(compice,compwav) = .true. - ! to land-ice + ! to land-ice do ns = 1,num_icesheets med_coupling_allowed(complnd,compglc(ns)) = .true. end do @@ -2217,6 +2263,11 @@ subroutine DataInitialize(gcomp, rc) deallocate(fieldNameList) if (.not. compDone(compatm)) then ! atmdone is not true + if (trim(lnd_present) == 'true') then + ! map initial lnd->atm + call med_phases_post_lnd_init(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if ! do the merge to the atmospheric component call med_phases_prep_atm(gcomp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -2260,9 +2311,11 @@ subroutine DataInitialize(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (.not. atCorrectTime) then allDone=.false. - if (mastertask) then - write(logunit,'(A)') trim(subname)//" MED - Initialize-Data-Dependency check Failed for "//& - trim(compname(n1)) + if (dbug_flag > 0) then + if (mastertask) then + write(logunit,'(A)') trim(subname)//" MED - Initialize-Data-Dependency check not yet satisfied for "//& + trim(compname(n1)) + end if end if endif enddo @@ -2282,7 +2335,10 @@ subroutine DataInitialize(gcomp, rc) !--------------------------------------- if (allDone) then - if (mastertask) write(logunit,*) + if (mastertask) then + write(logunit,*) + write(logunit,'(a)') trim(subname)//"Initialize-Data-Dependency allDone check Passed" + end if do n1 = 1,ncomps if (is_local%wrap%comp_present(n1) .and. ESMF_StateIsCreated(is_local%wrap%NStateImp(n1),rc=rc)) then call State_GetScalar(scalar_value=real_nx, & @@ -2309,13 +2365,11 @@ subroutine DataInitialize(gcomp, rc) !--------------------------------------- ! Initialize mediator IO !--------------------------------------- - call med_io_init() !--------------------------------------- ! Initialize mediator water/heat budget diags !--------------------------------------- - call med_diag_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call med_diag_zero(gcomp, mode='all', rc=rc) @@ -2324,24 +2378,62 @@ subroutine DataInitialize(gcomp, rc) !--------------------------------------- ! read mediator restarts !--------------------------------------- - call NUOPC_CompAttributeGet(gcomp, name="read_restart", value=cvalue, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call ESMF_LogWrite(subname//' read_restart = '//trim(cvalue), ESMF_LOGMSG_INFO) + if (mastertask) then + write(logunit,'(a)') trim(subname)//' read_restart = '//trim(cvalue) + end if read(cvalue,*) read_restart - if (read_restart) then call med_phases_restart_read(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif + !--------------------------------------- + ! Call post routines as part of initialization + !--------------------------------------- + if (trim(atm_present) == 'true') then + ! map atm->ocn, atm->ice, atm->lnd + call med_phases_post_atm(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + if (trim(ice_present) == 'true') then + ! call set ice_frac and map ice->atm and ice->ocn + call med_phases_post_ice(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + if (trim(glc_present) == 'true') then + ! map initial glc->lnd, glc->ocn and glc->ice + call med_phases_post_glc(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + if (trim(lnd_present) == 'true') then + ! map initial lnd->atm + call med_phases_post_lnd_init(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + if (trim(ocn_present) == 'true') then + ! map initial ocn->ice + call med_phases_post_ocn(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + if (trim(rof_present) == 'true') then + ! map initial rof->lnd, rof->ocn and rof->ice + call med_phases_post_rof(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + if (trim(wav_present) == 'true') then + ! map initial wav->ocn and wav->ice + call med_phases_post_wav(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + call med_phases_profile(gcomp, rc) else ! Not all done call NUOPC_CompAttributeSet(gcomp, name="InitializeDataComplete", value="false", rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite("MED - Initialize-Data-Dependency allDone check Failed, another loop is required", & + call ESMF_LogWrite("MED - Initialize-Data-Dependency allDone check not yet satisfied, another loop is required", & ESMF_LOGMSG_INFO) end if diff --git a/mediator/med_merge_mod.F90 b/mediator/med_merge_mod.F90 index 8b85a4a86..f08d633da 100644 --- a/mediator/med_merge_mod.F90 +++ b/mediator/med_merge_mod.F90 @@ -80,6 +80,8 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis real(r8), pointer :: dataptr1d(:) => null() real(r8), pointer :: dataptr2d(:,:) => null() character(CL) :: msg + logical :: zero_output + character(CL) :: fldname character(len=*),parameter :: subname=' (module_med_merge_mod: med_merge_auto)' !--------------------------------------- @@ -110,19 +112,7 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis ! Loop over all fields in field bundle FBOut do nfld_out = 1,fieldcount - - ! Initialize initial output field data to zero - call ESMF_FieldGet(fieldlist(nfld_out), ungriddedUBound=ungriddedUbound_out, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUBound_out(1) > 0) then - call ESMF_FieldGet(fieldlist(nfld_out), farrayPtr=dataptr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr2d(:,:) = czero - else - call ESMF_FieldGet(fieldlist(nfld_out), farrayPtr=dataptr1d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d(:) = czero - end if + zero_output = .true. ! Loop over the field in fldListTo do nfld_in = 1,med_fldList_GetNumFlds(fldListTo) @@ -168,6 +158,22 @@ subroutine med_merge_auto(compout, coupling_active, FBOut, FBfrac, FBImp, fldLis if (ChkErr(rc,__LINE__,u_FILE_u)) return end if ! end of error check + ! Initialize initial output field data to zero before doing merge + if (zero_output) then + call ESMF_FieldGet(fieldlist(nfld_out), ungriddedUBound=ungriddedUbound_out, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound_out(1) > 0) then + call ESMF_FieldGet(fieldlist(nfld_out), farrayPtr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d(:,:) = czero + else + call ESMF_FieldGet(fieldlist(nfld_out), farrayPtr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = czero + end if + zero_output = .false. + end if + ! Perform merge if ((present(FBMed1) .or. present(FBMed2)) .and. compsrc == compmed) then if (FB_FldChk(FBMed1, trim(merge_field), rc=rc)) then diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index 8ab54e4fd..e45cd70bc 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -152,17 +152,6 @@ subroutine med_phases_aofluxes_run(gcomp, rc) call memcheck(subname, 5, mastertask) - ! TODO(mvertens, 2019-01-12): ONLY regrid atm import fields that are needed for the atm/ocn flux calculation - ! Regrid atm import field bundle from atm to ocn grid as input for ocn/atm flux calculation - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(compatm,compatm), & - FBDst=is_local%wrap%FBImp(compatm,compocn), & - FBFracSrc=is_local%wrap%FBFrac(compatm), & - field_normOne=is_local%wrap%field_normOne(compatm,compocn,:), & - packed_data=is_local%wrap%packed_data(compatm,compocn,:), & - routehandles=is_local%wrap%RH(compatm,compocn,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Calculate atm/ocn fluxes on the destination grid call med_aofluxes_run(gcomp, aoflux, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return diff --git a/mediator/med_phases_post_atm_mod.F90 b/mediator/med_phases_post_atm_mod.F90 new file mode 100644 index 000000000..bd6b93230 --- /dev/null +++ b/mediator/med_phases_post_atm_mod.F90 @@ -0,0 +1,103 @@ +module med_phases_post_atm_mod + + !----------------------------------------------------------------------------- + ! Mediator phase for post atm calculations, maps atm->ice, atm->lnd and atm->ocn + !----------------------------------------------------------------------------- + + implicit none + private + + public :: med_phases_post_atm + + character(*), parameter :: u_FILE_u = & + __FILE__ + +!----------------------------------------------------------------------------- +contains +!----------------------------------------------------------------------------- + + subroutine med_phases_post_atm(gcomp, rc) + + !--------------------------------------- + ! map atm to ocn and atm to ice and atm to land + !--------------------------------------- + + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_FieldBundleGet + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 + use med_internalstate_mod , only : InternalState, mastertask, logunit + use med_map_mod , only : med_map_field_packed + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_utils_mod , only : chkerr => med_utils_ChkErr + use esmFlds , only : compocn, compatm, compice, complnd + use perf_mod , only : t_startf, t_stopf + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + character(len=*), parameter :: subname='(med_phases_post_atm)' + !------------------------------------------------------------------------------- + + rc = ESMF_SUCCESS + + call t_startf('MED:'//subname) + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + end if + + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! map atm to ocn + if (is_local%wrap%med_coupling_active(compatm,compocn)) then + call t_startf('MED:'//trim(subname)//' map_atm2ocn') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compatm,compatm), & + FBDst=is_local%wrap%FBImp(compatm,compocn), & + FBFracSrc=is_local%wrap%FBFrac(compatm), & + field_normOne=is_local%wrap%field_normOne(compatm,compocn,:), & + packed_data=is_local%wrap%packed_data(compatm,compocn,:), & + routehandles=is_local%wrap%RH(compatm,compocn,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map_atm2ocn') + end if + ! map atm->ice + if (is_local%wrap%med_coupling_active(compatm,compice)) then + call t_startf('MED:'//trim(subname)//' map_atm2ice') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compatm,compatm), & + FBDst=is_local%wrap%FBImp(compatm,compice), & + FBFracSrc=is_local%wrap%FBFrac(compatm), & + field_normOne=is_local%wrap%field_normOne(compatm,compice,:), & + packed_data=is_local%wrap%packed_data(compatm,compice,:), & + routehandles=is_local%wrap%RH(compatm,compice,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map_atm2ice') + end if + ! map atm->lnd + if (is_local%wrap%med_coupling_active(compatm,complnd)) then + call t_startf('MED:'//trim(subname)//' map_atm2lnd') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compatm,compatm), & + FBDst=is_local%wrap%FBImp(compatm,complnd), & + FBFracSrc=is_local%wrap%FBFrac(compatm), & + field_normOne=is_local%wrap%field_normOne(compatm,complnd,:), & + packed_data=is_local%wrap%packed_data(compatm,complnd,:), & + routehandles=is_local%wrap%RH(compatm,complnd,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map_atm2lnd') + end if + + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO) + end if + call t_stopf('MED:'//subname) + + end subroutine med_phases_post_atm + +end module med_phases_post_atm_mod diff --git a/mediator/med_phases_post_glc_mod.F90 b/mediator/med_phases_post_glc_mod.F90 new file mode 100644 index 000000000..6facc4433 --- /dev/null +++ b/mediator/med_phases_post_glc_mod.F90 @@ -0,0 +1,569 @@ +module med_phases_post_glc_mod + + !----------------------------------------------------------------------------- + ! Mediator phase for mapping glc->lnd and glc->ocn after the receive of glc + !----------------------------------------------------------------------------- + + use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 + use NUOPC , only : NUOPC_CompAttributeGet + use ESMF , only : operator(/=) + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR, ESMF_SUCCESS, ESMF_FAILURE + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_StateGet, ESMF_StateItem_Flag, ESMF_STATEITEM_NOTFOUND + use ESMF , only : ESMF_Mesh, ESMF_MeshLoc, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 + use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate + use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandleIsCreated + use esmFlds , only : compatm, compice, complnd, comprof, compocn, ncomps, compname + use esmFlds , only : max_icesheets, num_icesheets, compglc + use esmFlds , only : mapbilnr, mapconsd, compname + use esmFlds , only : fldListTo + use med_methods_mod , only : fldbun_diagnose => med_methods_FB_diagnose + use med_methods_mod , only : fldbun_fldchk => med_methods_FB_fldchk + use med_methods_mod , only : fldbun_getmesh => med_methods_FB_getmesh + use med_methods_mod , only : fldbun_getdata1d => med_methods_FB_getdata1d + use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d + use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d + use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_internalstate_mod , only : InternalState, mastertask, logunit + use med_map_mod , only : med_map_rh_is_created, med_map_routehandles_init + use med_map_mod , only : med_map_field_packed, med_map_field_normalized, med_map_field + use med_merge_mod , only : med_merge_auto + use glc_elevclass_mod , only : glc_get_num_elevation_classes + use glc_elevclass_mod , only : glc_mean_elevation_virtual + use glc_elevclass_mod , only : glc_get_fractional_icecov + use perf_mod , only : t_startf, t_stopf + + implicit none + private + + public :: med_phases_post_glc + + private :: map_glc2lnd_init + private :: map_glc2lnd + + ! private module variables + character(len =*), parameter :: Sg_icemask = 'Sg_icemask' + character(len =*), parameter :: Sg_icemask_coupled_fluxes = 'Sg_icemask_coupled_fluxes' + character(len =*), parameter :: Sg_frac = 'Sg_ice_covered' + character(len =*), parameter :: Sg_frac_x_icemask = 'Sg_frac_times_icemask' + character(len =*), parameter :: Sg_topo = 'Sg_topo' + character(len =*), parameter :: Flgg_hflx = 'Flgg_hflx' + + type, public :: ice_sheet_tolnd_type + character(CS) :: name + logical :: is_active + type(ESMF_Field) :: field_icemask_g ! no elevation classes + type(ESMF_Field) :: field_frac_g_ec ! elevation classes + type(ESMF_Field) :: field_frac_x_icemask_g_ec ! elevation classes + type(ESMF_Field) :: field_topo_x_icemask_g_ec ! elevation classes + type(ESMF_Mesh) :: mesh_g + end type ice_sheet_tolnd_type + type(ice_sheet_tolnd_type) :: ice_sheet_tolnd(max_icesheets) + + type(ESMF_field) :: field_icemask_l ! no elevation classes + type(ESMF_Field) :: field_frac_l_ec ! elevation classes + type(ESMF_Field) :: field_frac_x_icemask_l_ec ! elevation classes + type(ESMF_Field) :: field_topo_x_icemask_l_ec ! elevation classes + + ! the number of elevation classes (excluding bare land) = ungriddedCount - 1 + integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) + + logical :: cism_evolve = .false. + logical :: glc2lnd_coupling = .false. + logical :: glc2ocn_coupling = .false. + logical :: glc2ice_coupling = .false. + + character(*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================================ +contains +!================================================================================================ + + subroutine med_phases_post_glc(gcomp, rc) + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(ESMF_StateItem_Flag) :: itemType + type(InternalState) :: is_local + integer :: n1,ncnt,ns + real(r8) :: nextsw_cday + logical :: first_call = .true. + logical :: isPresent + character(CL) :: cvalue + character(len=*), parameter :: subname='(med_phases_post_glc)' + !--------------------------------------- + + rc = ESMF_SUCCESS + + call t_startf('MED:'//subname) + if (dbug_flag > 20) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + end if + + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + if (first_call) then + ! determine if there will be any glc to lnd coupling + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + glc2lnd_coupling = .true. + exit + end if + end do + ! determine if there will be any glc to ocn coupling + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),compocn)) then + glc2ocn_coupling = .true. + exit + end if + end do + ! determine if there will be any glc to ice coupling + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),compice)) then + glc2ice_coupling = .true. + exit + end if + end do + if (mastertask) then + write(logunit,'(a,l)') trim(subname) // 'glc2lnd_coupling is ',glc2lnd_coupling + write(logunit,'(a,l)') trim(subname) // 'glc2ocn_coupling is ',glc2ocn_coupling + write(logunit,'(a,l)') trim(subname) // 'glc2ice_coupling is ',glc2ice_coupling + end if + + ! determine if coupling to CISM is 2-way + call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent) then + call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", value=cvalue, isPresent=isPresent, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + read (cvalue,*) cism_evolve + if (mastertask) then + write(logunit,'(a,l7)') trim(subname)//' cism_evolve = ',cism_evolve + end if + end if + end if + + !--------------------------------------- + ! glc->ocn mapping - + ! merging with rof->ocn fields is done in med_phases_prep_ocn + !--------------------------------------- + if (glc2ocn_coupling) then + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),compocn)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compglc(ns),compglc(ns)), & + FBDst=is_local%wrap%FBImp(compglc(ns),compocn), & + FBFracSrc=is_local%wrap%FBFrac(compglc(ns)), & + field_normOne=is_local%wrap%field_normOne(compglc(ns),compocn,:), & + packed_data=is_local%wrap%packed_data(compglc(ns),compocn,:), & + routehandles=is_local%wrap%RH(compglc(ns),compocn,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end do + end if + + !--------------------------------------- + ! glc->ice mapping + !--------------------------------------- + if (glc2ice_coupling) then + ! Fill this in + end if + + !--------------------------------------- + ! glc->lnd mapping and custom merging of all ice sheets onto land mesh + !--------------------------------------- + if (glc2lnd_coupling) then + ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) + call t_startf('MED:'//trim(subname)//' glc2lnd ') + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compglc(ns),compglc(ns)), & + FBDst=is_local%wrap%FBImp(compglc(ns),complnd), & + FBFracSrc=is_local%wrap%FBFrac(compglc(ns)), & + field_normOne=is_local%wrap%field_normOne(compglc(ns),complnd,:), & + packed_data=is_local%wrap%packed_data(compglc(ns),complnd,:), & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end do + call t_stopf('MED:'//trim(subname)//' glc2lnd') + + ! The following is only done if glc->lnd coupling is active + if (first_call) then + call map_glc2lnd_init(gcomp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) + call map_glc2lnd(gcomp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! Reset first call logical + first_call = .false. + + if (dbug_flag > 20) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + end if + call t_stopf('MED:'//subname) + + end subroutine med_phases_post_glc + + !================================================================================================ + + subroutine map_glc2lnd_init(gcomp, rc) + + ! input/output variables + type(ESMF_GridComp) , intent(inout) :: gcomp + integer , intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + type(ESMF_Field) :: lfield_l + type(ESMF_Mesh) :: mesh_l + integer :: ungriddedUBound_output(1) + integer :: fieldCount + integer :: ns,n + type(ESMF_Field), pointer :: fieldlist(:) => null() + character(len=*) , parameter :: subname='(map_glc2lnd_init)' + !--------------------------------------- + + rc = ESMF_SUCCESS + + !--------------------------------------- + ! Get the internal state + !--------------------------------------- + + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !--------------------------------------- + ! Set the module variable for the number of elevation classes + !--------------------------------------- + + ! Determine number of elevation classes by querying a field that has elevation classes in it + call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), 'Sg_topo_elev', field=lfield_l, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield_l, ungriddedUBound=ungriddedUBound_output, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ungriddedCount = ungriddedUBound_output(1) + ! TODO: check that ungriddedCount = glc_nec+1 + + ! ------------------------------- + ! Create module fields on land mesh + ! ------------------------------- + + call fldbun_getmesh(is_local%wrap%FBExp(complnd), mesh_l, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + field_icemask_l = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + field_frac_l_ec = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + field_frac_x_icemask_l_ec = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + field_topo_x_icemask_l_ec = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + !--------------------------------------- + ! create module fields on glc mesh + !--------------------------------------- + + do ns = 1,max_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + + call fldbun_getmesh(is_local%wrap%FBImp(compglc(ns),compglc(ns)), ice_sheet_tolnd(ns)%mesh_g, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ice_sheet_tolnd(ns)%field_icemask_g = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & + ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ice_sheet_tolnd(ns)%field_frac_g_ec = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & + ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ice_sheet_tolnd(ns)%field_frac_x_icemask_g_ec = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & + ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ice_sheet_tolnd(ns)%field_topo_x_icemask_g_ec = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & + ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Create route handle if it has not been created + if (.not. ESMF_RouteHandleIsCreated(is_local%wrap%RH(compglc(ns),complnd,mapconsd), rc=rc)) then + call med_map_routehandles_init( compglc(ns), complnd, & + ice_sheet_tolnd(ns)%field_icemask_g, field_icemask_l, & + mapindex=mapconsd, & + routehandles=is_local%wrap%rh(compglc(ns),complnd,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end if + end do + + ! Currently cannot map hflx in multiple elevation classes from glc to land + if (fldbun_fldchk(is_local%wrap%FBExp(complnd), trim(Flgg_hflx), rc=rc)) then + call ESMF_LogWrite(trim(subname)//'ERROR: Flgg_hflx to land has not been implemented yet', & + ESMF_LOGMSG_ERROR, line=__LINE__, file=__FILE__) + rc = ESMF_FAILURE + return + end if + + end subroutine map_glc2lnd_init + + !================================================================================================ + subroutine map_glc2lnd( gcomp, rc) + + !------------------ + ! Maps fields from the GLC grid to the LND grid. + ! On the GLC grid the fields will not have elevation classes. + ! On the LND grid they will have elevation classes. + !------------------ + + ! input/output variables + type(ESMF_GridComp) , intent(inout) :: gcomp + integer , intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + type(ESMF_Field) :: lfield + type(ESMF_Field) :: lfield_src + type(ESMF_Field) :: lfield_dst + integer :: ec, l, g, ns, n + real(r8) :: topo_virtual + real(r8), pointer :: icemask_g(:) => null() ! glc ice mask field on glc grid + real(r8), pointer :: frac_g(:) => null() ! total ice fraction in each glc cell + real(r8), pointer :: frac_g_ec(:,:) => null() ! glc fractions on the glc grid + real(r8), pointer :: frac_l_ec(:,:) => null() ! glc fractions on the land grid + real(r8), pointer :: topo_g(:) => null() ! topo height of each glc cell (no elev classes) + real(r8), pointer :: topo_l_ec(:,:) => null() ! topo height in each land gridcell for each elev class + real(r8), pointer :: frac_x_icemask_g_ec(:,:) => null() ! (glc fraction) x (icemask), on the glc grid + real(r8), pointer :: frac_x_icemask_l_ec(:,:) => null() + real(r8), pointer :: topo_x_icemask_g_ec(:,:) => null() + real(r8), pointer :: topo_x_icemask_l_ec(:,:) => null() + real(r8), pointer :: dataptr1d(:) => null() + real(r8), pointer :: dataptr2d(:,:) => null() + real(r8), pointer :: frac_l_ec_sum(:,:) => null() + real(r8), pointer :: topo_l_ec_sum(:,:) => null() + real(r8), pointer :: dataptr1d_src(:) => null() + real(r8), pointer :: dataptr1d_dst(:) => null() + character(len=*), parameter :: subname = 'map_glc2lnd' + !----------------------------------------------------------------------- + + call t_startf('MED:'//subname) + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + end if + rc = ESMF_SUCCESS + + !--------------------------------------- + ! Get the internal state + !--------------------------------------- + + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + !--------------------------------- + ! Get pointers into land export field bundle (this is summed over all ice sheets) + !--------------------------------- + + call fldbun_getdata2d(is_local%wrap%FBExp(complnd), trim(Sg_frac)//'_elev', frac_l_ec_sum, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + frac_l_ec_sum(:,:) = 0._r8 + + call fldbun_getdata2d(is_local%wrap%FBExp(complnd), trim(Sg_topo)//'_elev', topo_l_ec_sum, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + topo_l_ec_sum(:,:) = 0._r8 + + !--------------------------------- + ! Map fractional ice coverage to the land grid (multiple elevation classes) + !--------------------------------- + + ! Map Sg_icemask and Sg_icemask_coupled_fluxes (no elevation classes) + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + call t_startf('MED:'//trim(subname)//' glc2lnd ') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compglc(ns),compglc(ns)), & + FBDst=is_local%wrap%FBImp(compglc(ns),complnd), & + FBFracSrc=is_local%wrap%FBFrac(compglc(ns)), & + field_normOne=is_local%wrap%field_normOne(compglc(ns),complnd,:), & + packed_data=is_local%wrap%packed_data(compglc(ns),complnd,:), & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' glc2lnd') + end if + end do + + ! Get Sg_icemask on land as sum of all ice sheets (no elevation classes) + call fldbun_getdata1d(is_local%wrap%FBExp(complnd), Sg_icemask, dataptr1d_dst, rc) + dataptr1d_dst(:) = 0._r8 + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),complnd), Sg_icemask, dataptr1d_src, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d_dst(:) = dataptr1d_dst(:) + dataptr1d_src(:) + end if + end do + + ! Get Sg_icemask_coupled_fluxes on land as sum of all ice sheets (no elevation classes) + call fldbun_getdata1d(is_local%wrap%FBExp(complnd), Sg_icemask_coupled_fluxes, dataptr1d_dst, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d_dst(:) = 0._r8 + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),complnd), Sg_icemask_coupled_fluxes, dataptr1d_src, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d_dst(:) = dataptr1d_dst(:) + dataptr1d_src(:) + end if + end do + + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then + + ! Set (fractional ice coverage for each elevation class on the glc grid) + + ! get topo_g(:) - the topographic height of each glc gridcell + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_topo, topo_g, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! get frac_g(:) - the total ice fraction in each glc gridcell + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_frac, frac_g, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! compute frac_g_ec(:,:) - the glc fractions on the glc grid for each elevation class (inner dimension) + call field_getdata2d(ice_sheet_tolnd(ns)%field_frac_g_ec, frac_g_ec, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call glc_get_fractional_icecov(ungriddedCount-1, topo_g, frac_g, frac_g_ec, logunit) + + ! compute icemask_g + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_icemask, dataptr1d, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata1d(ice_sheet_tolnd(ns)%field_icemask_g, icemask_g, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + icemask_g(:) = dataptr1d(:) + + ! compute frac_x_icemask_g_ec + ! only include grid cells that are both (a) within the icemask and (b) in this elevation class + call field_getdata2d(ice_sheet_tolnd(ns)%field_frac_x_icemask_g_ec, frac_x_icemask_g_ec, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ec = 1, ungriddedCount + frac_x_icemask_g_ec(ec,:) = frac_g_ec(ec,:) * icemask_g(:) + end do + + ! map frac_g_ec to frac_l_ec and normalize by icemask_g + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": calling mapping elevation class fractions from glc to land", & + ESMF_LOGMSG_INFO) + end if + call med_map_field_normalized( & + field_src=ice_sheet_tolnd(ns)%field_frac_g_ec, & + field_dst=field_frac_l_ec, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & + maptype=mapconsd, & + field_normsrc=ice_sheet_tolnd(ns)%field_icemask_g, & + field_normdst=field_icemask_l, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! now set values in land export state for Sg_frac_elev (this is summed over all ice sheets) + call field_getdata2d(field_frac_l_ec, frac_l_ec, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + frac_l_ec_sum(:,:) = frac_l_ec_sum(:,:) + frac_l_ec(:,:) + + !--------------------------------- + ! Map topo to the land grid (multiple elevation classes) + !--------------------------------- + + ! Note that all topo values in FBimp(compglc(ns),compglc(ns)) do not have elevation class dependence + ! Normalize by frac_x_icemask_g_ec - this is what introduces + ! elevation class information from the glc grid (without elevation classes) to the + ! land grid (with elevation classes) + ! Note that bare land values are mapped in the same way as ice-covered values + + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_topo, topo_g, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata2d(ice_sheet_tolnd(ns)%field_topo_x_icemask_g_ec, topo_x_icemask_g_ec, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do ec = 1,ungriddedCount + do l = 1,size(topo_g) + topo_x_icemask_g_ec(ec,l) = topo_g(l) * frac_x_icemask_g_ec(ec,l) + end do + end do + + ! map field_topo_x_icemask_g_ec from glc to land (with multiple elevation classes) - no normalization + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": calling mapping of topo from glc to land", ESMF_LOGMSG_INFO) + end if + call med_map_field( & + field_src=ice_sheet_tolnd(ns)%field_topo_x_icemask_g_ec, & + field_dst=field_topo_x_icemask_l_ec, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & + maptype=mapconsd, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata2d(field_topo_x_icemask_l_ec, topo_l_ec, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! map FBglc_frac_x_icemask from glc to land (with multiple elevation classes) - no normalization + if (dbug_flag > 1) then + call ESMF_LogWrite(trim(subname)//": calling mapping of frac_x_icemask from glc to land", ESMF_LOGMSG_INFO) + end if + call med_map_field( & + field_src=ice_sheet_tolnd(ns)%field_frac_x_icemask_g_ec, & + field_dst=field_frac_x_icemask_l_ec, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & + maptype=mapconsd, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata2d(field_frac_x_icemask_l_ec, frac_x_icemask_l_ec, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! set Sg_topo values in export state to land (in multiple elevation classes) + ! also set the topo field for virtual columns, in a given elevation class. + ! This is needed because virtual columns (i.e., elevation classes that have no + ! contributing glc grid cells) won't have any topographic information mapped onto + ! them, so would otherwise end up with an elevation of 0. + do ec = 1,ungriddedCount + topo_virtual = glc_mean_elevation_virtual(ec-1) ! glc_mean_elevation_virtual uses 0:glc_nec + do l = 1,size(frac_x_icemask_l_ec, dim=2) + if (frac_l_ec_sum(ec,l) <= 0._r8) then + topo_l_ec_sum(ec,l) = topo_l_ec_sum(ec,l) + topo_virtual + else + if (frac_x_icemask_l_ec(ec,l) /= 0.0_r8) then + topo_l_ec_sum(ec,l) = topo_l_ec_sum(ec,l) + topo_l_ec(ec,l) / frac_x_icemask_l_ec(ec,l) + end if + end if + end do + end do + end if + end do + + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + end if + call t_stopf('MED:'//subname) + + end subroutine map_glc2lnd + +end module med_phases_post_glc_mod diff --git a/mediator/med_phases_post_ice_mod.F90 b/mediator/med_phases_post_ice_mod.F90 new file mode 100644 index 000000000..b7bfbb679 --- /dev/null +++ b/mediator/med_phases_post_ice_mod.F90 @@ -0,0 +1,104 @@ +module med_phases_post_ice_mod + + !----------------------------------------------------------------------------- + ! Mediator phases updating fractions and mapping ice->atm and ice->ocn + !----------------------------------------------------------------------------- + + implicit none + private + + public :: med_phases_post_ice + + character(*), parameter :: u_FILE_u = & + __FILE__ + +!----------------------------------------------------------------------------- +contains +!----------------------------------------------------------------------------- + + subroutine med_phases_post_ice(gcomp, rc) + + 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_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_GridComp + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose + use med_map_mod , only : med_map_field_packed + use med_fraction_mod , only : med_fraction_set + use med_internalstate_mod , only : InternalState, mastertask + use esmFlds , only : compice, compatm, compocn, compwav + use perf_mod , only : t_startf, t_stopf + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + character(len=*),parameter :: subname='(med_phases_post_ice)' + !------------------------------------------------------------------------------- + + call t_startf('MED:'//subname) + rc = ESMF_SUCCESS + + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + end if + + ! get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! update ice fraction + call med_fraction_set(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! map ice to atm - scaling by updated ice fraction + if (is_local%wrap%med_coupling_active(compice,compatm)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compice,compice), & + FBDst=is_local%wrap%FBImp(compice,compatm), & + FBFracSrc=is_local%wrap%FBFrac(compice), & + field_NormOne=is_local%wrap%field_normOne(compice,compatm,:), & + packed_data=is_local%wrap%packed_data(compice,compatm,:), & + routehandles=is_local%wrap%RH(compice,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + end if + ! map ice to ocn + if (is_local%wrap%med_coupling_active(compice,compocn)) then + call t_startf('MED:'//trim(subname)//' map_ice2ocn') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compice,compice), & + FBDst=is_local%wrap%FBImp(compice,compocn), & + FBFracSrc=is_local%wrap%FBFrac(compice), & + field_normOne=is_local%wrap%field_normOne(compice,compocn,:), & + packed_data=is_local%wrap%packed_data(compice,compocn,:), & + routehandles=is_local%wrap%RH(compice,compocn,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map_ice2ocn') + end if + ! map ice to wav + if (is_local%wrap%med_coupling_active(compice,compwav)) then + call t_startf('MED:'//trim(subname)//' map_ice2wav') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compice,compice), & + FBDst=is_local%wrap%FBImp(compice,compwav), & + FBFracSrc=is_local%wrap%FBFrac(compice), & + field_normOne=is_local%wrap%field_normOne(compice,compwav,:), & + packed_data=is_local%wrap%packed_data(compice,compwav,:), & + routehandles=is_local%wrap%RH(compice,compwav,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map_ice2wav') + end if + + call t_stopf('MED:'//subname) + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO) + end if + + end subroutine med_phases_post_ice + +end module med_phases_post_ice_mod diff --git a/mediator/med_phases_post_lnd_mod.F90 b/mediator/med_phases_post_lnd_mod.F90 new file mode 100644 index 000000000..1f168dfa2 --- /dev/null +++ b/mediator/med_phases_post_lnd_mod.F90 @@ -0,0 +1,152 @@ +module med_phases_post_lnd_mod + + implicit none + private + + public :: med_phases_post_lnd_init ! does not accumulate input to rof + public :: med_phases_post_lnd + + logical :: lnd2glc_coupling + + character(*), parameter :: u_FILE_u = & + __FILE__ + +!----------------------------------------------------------------------------- +contains +!----------------------------------------------------------------------------- + + subroutine med_phases_post_lnd(gcomp, rc) + + 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_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_GridComp + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose + use med_map_mod , only : med_map_field_packed + use med_internalstate_mod , only : InternalState, mastertask + use med_phases_prep_rof_mod , only : med_phases_prep_rof_accum + use med_phases_prep_glc_mod , only : med_phases_prep_glc_accum + use esmFlds , only : complnd, compatm, comprof, compglc, num_icesheets + use perf_mod , only : t_startf, t_stopf + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + integer :: ns + logical :: first_call = .true. + character(len=*),parameter :: subname='(med_phases_post_lnd)' + !------------------------------------------------------------------------------- + + call t_startf('MED:'//subname) + rc = ESMF_SUCCESS + + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + end if + + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! map lnd to atm + if (is_local%wrap%med_coupling_active(complnd,compatm)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(complnd,complnd), & + FBDst=is_local%wrap%FBImp(complnd,compatm), & + FBFracSrc=is_local%wrap%FBFrac(complnd), & + field_NormOne=is_local%wrap%field_normOne(complnd,compatm,:), & + packed_data=is_local%wrap%packed_data(complnd,compatm,:), & + routehandles=is_local%wrap%RH(complnd,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! accumulate lnd input for rof + if (is_local%wrap%med_coupling_active(complnd,comprof)) then + call med_phases_prep_rof_accum(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + ! first determine if there will be any lnd to glc coupling + if (first_call) then + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(complnd,compglc(ns))) then + lnd2glc_coupling = .true. + exit + end if + end do + first_call = .false. + end if + + ! accumulate lnd input for glc + if (lnd2glc_coupling) then + call med_phases_prep_glc_accum(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO) + end if + call t_stopf('MED:'//subname) + + end subroutine med_phases_post_lnd + + !=============================================================================== + subroutine med_phases_post_lnd_init(gcomp, rc) + + 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_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_GridComp + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose + use med_map_mod , only : med_map_field_packed + use med_internalstate_mod , only : InternalState, mastertask + use esmFlds , only : complnd, compatm + use perf_mod , only : t_startf, t_stopf + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + character(len=*),parameter :: subname='(med_phases_post_lnd)' + !------------------------------------------------------------------------------- + + call t_startf('MED:'//subname) + rc = ESMF_SUCCESS + + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + end if + + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! map lnd to atm + if (is_local%wrap%med_coupling_active(complnd,compatm)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(complnd,complnd), & + FBDst=is_local%wrap%FBImp(complnd,compatm), & + FBFracSrc=is_local%wrap%FBFrac(complnd), & + field_NormOne=is_local%wrap%field_normOne(complnd,compatm,:), & + packed_data=is_local%wrap%packed_data(complnd,compatm,:), & + routehandles=is_local%wrap%RH(complnd,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO) + end if + call t_stopf('MED:'//subname) + + end subroutine med_phases_post_lnd_init + +end module med_phases_post_lnd_mod diff --git a/mediator/med_phases_post_ocn_mod.F90 b/mediator/med_phases_post_ocn_mod.F90 new file mode 100644 index 000000000..8b8de5865 --- /dev/null +++ b/mediator/med_phases_post_ocn_mod.F90 @@ -0,0 +1,73 @@ +module med_phases_post_ocn_mod + + !----------------------------------------------------------------------------- + ! Mediator post ocn phase - maps ocn->ice + !----------------------------------------------------------------------------- + + implicit none + private + + public :: med_phases_post_ocn + + character(*), parameter :: u_FILE_u = & + __FILE__ + +!----------------------------------------------------------------------------- +contains +!----------------------------------------------------------------------------- + + subroutine med_phases_post_ocn(gcomp, rc) + + 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_GridComp + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_map_mod , only : med_map_field_packed + use med_internalstate_mod , only : InternalState, logunit, mastertask + use esmFlds , only : compice, compocn + use perf_mod , only : t_startf, t_stopf + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + character(len=*),parameter :: subname='(med_phases_prep_ice)' + !--------------------------------------- + + rc = ESMF_SUCCESS + + call t_startf('MED:'//subname) + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + end if + + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! map ocn->ice + if (is_local%wrap%med_coupling_active(compocn,compice)) then + call t_startf('MED:'//trim(subname)//' map_ocn2ice') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compocn,compocn), & + FBDst=is_local%wrap%FBImp(compocn,compice), & + FBFracSrc=is_local%wrap%FBFrac(compocn), & + field_normOne=is_local%wrap%field_normOne(compocn,compice,:), & + packed_data=is_local%wrap%packed_data(compocn,compice,:), & + routehandles=is_local%wrap%RH(compocn,compice,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map_ocn2ice') + end if + + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO) + end if + call t_stopf('MED:'//subname) + + end subroutine med_phases_post_ocn + +end module med_phases_post_ocn_mod diff --git a/mediator/med_phases_post_rof_mod.F90 b/mediator/med_phases_post_rof_mod.F90 new file mode 100644 index 000000000..93e73ac3e --- /dev/null +++ b/mediator/med_phases_post_rof_mod.F90 @@ -0,0 +1,96 @@ +module med_phases_post_rof_mod + + ! Post rof phase, if appropriate, map initial rof->lnd, rof->ocn, rof->ice + + implicit none + private + + public :: med_phases_post_rof + + character(*) , parameter :: u_FILE_u = & + __FILE__ + +!================================================================================================ +contains +!================================================================================================ + + subroutine med_phases_post_rof(gcomp, rc) + + 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_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR, ESMF_SUCCESS, ESMF_FAILURE + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use esmFlds , only : complnd, compocn, compice, compatm, comprof, ncomps, compname + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_internalstate_mod , only : InternalState, mastertask, logunit + use med_map_mod , only : med_map_field_packed + use perf_mod , only : t_startf, t_stopf + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + character(len=*), parameter :: subname='(med_phases_post_rof)' + !--------------------------------------- + + rc = ESMF_SUCCESS + + call t_startf('MED:'//subname) + if (dbug_flag > 20) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + end if + + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! map rof to lnd + if (is_local%wrap%med_coupling_active(comprof,complnd)) then + call t_startf('MED:'//trim(subname)//' map_rof2lnd') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(comprof,comprof), & + FBDst=is_local%wrap%FBImp(comprof,complnd), & + FBFracSrc=is_local%wrap%FBFrac(comprof), & + field_normOne=is_local%wrap%field_normOne(comprof,complnd,:), & + packed_data=is_local%wrap%packed_data(comprof,complnd,:), & + routehandles=is_local%wrap%RH(comprof,complnd,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map_rof2lnd') + end if + ! map rof to ocn + if (is_local%wrap%med_coupling_active(comprof,compocn)) then + call t_startf('MED:'//trim(subname)//' map_rof2ocn') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(comprof,comprof), & + FBDst=is_local%wrap%FBImp(comprof,compocn), & + FBFracSrc=is_local%wrap%FBFrac(comprof), & + field_normOne=is_local%wrap%field_normOne(comprof,compocn,:), & + packed_data=is_local%wrap%packed_data(comprof,compocn,:), & + routehandles=is_local%wrap%RH(comprof,compocn,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map_rof2ocn') + end if + ! map rof to ice + if (is_local%wrap%med_coupling_active(comprof,compice)) then + call t_startf('MED:'//trim(subname)//' map_rof2ice') + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(comprof,comprof), & + FBDst=is_local%wrap%FBImp(comprof,compice), & + FBFracSrc=is_local%wrap%FBFrac(comprof), & + field_normOne=is_local%wrap%field_normOne(comprof,compice,:), & + packed_data=is_local%wrap%packed_data(comprof,compice,:), & + routehandles=is_local%wrap%RH(comprof,compice,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' map_rof2ice') + end if + + if (dbug_flag > 20) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + end if + call t_stopf('MED:'//subname) + + end subroutine med_phases_post_rof + +end module med_phases_post_rof_mod diff --git a/mediator/med_phases_post_wav_mod.F90 b/mediator/med_phases_post_wav_mod.F90 new file mode 100644 index 000000000..9e38eb32a --- /dev/null +++ b/mediator/med_phases_post_wav_mod.F90 @@ -0,0 +1,79 @@ +module med_phases_post_wav_mod + + implicit none + private + + public :: med_phases_post_wav + + character(*), parameter :: u_FILE_u = & + __FILE__ + +!----------------------------------------------------------------------------- +contains +!----------------------------------------------------------------------------- + + subroutine med_phases_post_wav(gcomp, rc) + + 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_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_GridComp + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose + use med_map_mod , only : med_map_field_packed + use med_internalstate_mod , only : InternalState, mastertask + use esmFlds , only : compwav, compocn, compice + use perf_mod , only : t_startf, t_stopf + + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc + + ! local variables + type(InternalState) :: is_local + character(len=*),parameter :: subname='(med_phases_post_wav)' + !------------------------------------------------------------------------------- + + call t_startf('MED:'//subname) + rc = ESMF_SUCCESS + + if (dbug_flag > 5) then + call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) + end if + + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! map wav to ocn + if (is_local%wrap%med_coupling_active(compwav,compocn)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compwav,compwav), & + FBDst=is_local%wrap%FBImp(compwav,compocn), & + FBFracSrc=is_local%wrap%FBFrac(compwav), & + field_NormOne=is_local%wrap%field_normOne(compwav,compocn,:), & + packed_data=is_local%wrap%packed_data(compwav,compocn,:), & + routehandles=is_local%wrap%RH(compwav,compocn,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + ! map wav to ice + if (is_local%wrap%med_coupling_active(compwav,compice)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compwav,compwav), & + FBDst=is_local%wrap%FBImp(compwav,compice), & + FBFracSrc=is_local%wrap%FBFrac(compwav), & + field_NormOne=is_local%wrap%field_normOne(compwav,compice,:), & + packed_data=is_local%wrap%packed_data(compwav,compice,:), & + routehandles=is_local%wrap%RH(compwav,compice,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + call t_stopf('MED:'//subname) + if (dbug_flag > 20) then + call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO) + end if + + end subroutine med_phases_post_wav + +end module med_phases_post_wav_mod diff --git a/mediator/med_phases_prep_atm_mod.F90 b/mediator/med_phases_prep_atm_mod.F90 index bacb7af31..ce69921f3 100644 --- a/mediator/med_phases_prep_atm_mod.F90 +++ b/mediator/med_phases_prep_atm_mod.F90 @@ -23,7 +23,7 @@ module med_phases_prep_atm_mod implicit none private - public :: med_phases_prep_atm + public :: med_phases_prep_atm character(*), parameter :: u_FILE_u = & __FILE__ @@ -64,146 +64,130 @@ subroutine med_phases_prep_atm(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- - !--- Count the number of fields outside of scalar data, if zero, then return + ! --- map ocn and ice to atm !--------------------------------------- + if (is_local%wrap%med_coupling_active(compocn,compatm)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compocn,compocn), & + FBDst=is_local%wrap%FBImp(compocn,compatm), & + FBFracSrc=is_local%wrap%FBFrac(compocn), & + field_NormOne=is_local%wrap%field_normOne(compocn,compatm,:), & + packed_data=is_local%wrap%packed_data(compocn,compatm,:), & + routehandles=is_local%wrap%RH(compocn,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + if (is_local%wrap%med_coupling_active(compice,compatm)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImp(compice,compice), & + FBDst=is_local%wrap%FBImp(compice,compatm), & + FBFracSrc=is_local%wrap%FBFrac(compice), & + field_NormOne=is_local%wrap%field_normOne(compice,compatm,:), & + packed_data=is_local%wrap%packed_data(compice,compatm,:), & + routehandles=is_local%wrap%RH(compice,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if - ! Note - the scalar field has been removed from all mediator field bundles - so this is why we check if the - ! fieldCount is 0 and not 1 here + !--------------------------------------- + !--- map ocean albedos from ocn to atm grid if appropriate + !--------------------------------------- + if (trim(coupling_mode) == 'cesm') then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBMed_ocnalb_o, & + FBDst=is_local%wrap%FBMed_ocnalb_a, & + FBFracSrc=is_local%wrap%FBFrac(compocn), & + field_normOne=is_local%wrap%field_normOne(compocn,compatm,:), & + packed_data=is_local%wrap%packed_data_ocnalb_o2a(:), & + routehandles=is_local%wrap%RH(compocn,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldCount=ncnt, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (ncnt == 0) then - call ESMF_LogWrite(trim(subname)//": only scalar data is present in FBexp(compatm), returning", & - ESMF_LOGMSG_INFO) - else - - !--------------------------------------- - !--- map import field bundles from n1 grid to atm grid - FBimp(:,compatm) - !--------------------------------------- - do n1 = 1,ncomps - if (is_local%wrap%med_coupling_active(n1,compatm)) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(n1,n1), & - FBDst=is_local%wrap%FBImp(n1,compatm), & - FBFracSrc=is_local%wrap%FBFrac(n1), & - field_NormOne=is_local%wrap%field_normOne(n1,compatm,:), & - packed_data=is_local%wrap%packed_data(n1,compatm,:), & - routehandles=is_local%wrap%RH(n1,compatm,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end do + !--------------------------------------- + !--- map atm/ocn fluxes from ocn to atm grid if appropriate + !--------------------------------------- + if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then + ! Assumption here is that fluxes are computed on the ocean grid + call med_map_field_packed( & + FBSrc=is_local%wrap%FBMed_aoflux_o, & + FBDst=is_local%wrap%FBMed_aoflux_a, & + FBFracSrc=is_local%wrap%FBFrac(compocn), & + field_normOne=is_local%wrap%field_normOne(compocn,compatm,:), & + packed_data=is_local%wrap%packed_data_aoflux_o2a(:), & + routehandles=is_local%wrap%RH(compocn,compatm,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + endif - !--------------------------------------- - !--- map ocean albedos from ocn to atm grid if appropriate - !--------------------------------------- - if (trim(coupling_mode) == 'cesm') then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBMed_ocnalb_o, & - FBDst=is_local%wrap%FBMed_ocnalb_a, & - FBFracSrc=is_local%wrap%FBFrac(compocn), & - field_normOne=is_local%wrap%field_normOne(compocn,compatm,:), & - packed_data=is_local%wrap%packed_data_ocnalb_o2a(:), & - routehandles=is_local%wrap%RH(compocn,compatm,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - !--------------------------------------- - !--- map atm/ocn fluxes from ocn to atm grid if appropriate - !--------------------------------------- - if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then - ! Assumption here is that fluxes are computed on the ocean grid - call med_map_field_packed( & - FBSrc=is_local%wrap%FBMed_aoflux_o, & - FBDst=is_local%wrap%FBMed_aoflux_a, & - FBFracSrc=is_local%wrap%FBFrac(compocn), & - field_normOne=is_local%wrap%field_normOne(compocn,compatm,:), & - packed_data=is_local%wrap%packed_data_aoflux_o2a(:), & - routehandles=is_local%wrap%RH(compocn,compatm,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif - - !--------------------------------------- - !--- merge all fields to atm - !--------------------------------------- - if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then - call med_merge_auto(compatm, & - is_local%wrap%med_coupling_active(:,compatm), & - is_local%wrap%FBExp(compatm), & - is_local%wrap%FBFrac(compatm), & - is_local%wrap%FBImp(:,compatm), & - fldListTo(compatm), & - FBMed1=is_local%wrap%FBMed_ocnalb_a, & - FBMed2=is_local%wrap%FBMed_aoflux_a, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else if (trim(coupling_mode) == 'nems_frac' .or. trim(coupling_mode) == 'nems_orig') then - call med_merge_auto(compatm, & - is_local%wrap%med_coupling_active(:,compatm), & - is_local%wrap%FBExp(compatm), & - is_local%wrap%FBFrac(compatm), & - is_local%wrap%FBImp(:,compatm), & - fldListTo(compatm), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(compatm),string=trim(subname)//' FBexp(compatm) ', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - !--------------------------------------- - !--- custom calculations - !--------------------------------------- - - ! set fractions to send back to atm - if (FB_FldChk(is_local%wrap%FBExp(compatm), 'So_ofrac', rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='So_ofrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='ofrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(dataptr1) - dataptr1(n) = dataptr2(n) - end do - end if - if (FB_FldChk(is_local%wrap%FBExp(compatm), 'Si_ifrac', rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='Si_ifrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='ifrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(dataptr1) - dataptr1(n) = dataptr2(n) - end do - end if - if (FB_FldChk(is_local%wrap%FBExp(compatm), 'Sl_lfrac', rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='Sl_lfrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='lfrac', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(dataptr1) - dataptr1(n) = dataptr2(n) - end do - end if - - !--------------------------------------- - !--- update local scalar data - !--------------------------------------- - - !--------------------------------------- - !--- clean up - !--------------------------------------- + !--------------------------------------- + !--- merge all fields to atm + !--------------------------------------- + if (trim(coupling_mode) == 'cesm' .or. trim(coupling_mode) == 'hafs') then + call med_merge_auto(compatm, & + is_local%wrap%med_coupling_active(:,compatm), & + is_local%wrap%FBExp(compatm), & + is_local%wrap%FBFrac(compatm), & + is_local%wrap%FBImp(:,compatm), & + fldListTo(compatm), & + FBMed1=is_local%wrap%FBMed_ocnalb_a, & + FBMed2=is_local%wrap%FBMed_aoflux_a, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else if (trim(coupling_mode) == 'nems_frac' .or. trim(coupling_mode) == 'nems_orig') then + call med_merge_auto(compatm, & + is_local%wrap%med_coupling_active(:,compatm), & + is_local%wrap%FBExp(compatm), & + is_local%wrap%FBFrac(compatm), & + is_local%wrap%FBImp(:,compatm), & + fldListTo(compatm), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if - endif + if (dbug_flag > 1) then + call FB_diagnose(is_local%wrap%FBExp(compatm),string=trim(subname)//' FBexp(compatm) ', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + + !--------------------------------------- + !--- custom calculations + !--------------------------------------- + + ! set fractions to send back to atm + if (FB_FldChk(is_local%wrap%FBExp(compatm), 'So_ofrac', rc=rc)) then + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='So_ofrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='ofrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(dataptr1) + dataptr1(n) = dataptr2(n) + end do + end if + if (FB_FldChk(is_local%wrap%FBExp(compatm), 'Si_ifrac', rc=rc)) then + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='Si_ifrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='ifrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(dataptr1) + dataptr1(n) = dataptr2(n) + end do + end if + if (FB_FldChk(is_local%wrap%FBExp(compatm), 'Sl_lfrac', rc=rc)) then + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compatm), fieldName='Sl_lfrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr1, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compatm), fieldName='lfrac', field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayPtr=dataptr2, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(dataptr1) + dataptr1(n) = dataptr2(n) + end do + end if if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 3bdda2391..d53424cc0 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -45,11 +45,11 @@ module med_phases_prep_glc_mod implicit none private - public :: med_phases_prep_glc_init - public :: med_phases_prep_glc_accum - public :: med_phases_prep_glc_avg + public :: med_phases_prep_glc_accum ! called from med_phases_post_lnd + public :: med_phases_prep_glc - private :: map_lnd2glc + private :: med_phases_prep_glc_init + private :: med_phases_prep_glc_map_lnd2glc private :: med_phases_prep_glc_renormalize_smb ! glc fields with multiple elevation classes: lnd->glc @@ -67,7 +67,6 @@ module med_phases_prep_glc_mod integer :: FBlndAccumCnt character(len=14) :: fldnames_fr_lnd(3) = (/'Flgl_qice_elev','Sl_tsrf_elev ','Sl_topo_elev '/) character(len=14) :: fldnames_to_glc(2) = (/'Flgl_qice ','Sl_tsrf '/) - type, public :: ice_sheet_toglc_type character(CS) :: name @@ -106,7 +105,7 @@ module med_phases_prep_glc_mod subroutine med_phases_prep_glc_init(gcomp, rc) !--------------------------------------- - ! Create land accumulation field bundles on and and glc grid and initialize accumulation count + ! Create land accumulation field bundles on lnd and and glc mesh and initialize accumulation count !--------------------------------------- ! input/output variables @@ -491,7 +490,7 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) end subroutine med_phases_prep_glc_accum !================================================================================================ - subroutine med_phases_prep_glc_avg(gcomp, rc) + subroutine med_phases_prep_glc(gcomp, rc) !--------------------------------------- ! Prepare the GLC export Fields from the mediator @@ -596,7 +595,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) ! Map accumulated field bundle from land grid (with elevation classes) to glc grid (without elevation classes) ! and set FBExp(compglc(ns)) data - call map_lnd2glc(gcomp, rc) + call med_phases_prep_glc_map_lnd2glc(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return ! zero accumulator and accumulated field bundles on land grid @@ -622,11 +621,10 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) endif call t_stopf('MED:'//subname) - end subroutine med_phases_prep_glc_avg + end subroutine med_phases_prep_glc !================================================================================================ - - subroutine map_lnd2glc(gcomp, rc) + subroutine med_phases_prep_glc_map_lnd2glc(gcomp, rc) !--------------------------------------- ! map accumulated land fields from the land to the glc mesh @@ -658,7 +656,7 @@ subroutine map_lnd2glc(gcomp, rc) character(len=3) :: cnum type(ESMF_Field), pointer :: fieldlist_lnd(:) => null() type(ESMF_Field), pointer :: fieldlist_glc(:) => null() - character(len=*) , parameter :: subname=' (map_lnd2glc) ' + character(len=*) , parameter :: subname=' (med_phases_prep_glc_map_lnd2glc) ' !--------------------------------------- !--------------------------------------- @@ -862,10 +860,9 @@ subroutine map_lnd2glc(gcomp, rc) end do ! end of loop over ice sheets - end subroutine map_lnd2glc + end subroutine med_phases_prep_glc_map_lnd2glc !================================================================================================ - subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) !------------------ diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index a65680681..f987488f3 100644 --- a/mediator/med_phases_prep_ice_mod.F90 +++ b/mediator/med_phases_prep_ice_mod.F90 @@ -4,28 +4,16 @@ module med_phases_prep_ice_mod ! Mediator phases for preparing ice export from mediator !----------------------------------------------------------------------------- - use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_methods_mod , only : fldchk => med_methods_FB_FldChk - use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar - use med_methods_mod , only : State_SetScalar => med_methods_State_SetScalar - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag - use med_merge_mod , only : med_merge_auto - use med_map_mod , only : med_map_field_packed - use med_internalstate_mod , only : InternalState, logunit, mastertask - use esmFlds , only : compatm, compice, comprof, compglc, ncomps, compname - use esmFlds , only : fldListFr, fldListTo - use esmFlds , only : mapnames - use esmFlds , only : coupling_mode - use esmFlds , only : med_fldList_GetFldInfo - use perf_mod , only : t_startf, t_stopf + use med_kind_mod, only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 implicit none private public :: med_phases_prep_ice + real(r8), pointer :: dataptr_scalar_ice(:,:) => null() + real(r8), pointer :: dataptr_scalar_atm(:,:) => null() + character(*), parameter :: u_FILE_u = & __FILE__ @@ -35,13 +23,23 @@ module med_phases_prep_ice_mod subroutine med_phases_prep_ice(gcomp, rc) - use ESMF , only : operator(/=) - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_StateGet - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - 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 NUOPC , only : NUOPC_IsConnected + use ESMF , only : operator(/=) + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_StateGet + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + 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 med_utils_mod , only : chkerr => med_utils_ChkErr + use med_methods_mod , only : fldchk => med_methods_FB_FldChk + use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_merge_mod , only : med_merge_auto + use med_internalstate_mod , only : InternalState, logunit, mastertask + use esmFlds , only : compatm, compice, compocn, comprof, compglc, ncomps, compname + use esmFlds , only : fldListTo + use esmFlds , only : coupling_mode + use perf_mod , only : t_startf, t_stopf ! input/output variables type(ESMF_GridComp) :: gcomp @@ -51,15 +49,15 @@ subroutine med_phases_prep_ice(gcomp, rc) type(ESMF_StateItem_Flag) :: itemType type(InternalState) :: is_local type(ESMF_Field) :: lfield - integer :: i,n,n1,ncnt - character(len=CS) :: fldname - integer :: fldnum - integer :: mapindex - real(R8), pointer :: dataptr(:) => null() + integer :: i,n + real(R8), pointer :: dataptr1d(:) => null() real(R8) :: precip_fact character(len=CS) :: cvalue character(len=64), allocatable :: fldnames(:) real(r8) :: nextsw_cday + integer :: scalar_id + real(r8) :: tmp(1) + logical :: first_call = .true. logical :: first_precip_fact_call = .true. character(len=*),parameter :: subname='(med_phases_prep_ice)' !--------------------------------------- @@ -71,124 +69,93 @@ subroutine med_phases_prep_ice(gcomp, rc) endif rc = ESMF_SUCCESS - !--------------------------------------- - ! --- 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 - !--------------------------------------- - !--- Count the number of fields outside of scalar data, if zero, then return - !--------------------------------------- - - ! Note - the scalar field has been removed from all mediator field bundles - so this is why we check if the - ! fieldCount is 0 and not 1 here - - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compice), fieldCount=ncnt, rc=rc) + ! atm->ice is mapped in med_phases_post_atm + ! glc->ice is mapped in med_phases_post_glc + ! rof->ice is mapped in med_phases_post_rof + ! ocn->ice is mapped in med_phases_post_ocn + + ! auto merges to create FBExp(compice) + call med_merge_auto(compice, & + is_local%wrap%med_coupling_active(:,compice), & + is_local%wrap%FBExp(compice), & + is_local%wrap%FBFrac(compice), & + is_local%wrap%FBImp(:,compice), & + fldListTo(compice), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ncnt > 0) then - - ! map all fields in FBImp that have active ice coupling - do n1 = 1,ncomps - if (is_local%wrap%med_coupling_active(n1,compice)) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(n1,n1), & - FBDst=is_local%wrap%FBImp(n1,compice), & - FBFracSrc=is_local%wrap%FBFrac(n1), & - field_normOne=is_local%wrap%field_normOne(n1,compice,:), & - packed_data=is_local%wrap%packed_data(n1,compice,:), & - routehandles=is_local%wrap%RH(n1,compice,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! apply precipitation factor from ocean + ! TODO (mvertens, 2019-03-18): precip_fact here is not valid if + ! the component does not send it - hardwire it to 1 until this is resolved + if (trim(coupling_mode) == 'cesm') then + precip_fact = 1.0_R8 + if (precip_fact /= 1.0_R8) then + if (first_precip_fact_call .and. mastertask) then + write(logunit,'(a)')'(merge_to_ice): Scaling rain, snow, liquid and ice runoff by precip_fact ' + first_precip_fact_call = .false. end if - end do - - !--------------------------------------- - !--- auto merges to create FBExp(compice) - !--------------------------------------- - - call med_merge_auto(compice, & - is_local%wrap%med_coupling_active(:,compice), & - is_local%wrap%FBExp(compice), & - is_local%wrap%FBFrac(compice), & - is_local%wrap%FBImp(:,compice), & - fldListTo(compice), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------- - !--- custom calculations - !--------------------------------------- - - if (trim(coupling_mode) == 'cesm') then - - ! application of precipitation factor from ocean - ! TODO (mvertens, 2019-03-18): precip_fact here is not valid if - ! the component does not send it - hardwire it to 1 until this is resolved - precip_fact = 1.0_R8 - if (precip_fact /= 1.0_R8) then - if (first_precip_fact_call .and. mastertask) then - write(logunit,'(a)')'(merge_to_ice): Scaling rain, snow, liquid and ice runoff by precip_fact ' - first_precip_fact_call = .false. + write(cvalue,*) precip_fact + call ESMF_LogWrite(trim(subname)//" precip_fact is "//trim(cvalue), ESMF_LOGMSG_INFO) + + allocate(fldnames(3)) + fldnames = (/'Faxa_rain', 'Faxa_snow', 'Fixx_rofi'/) + do n = 1,size(fldnames) + if (fldchk(is_local%wrap%FBExp(compice), trim(fldnames(n)), rc=rc)) then + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compice), fieldname=trim(fldnames(n)), & + field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = dataptr1d(:) * precip_fact end if - write(cvalue,*) precip_fact - call ESMF_LogWrite(trim(subname)//" precip_fact is "//trim(cvalue), ESMF_LOGMSG_INFO) - - allocate(fldnames(3)) - fldnames = (/'Faxa_rain', 'Faxa_snow', 'Fixx_rofi'/) - do n = 1,size(fldnames) - if (fldchk(is_local%wrap%FBExp(compice), trim(fldnames(n)), rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compice), fieldname=trim(fldnames(n)), & - field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=dataptr, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr(:) = dataptr(:) * precip_fact - end if - end do - deallocate(fldnames) - end if + end do + deallocate(fldnames) end if + end if - if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(compice), string=trim(subname)//' FBexp(compice) ', rc=rc) + ! obtain nextsw_cday from atm if it is in the import state and send it to ice + call ESMF_StateGet(is_local%wrap%NStateImp(compatm), & + trim(is_local%wrap%flds_scalar_name), itemtype, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (itemType /= ESMF_STATEITEM_NOTFOUND) then + call t_startf('MED:'//trim(subname)//' nextsw_cday') + if (first_call) then + ! determine module pointer data for performance reasons + call ESMF_StateGet(is_local%wrap%NstateImp(compatm), & + 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_atm, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(is_local%wrap%NStateExp(compice), & + 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_ice, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - - !--------------------------------------- - !--- update scalar data - !--------------------------------------- - - call ESMF_StateGet(is_local%wrap%NStateImp(compatm), trim(is_local%wrap%flds_scalar_name), itemType, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (itemType /= ESMF_STATEITEM_NOTFOUND) then - if (is_local%wrap%flds_scalar_index_nextsw_cday .ne. 0) then - ! send nextsw_cday to ice - first obtain it from atm import - call State_GetScalar(& - scalar_value=nextsw_cday, & - scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday, & - state=is_local%wrap%NstateImp(compatm), & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - flds_scalar_num=is_local%wrap%flds_scalar_num, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call State_SetScalar(& - scalar_value=nextsw_cday, & - scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday, & - state=is_local%wrap%NstateExp(compice), & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - flds_scalar_num=is_local%wrap%flds_scalar_num, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + ! obtain nextsw_cday from atm import on all tasks + scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday + if (mastertask) then + tmp(1) = dataptr_scalar_atm(scalar_id,1) end if + call ESMF_VMBroadCast(is_local%wrap%vm, tmp, 1, 0, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + ! set nextsw_cday on all ice export tasks + dataptr_scalar_ice(scalar_id,1) = tmp(1) + call t_stopf('MED:'//trim(subname)//' nextsw_cday') + end if - !--------------------------------------- - !--- clean up - !--------------------------------------- - + if (dbug_flag > 1) then + call FB_diagnose(is_local%wrap%FBExp(compice), string=trim(subname)//' FBexp(compice) ', rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return end if + ! Set first call logical to false + first_call = .false. + if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif diff --git a/mediator/med_phases_prep_lnd_mod.F90 b/mediator/med_phases_prep_lnd_mod.F90 index 88a6fecc8..fd2a32c95 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -4,77 +4,15 @@ module med_phases_prep_lnd_mod ! Mediator phases for preparing land export from mediator !----------------------------------------------------------------------------- - use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - use NUOPC , only : NUOPC_CompAttributeGet - use ESMF , only : operator(/=) - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR, ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet - use ESMF , only : ESMF_StateGet, ESMF_StateItem_Flag, ESMF_STATEITEM_NOTFOUND - use ESMF , only : ESMF_Mesh, ESMF_MeshLoc, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 - use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate - use ESMF , only : ESMF_RouteHandle, ESMF_RouteHandleIsCreated - use esmFlds , only : complnd, compatm, comprof, ncomps, compname - use esmFlds , only : max_icesheets, num_icesheets, compglc - use esmFlds , only : mapbilnr, mapconsd, mapconsf, compname - use esmFlds , only : fldListTo - use med_methods_mod , only : fldbun_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : fldbun_fldchk => med_methods_FB_fldchk - use med_methods_mod , only : fldbun_getmesh => med_methods_FB_getmesh - use med_methods_mod , only : fldbun_getdata1d => med_methods_FB_getdata1d - use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d - use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d - use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d - use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar - use med_methods_mod , only : State_SetScalar => med_methods_State_SetScalar - use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag - use med_internalstate_mod , only : InternalState, mastertask, logunit - use med_map_mod , only : med_map_rh_is_created, med_map_routehandles_init - use med_map_mod , only : med_map_field_packed, med_map_field_normalized, med_map_field - use med_merge_mod , only : med_merge_auto - use glc_elevclass_mod , only : glc_get_num_elevation_classes - use glc_elevclass_mod , only : glc_mean_elevation_virtual - use glc_elevclass_mod , only : glc_get_fractional_icecov - use perf_mod , only : t_startf, t_stopf + use med_kind_mod, only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 implicit none private public :: med_phases_prep_lnd - private :: map_glc2lnd_init - private :: map_glc2lnd - - ! private module variables - character(len =*), parameter :: Sg_icemask = 'Sg_icemask' - character(len =*), parameter :: Sg_icemask_coupled_fluxes = 'Sg_icemask_coupled_fluxes' - character(len =*), parameter :: Sg_frac = 'Sg_ice_covered' - character(len =*), parameter :: Sg_frac_x_icemask = 'Sg_frac_times_icemask' - character(len =*), parameter :: Sg_topo = 'Sg_topo' - character(len =*), parameter :: Flgg_hflx = 'Flgg_hflx' - - type, public :: ice_sheet_tolnd_type - character(CS) :: name - logical :: is_active - type(ESMF_Field) :: field_icemask_g ! no elevation classes - type(ESMF_Field) :: field_frac_g_ec ! elevation classes - type(ESMF_Field) :: field_frac_x_icemask_g_ec ! elevation classes - type(ESMF_Field) :: field_topo_x_icemask_g_ec ! elevation classes - type(ESMF_Mesh) :: mesh_g - end type ice_sheet_tolnd_type - type(ice_sheet_tolnd_type) :: ice_sheet_tolnd(max_icesheets) - - type(ESMF_field) :: field_icemask_l ! no elevation classes - type(ESMF_Field) :: field_frac_l_ec ! elevation classes - type(ESMF_Field) :: field_frac_x_icemask_l_ec ! elevation classes - type(ESMF_Field) :: field_topo_x_icemask_l_ec ! elevation classes - - ! the number of elevation classes (excluding bare land) = ungriddedCount - 1 - integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) - - logical :: glc2lnd_coupling = .false. - logical :: cism_evolve = .false. + real(r8), pointer :: dataptr_scalar_lnd(:,:) => null() + real(r8), pointer :: dataptr_scalar_atm(:,:) => null() character(*) , parameter :: u_FILE_u = & __FILE__ @@ -85,18 +23,36 @@ module med_phases_prep_lnd_mod subroutine med_phases_prep_lnd(gcomp, rc) + use NUOPC , only : NUOPC_CompAttributeGet + use ESMF , only : operator(/=) + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR, ESMF_SUCCESS, ESMF_FAILURE + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field, ESMF_FieldGet + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_StateGet, ESMF_StateItem_Flag, ESMF_STATEITEM_NOTFOUND + use ESMF , only : ESMF_VMBroadCast + use esmFlds , only : complnd, compatm, ncomps + use esmFlds , only : fldListTo + use med_methods_mod , only : fldbun_diagnose => med_methods_FB_diagnose + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_internalstate_mod , only : InternalState, mastertask, logunit + use med_merge_mod , only : med_merge_auto + use perf_mod , only : t_startf, t_stopf + ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc ! local variables - type(ESMF_StateItem_Flag) :: itemType - type(InternalState) :: is_local - integer :: n1,ncnt,ns - real(r8) :: nextsw_cday - logical :: first_call = .true. - logical :: isPresent - character(CL) :: cvalue + type(ESMF_StateItem_Flag) :: itemType + type(InternalState) :: is_local + type(ESMF_Field) :: lfield + integer :: ncnt,ns + real(r8) :: nextsw_cday + integer :: scalar_id + real(r8) :: tmp(1) + real(r8), pointer :: dataptr2d(:,:) => null() + logical :: first_call = .true. character(len=*), parameter :: subname='(med_phases_prep_lnd)' !--------------------------------------- @@ -121,68 +77,12 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ncnt > 0) then - ! determine if coupling to CISM is 2-way - if (first_call) then - call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (isPresent) then - call NUOPC_CompAttributeGet(gcomp, name="cism_evolve", value=cvalue, isPresent=isPresent, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - read (cvalue,*) cism_evolve - if (mastertask) then - write(logunit,'(a,l7)') trim(subname)//' cism_evolve = ',cism_evolve - end if - end if - end if - - !--------------------------------------- - ! map to create FBimp(:,complnd) - other than glc->lnd - !--------------------------------------- - - call t_startf('MED:'//trim(subname)//' map') - do n1 = 1,ncomps - ! Skip glc here and handle it below - only components that are allowed to couple to - ! land are atm, rof and glc - if (is_local%wrap%med_coupling_active(n1,complnd)) then - if (n1 == comprof .or. n1 == compatm) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(n1,n1), & - FBDst=is_local%wrap%FBImp(n1,complnd), & - FBFracSrc=is_local%wrap%FBFrac(n1), & - field_normOne=is_local%wrap%field_normOne(n1,complnd,:), & - packed_data=is_local%wrap%packed_data(n1,complnd,:), & - routehandles=is_local%wrap%RH(n1,complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end if - end do - call t_stopf('MED:'//trim(subname)//' map') - - ! The following is only done if glc->lnd coupling is active - ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) - call t_startf('MED:'//trim(subname)//' glc2lnd ') - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(compglc(ns),compglc(ns)), & - FBDst=is_local%wrap%FBImp(compglc(ns),complnd), & - FBFracSrc=is_local%wrap%FBFrac(compglc(ns)), & - field_normOne=is_local%wrap%field_normOne(compglc(ns),complnd,:), & - packed_data=is_local%wrap%packed_data(compglc(ns),complnd,:), & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end do - call t_stopf('MED:'//trim(subname)//' glc2lnd') + ! atm2lnd is done in med_phases_post_atm + ! rof2lnd is done in med_phases_post_rof + ! glc2lnd is done in med_phases_post_glc - !--------------------------------------- ! auto merges to create FBExp(complnd) - other than glc->lnd - !--------------------------------------- - ! The following will merge all fields in fldsSrc - ! Note that there is no merge for glc Sg_icemask and Sg_icemask_coupled_fluxes) - ! these are mapped and set directly in map_glc2lnd - call t_startf('MED:'//trim(subname)//' merge') call med_merge_auto(complnd, & is_local%wrap%med_coupling_active(:,complnd), & @@ -193,54 +93,34 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return call t_stopf('MED:'//trim(subname)//' merge') - !--------------------------------------- - ! glc-lnd custom mapping and merging - !--------------------------------------- - - ! determine if there will be any glc to lnd coupling - if (first_call) then - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - glc2lnd_coupling = .true. - exit - end if - end do - end if - - ! The following is only done if glc->lnd coupling is active - if (glc2lnd_coupling) then - if (first_call) then - call map_glc2lnd_init(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - ! The will following will map and merge Sg_frac and Sg_topo (and in the future Flgg_hflx) - call map_glc2lnd(gcomp, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - !--------------------------------------- - ! update scalar data - !--------------------------------------- - - call ESMF_StateGet(is_local%wrap%NStateImp(compatm), trim(is_local%wrap%flds_scalar_name), itemType, rc=rc) + ! obtain nextsw_cday from atm if it is in the import state and send it to lnd + call ESMF_StateGet(is_local%wrap%NStateImp(compatm), & + trim(is_local%wrap%flds_scalar_name), itemtype, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (itemType /= ESMF_STATEITEM_NOTFOUND) then call t_startf('MED:'//trim(subname)//' nextsw_cday') - ! send nextsw_cday to land - first obtain it from atm import - call State_GetScalar(& - scalar_value=nextsw_cday, & - scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday, & - state=is_local%wrap%NstateImp(compatm), & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - flds_scalar_num=is_local%wrap%flds_scalar_num, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call State_SetScalar(& - scalar_value=nextsw_cday, & - scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday, & - state=is_local%wrap%NstateExp(complnd), & - flds_scalar_name=is_local%wrap%flds_scalar_name, & - flds_scalar_num=is_local%wrap%flds_scalar_num, rc=rc) + if (first_call) then + ! Determine module pointer data for performance reasons + call ESMF_StateGet(is_local%wrap%NstateImp(compatm), & + 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_atm, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_StateGet(is_local%wrap%NStateExp(complnd), & + 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_lnd, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if + ! obtain nextsw_cday from atm import on all tasks + scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday + if (mastertask) then + tmp(1) = dataptr_scalar_atm(scalar_id,1) + end if + call ESMF_VMBroadCast(is_local%wrap%vm, tmp, 1, 0, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ! set nextsw_cday on all lnd export tasks + dataptr_scalar_lnd(scalar_id,1) = tmp(1) call t_stopf('MED:'//trim(subname)//' nextsw_cday') end if @@ -252,7 +132,7 @@ subroutine med_phases_prep_lnd(gcomp, rc) end if end if - ! Reset first call logical + ! Set first call logical to false first_call = .false. if (dbug_flag > 5) then @@ -262,350 +142,4 @@ subroutine med_phases_prep_lnd(gcomp, rc) end subroutine med_phases_prep_lnd - !================================================================================================ - - subroutine map_glc2lnd_init(gcomp, rc) - - ! input/output variables - type(ESMF_GridComp) , intent(inout) :: gcomp - integer , intent(out) :: rc - - ! local variables - type(InternalState) :: is_local - type(ESMF_Field) :: lfield_l - type(ESMF_Mesh) :: mesh_l - integer :: ungriddedUBound_output(1) - integer :: fieldCount - integer :: ns,n - type(ESMF_Field), pointer :: fieldlist(:) => null() - character(len=*) , parameter :: subname='(map_glc2lnd_mod:map_glc2lnd_init)' - !--------------------------------------- - - rc = ESMF_SUCCESS - - !--------------------------------------- - ! Get the internal state - !--------------------------------------- - - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------- - ! Set the module variable for the number of elevation classes - !--------------------------------------- - - ! Determine number of elevation classes by querying a field that has elevation classes in it - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), 'Sg_topo_elev', field=lfield_l, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield_l, ungriddedUBound=ungriddedUBound_output, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - ungriddedCount = ungriddedUBound_output(1) - ! TODO: check that ungriddedCount = glc_nec+1 - - ! ------------------------------- - ! Create module fields on land mesh - ! ------------------------------- - - call fldbun_getmesh(is_local%wrap%FBExp(complnd), mesh_l, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - field_icemask_l = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - field_frac_l_ec = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - field_frac_x_icemask_l_ec = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - field_topo_x_icemask_l_ec = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------------- - ! create module fields on glc mesh - !--------------------------------------- - - do ns = 1,max_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - - call fldbun_getmesh(is_local%wrap%FBImp(compglc(ns),compglc(ns)), ice_sheet_tolnd(ns)%mesh_g, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ice_sheet_tolnd(ns)%field_icemask_g = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & - ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ice_sheet_tolnd(ns)%field_frac_g_ec = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & - ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ice_sheet_tolnd(ns)%field_frac_x_icemask_g_ec = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & - ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ice_sheet_tolnd(ns)%field_topo_x_icemask_g_ec = ESMF_FieldCreate(ice_sheet_tolnd(ns)%mesh_g, & - ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Create route handle if it has not been created - if (.not. ESMF_RouteHandleIsCreated(is_local%wrap%RH(compglc(ns),complnd,mapconsd), rc=rc)) then - call med_map_routehandles_init( compglc(ns), complnd, & - ice_sheet_tolnd(ns)%field_icemask_g, field_icemask_l, & - mapindex=mapconsd, & - routehandles=is_local%wrap%rh(compglc(ns),complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end if - end do - - ! Currently cannot map hflx in multiple elevation classes from glc to land - if (fldbun_fldchk(is_local%wrap%FBExp(complnd), trim(Flgg_hflx), rc=rc)) then - call ESMF_LogWrite(trim(subname)//'ERROR: Flgg_hflx to land has not been implemented yet', & - ESMF_LOGMSG_ERROR, line=__LINE__, file=__FILE__) - rc = ESMF_FAILURE - return - end if - - end subroutine map_glc2lnd_init - - !================================================================================================ - subroutine map_glc2lnd( gcomp, rc) - - !------------------ - ! Maps fields from the GLC grid to the LND grid. - ! On the GLC grid the fields will not have elevation classes. - ! On the LND grid they will have elevation classes. - !------------------ - - ! input/output variables - type(ESMF_GridComp) , intent(inout) :: gcomp - integer , intent(out) :: rc - - ! local variables - type(InternalState) :: is_local - type(ESMF_Field) :: lfield - type(ESMF_Field) :: lfield_src - type(ESMF_Field) :: lfield_dst - integer :: ec, l, g, ns, n - real(r8) :: topo_virtual - real(r8), pointer :: icemask_g(:) => null() ! glc ice mask field on glc grid - real(r8), pointer :: frac_g(:) => null() ! total ice fraction in each glc cell - real(r8), pointer :: frac_g_ec(:,:) => null() ! glc fractions on the glc grid - real(r8), pointer :: frac_l_ec(:,:) => null() ! glc fractions on the land grid - real(r8), pointer :: topo_g(:) => null() ! topo height of each glc cell (no elev classes) - real(r8), pointer :: topo_l_ec(:,:) => null() ! topo height in each land gridcell for each elev class - real(r8), pointer :: frac_x_icemask_g_ec(:,:) => null() ! (glc fraction) x (icemask), on the glc grid - real(r8), pointer :: frac_x_icemask_l_ec(:,:) => null() - real(r8), pointer :: topo_x_icemask_g_ec(:,:) => null() - real(r8), pointer :: topo_x_icemask_l_ec(:,:) => null() - real(r8), pointer :: dataptr1d(:) => null() - real(r8), pointer :: dataptr2d(:,:) => null() - real(r8), pointer :: frac_l_ec_sum(:,:) => null() - real(r8), pointer :: topo_l_ec_sum(:,:) => null() - real(r8), pointer :: dataptr1d_src(:) => null() - real(r8), pointer :: dataptr1d_dst(:) => null() - character(len=*), parameter :: subname = 'map_glc2lnd' - !----------------------------------------------------------------------- - - call t_startf('MED:'//subname) - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - end if - rc = ESMF_SUCCESS - - !--------------------------------------- - ! Get the internal state - !--------------------------------------- - - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - !--------------------------------- - ! Get pointers into land export field bundle (this is summed over all ice sheets) - !--------------------------------- - - call fldbun_getdata2d(is_local%wrap%FBExp(complnd), trim(Sg_frac)//'_elev', frac_l_ec_sum, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - frac_l_ec_sum(:,:) = 0._r8 - - call fldbun_getdata2d(is_local%wrap%FBExp(complnd), trim(Sg_topo)//'_elev', topo_l_ec_sum, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - topo_l_ec_sum(:,:) = 0._r8 - - !--------------------------------- - ! Map fractional ice coverage to the land grid (multiple elevation classes) - !--------------------------------- - - ! Map Sg_icemask and Sg_icemask_coupled_fluxes (no elevation classes) - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - call t_startf('MED:'//trim(subname)//' glc2lnd ') - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(compglc(ns),compglc(ns)), & - FBDst=is_local%wrap%FBImp(compglc(ns),complnd), & - FBFracSrc=is_local%wrap%FBFrac(compglc(ns)), & - field_normOne=is_local%wrap%field_normOne(compglc(ns),complnd,:), & - packed_data=is_local%wrap%packed_data(compglc(ns),complnd,:), & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call t_stopf('MED:'//trim(subname)//' glc2lnd') - end if - end do - - ! Get Sg_icemask on land as sum of all ice sheets (no elevation classes) - call fldbun_getdata1d(is_local%wrap%FBExp(complnd), Sg_icemask, dataptr1d_dst, rc) - dataptr1d_dst(:) = 0._r8 - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),complnd), Sg_icemask, dataptr1d_src, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d_dst(:) = dataptr1d_dst(:) + dataptr1d_src(:) - end if - end do - - ! Get Sg_icemask_coupled_fluxes on land as sum of all ice sheets (no elevation classes) - call fldbun_getdata1d(is_local%wrap%FBExp(complnd), Sg_icemask_coupled_fluxes, dataptr1d_dst, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d_dst(:) = 0._r8 - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),complnd), Sg_icemask_coupled_fluxes, dataptr1d_src, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr1d_dst(:) = dataptr1d_dst(:) + dataptr1d_src(:) - end if - end do - - do ns = 1,num_icesheets - if (is_local%wrap%med_coupling_active(compglc(ns),complnd)) then - - ! Set (fractional ice coverage for each elevation class on the glc grid) - - ! get topo_g(:) - the topographic height of each glc gridcell - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_topo, topo_g, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! get frac_g(:) - the total ice fraction in each glc gridcell - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_frac, frac_g, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! compute frac_g_ec(:,:) - the glc fractions on the glc grid for each elevation class (inner dimension) - call field_getdata2d(ice_sheet_tolnd(ns)%field_frac_g_ec, frac_g_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call glc_get_fractional_icecov(ungriddedCount-1, topo_g, frac_g, frac_g_ec, logunit) - - ! compute icemask_g - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_icemask, dataptr1d, rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call field_getdata1d(ice_sheet_tolnd(ns)%field_icemask_g, icemask_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - icemask_g(:) = dataptr1d(:) - - ! compute frac_x_icemask_g_ec - ! only include grid cells that are both (a) within the icemask and (b) in this elevation class - call field_getdata2d(ice_sheet_tolnd(ns)%field_frac_x_icemask_g_ec, frac_x_icemask_g_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do ec = 1, ungriddedCount - frac_x_icemask_g_ec(ec,:) = frac_g_ec(ec,:) * icemask_g(:) - end do - - ! map frac_g_ec to frac_l_ec and normalize by icemask_g - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": calling mapping elevation class fractions from glc to land", & - ESMF_LOGMSG_INFO) - end if - call med_map_field_normalized( & - field_src=ice_sheet_tolnd(ns)%field_frac_g_ec, & - field_dst=field_frac_l_ec, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsd, & - field_normsrc=ice_sheet_tolnd(ns)%field_icemask_g, & - field_normdst=field_icemask_l, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! now set values in land export state for Sg_frac_elev (this is summed over all ice sheets) - call field_getdata2d(field_frac_l_ec, frac_l_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - frac_l_ec_sum(:,:) = frac_l_ec_sum(:,:) + frac_l_ec(:,:) - - !--------------------------------- - ! Map topo to the land grid (multiple elevation classes) - !--------------------------------- - - ! Note that all topo values in FBimp(compglc(ns),compglc(ns)) do not have elevation class dependence - ! Normalize by frac_x_icemask_g_ec - this is what introduces - ! elevation class information from the glc grid (without elevation classes) to the - ! land grid (with elevation classes) - ! Note that bare land values are mapped in the same way as ice-covered values - - call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_topo, topo_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call field_getdata2d(ice_sheet_tolnd(ns)%field_topo_x_icemask_g_ec, topo_x_icemask_g_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do ec = 1,ungriddedCount - do l = 1,size(topo_g) - topo_x_icemask_g_ec(ec,l) = topo_g(l) * frac_x_icemask_g_ec(ec,l) - end do - end do - - ! map field_topo_x_icemask_g_ec from glc to land (with multiple elevation classes) - no normalization - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": calling mapping of topo from glc to land", ESMF_LOGMSG_INFO) - end if - call med_map_field( & - field_src=ice_sheet_tolnd(ns)%field_topo_x_icemask_g_ec, & - field_dst=field_topo_x_icemask_l_ec, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsd, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call field_getdata2d(field_topo_x_icemask_l_ec, topo_l_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! map FBglc_frac_x_icemask from glc to land (with multiple elevation classes) - no normalization - if (dbug_flag > 1) then - call ESMF_LogWrite(trim(subname)//": calling mapping of frac_x_icemask from glc to land", ESMF_LOGMSG_INFO) - end if - call med_map_field( & - field_src=ice_sheet_tolnd(ns)%field_frac_x_icemask_g_ec, & - field_dst=field_frac_x_icemask_l_ec, & - routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & - maptype=mapconsd, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call field_getdata2d(field_frac_x_icemask_l_ec, frac_x_icemask_l_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! set Sg_topo values in export state to land (in multiple elevation classes) - ! also set the topo field for virtual columns, in a given elevation class. - ! This is needed because virtual columns (i.e., elevation classes that have no - ! contributing glc grid cells) won't have any topographic information mapped onto - ! them, so would otherwise end up with an elevation of 0. - do ec = 1,ungriddedCount - topo_virtual = glc_mean_elevation_virtual(ec-1) ! glc_mean_elevation_virtual uses 0:glc_nec - do l = 1,size(frac_x_icemask_l_ec, dim=2) - if (frac_l_ec_sum(ec,l) <= 0._r8) then - topo_l_ec_sum(ec,l) = topo_l_ec_sum(ec,l) + topo_virtual - else - if (frac_x_icemask_l_ec(ec,l) /= 0.0_r8) then - topo_l_ec_sum(ec,l) = topo_l_ec_sum(ec,l) + topo_l_ec(ec,l) / frac_x_icemask_l_ec(ec,l) - end if - end if - end do - end do - end if - end do - - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - end if - call t_stopf('MED:'//subname) - - end subroutine map_glc2lnd - end module med_phases_prep_lnd_mod diff --git a/mediator/med_phases_prep_ocn_mod.F90 b/mediator/med_phases_prep_ocn_mod.F90 index 4352239b9..3f971b0d4 100644 --- a/mediator/med_phases_prep_ocn_mod.F90 +++ b/mediator/med_phases_prep_ocn_mod.F90 @@ -5,8 +5,8 @@ module med_phases_prep_ocn_mod !----------------------------------------------------------------------------- use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - use med_constants_mod , only : czero=>med_constants_czero - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_constants_mod , only : czero =>med_constants_czero + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag use med_internalstate_mod , only : InternalState, mastertask, logunit use med_merge_mod , only : med_merge_auto, med_merge_field use med_map_mod , only : med_map_field_packed @@ -20,17 +20,15 @@ module med_phases_prep_ocn_mod use med_methods_mod , only : FB_copy => med_methods_FB_copy use med_methods_mod , only : FB_reset => med_methods_FB_reset use esmFlds , only : fldListTo - use esmFlds , only : compocn, compatm, compice, ncomps, compname, comprof + use esmFlds , only : compocn, compatm, compice use esmFlds , only : coupling_mode use perf_mod , only : t_startf, t_stopf implicit none private - public :: med_phases_prep_ocn_map - public :: med_phases_prep_ocn_merge - public :: med_phases_prep_ocn_accum_fast - public :: med_phases_prep_ocn_accum_avg + public :: med_phases_prep_ocn_accum + public :: med_phases_prep_ocn_avg private :: med_phases_prep_ocn_custom_cesm private :: med_phases_prep_ocn_custom_nems @@ -42,68 +40,7 @@ module med_phases_prep_ocn_mod contains !----------------------------------------------------------------------------- - subroutine med_phases_prep_ocn_map(gcomp, rc) - - !--------------------------------------- - ! Map all fields in from relevant source components to the ocean grid - !--------------------------------------- - - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_FieldBundleGet - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - - ! input/output variables - type(ESMF_GridComp) :: gcomp - integer, intent(out) :: rc - - ! local variables - type(InternalState) :: is_local - integer :: n1, ncnt - logical :: first_call = .true. - character(len=*), parameter :: subname='(med_phases_prep_ocn_map)' - !------------------------------------------------------------------------------- - - rc = ESMF_SUCCESS - - call t_startf('MED:'//subname) - if (dbug_flag > 20) then - call ESMF_LogWrite(subname//' called', ESMF_LOGMSG_INFO) - end if - call memcheck(subname, 5, mastertask) - - ! Get the internal state - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Count the number of fields outside of scalar data, if zero, then return - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compocn), fieldCount=ncnt, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! map all fields in FBImp that have active ocean coupling - if (ncnt > 0) then - do n1 = 1,ncomps - if (is_local%wrap%med_coupling_active(n1,compocn)) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImp(n1,n1), & - FBDst=is_local%wrap%FBImp(n1,compocn), & - FBFracSrc=is_local%wrap%FBFrac(n1), & - field_normOne=is_local%wrap%field_normOne(n1,compocn,:), & - packed_data=is_local%wrap%packed_data(n1,compocn,:), & - routehandles=is_local%wrap%RH(n1,compocn,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end do - endif - - call t_stopf('MED:'//subname) - if (dbug_flag > 20) then - call ESMF_LogWrite(subname//' done', ESMF_LOGMSG_INFO) - end if - - end subroutine med_phases_prep_ocn_map - - !----------------------------------------------------------------------------- - subroutine med_phases_prep_ocn_merge(gcomp, rc) + subroutine med_phases_prep_ocn_accum(gcomp, rc) use ESMF , only : ESMF_GridComp, ESMF_FieldBundleGet use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS @@ -131,122 +68,56 @@ subroutine med_phases_prep_ocn_merge(gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Count the number of fields outside of scalar data, if zero, then return - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compocn), fieldCount=ncnt, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (ncnt > 0) then - - !--------------------------------------- - ! merges to ocean - !--------------------------------------- - - ! auto merges to ocn - if (trim(coupling_mode) == 'cesm' .or. & - trim(coupling_mode) == 'nems_orig_data' .or. & - trim(coupling_mode) == 'hafs') then - call med_merge_auto(compocn, & - is_local%wrap%med_coupling_active(:,compocn), & - is_local%wrap%FBExp(compocn), & - is_local%wrap%FBFrac(compocn), & - is_local%wrap%FBImp(:,compocn), & - fldListTo(compocn), & - FBMed1=is_local%wrap%FBMed_aoflux_o, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else if (trim(coupling_mode) == 'nems_frac' .or. trim(coupling_mode) == 'nems_orig') then - call med_merge_auto(compocn, & - is_local%wrap%med_coupling_active(:,compocn), & - is_local%wrap%FBExp(compocn), & - is_local%wrap%FBFrac(compocn), & - is_local%wrap%FBImp(:,compocn), & - fldListTo(compocn), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - ! custom merges to ocean - if (trim(coupling_mode) == 'cesm') then - call med_phases_prep_ocn_custom_cesm(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else if (trim(coupling_mode(1:5)) == 'nems_') then - call med_phases_prep_ocn_custom_nems(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - ! diagnose output - if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(compocn), string=trim(subname)//' FBexp(compocn) ', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - endif - - if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + ! auto merges to ocn + if (trim(coupling_mode) == 'cesm' .or. & + trim(coupling_mode) == 'nems_orig_data' .or. & + trim(coupling_mode) == 'hafs') then + call med_merge_auto(compocn, & + is_local%wrap%med_coupling_active(:,compocn), & + is_local%wrap%FBExp(compocn), & + is_local%wrap%FBFrac(compocn), & + is_local%wrap%FBImp(:,compocn), & + fldListTo(compocn), & + FBMed1=is_local%wrap%FBMed_aoflux_o, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else if (trim(coupling_mode) == 'nems_frac' .or. trim(coupling_mode) == 'nems_orig') then + call med_merge_auto(compocn, & + is_local%wrap%med_coupling_active(:,compocn), & + is_local%wrap%FBExp(compocn), & + is_local%wrap%FBFrac(compocn), & + is_local%wrap%FBImp(:,compocn), & + fldListTo(compocn), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - call t_stopf('MED:'//subname) - - end subroutine med_phases_prep_ocn_merge - - !----------------------------------------------------------------------------- - subroutine med_phases_prep_ocn_accum_fast(gcomp, rc) - - ! Carry out fast accumulation for the ocean - - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_FieldBundleGet - use ESMF , only : ESMF_Clock, ESMF_Time - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - - ! input/output variables - type(ESMF_GridComp) :: gcomp - integer, intent(out) :: rc - - ! local variables - type(ESMF_Clock) :: clock - type(ESMF_Time) :: time - type(InternalState) :: is_local - integer :: i,j,n,ncnt - character(len=*), parameter :: subname='(med_phases_accum_fast)' - !--------------------------------------- - rc = ESMF_SUCCESS - - call t_startf('MED:'//subname) - if (dbug_flag > 20) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - endif + ! custom merges to ocean + if (trim(coupling_mode) == 'cesm') then + call med_phases_prep_ocn_custom_cesm(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + else if (trim(coupling_mode(1:5)) == 'nems_') then + call med_phases_prep_ocn_custom_nems(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if - ! Get the internal state - nullify(is_local%wrap) - call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + ! ocean accumulator + call FB_accum(is_local%wrap%FBExpAccum(compocn), is_local%wrap%FBExp(compocn), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + is_local%wrap%FBExpAccumCnt(compocn) = is_local%wrap%FBExpAccumCnt(compocn) + 1 - ! Count the number of fields outside of scalar data, if zero, then return - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compocn), fieldCount=ncnt, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - if (ncnt > 0) then - ! ocean accumulator - call FB_accum(is_local%wrap%FBExpAccum(compocn), is_local%wrap%FBExp(compocn), rc=rc) + ! diagnose output + if (dbug_flag > 1) then + call FB_diagnose(is_local%wrap%FBExpAccum(compocn), string=trim(subname)//' FBExpAccum accumulation ', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - - is_local%wrap%FBExpAccumCnt(compocn) = is_local%wrap%FBExpAccumCnt(compocn) + 1 - - if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExpAccum(compocn), & - string=trim(subname)//' FBExpAccum accumulation ', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - endif - + end if if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) - end subroutine med_phases_prep_ocn_accum_fast + end subroutine med_phases_prep_ocn_accum !----------------------------------------------------------------------------- - subroutine med_phases_prep_ocn_accum_avg(gcomp, rc) + subroutine med_phases_prep_ocn_avg(gcomp, rc) ! Prepare the OCN import Fields. @@ -260,7 +131,7 @@ subroutine med_phases_prep_ocn_accum_avg(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: ncnt - character(len=*),parameter :: subname='(med_phases_prep_ocn_accum_avg)' + character(len=*),parameter :: subname='(med_phases_prep_ocn)' !--------------------------------------- rc = ESMF_SUCCESS @@ -313,7 +184,7 @@ subroutine med_phases_prep_ocn_accum_avg(gcomp, rc) end if call t_stopf('MED:'//subname) - end subroutine med_phases_prep_ocn_accum_avg + end subroutine med_phases_prep_ocn_avg !----------------------------------------------------------------------------- subroutine med_phases_prep_ocn_custom_cesm(gcomp, rc) diff --git a/mediator/med_phases_prep_rof_mod.F90 b/mediator/med_phases_prep_rof_mod.F90 index 0baf8c784..9592b7a22 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -13,7 +13,7 @@ module med_phases_prep_rof_mod 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_FieldBundle, ESMF_Field use esmFlds , only : ncomps, complnd, comprof, compname, mapconsf, mapconsd - use med_internalstate_mod , only : InternalState, mastertask + use med_internalstate_mod , only : InternalState, mastertask, logunit use med_constants_mod , only : dbug_flag => med_constants_dbug_flag use med_constants_mod , only : czero => med_constants_czero use med_utils_mod , only : chkerr => med_utils_chkerr @@ -22,7 +22,6 @@ module med_phases_prep_rof_mod use med_methods_mod , only : fldbun_getdata1d => med_methods_FB_getdata1d use med_methods_mod , only : fldbun_diagnose => med_methods_FB_diagnose use med_methods_mod , only : fldbun_reset => med_methods_FB_reset - use med_methods_mod , only : fldbun_accum => med_methods_FB_accum use med_methods_mod , only : fldbun_average => med_methods_FB_average use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d @@ -31,8 +30,8 @@ module med_phases_prep_rof_mod implicit none private - public :: med_phases_prep_rof_accum - public :: med_phases_prep_rof_avg + public :: med_phases_prep_rof ! called by run sequence + public :: med_phases_prep_rof_accum ! called by med_phases_post_lnd private :: med_phases_prep_rof_irrig @@ -50,6 +49,10 @@ module med_phases_prep_rof_mod character(len=*), parameter :: irrig_normalized_field = 'Flrl_irrig_normalized' character(len=*), parameter :: irrig_volr0_field = 'Flrl_irrig_volr0 ' + ! the following are the fields that will be accumulated from the land + character(CS) :: lnd2rof_flds(6) = (/'Flrl_rofsur','Flrl_rofgwl','Flrl_rofsub', & + 'Flrl_rofdto','Flrl_rofi ','Flrl_irrig '/) + character(*) , parameter :: u_FILE_u = & __FILE__ @@ -66,10 +69,11 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) ! Mapping from the land to the rof grid is then done with the time averaged fields !------------------------------------ - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use ESMF , only : ESMF_FieldBundleGet, ESMF_StateIsCreated, ESMF_StateGet - use ESMF , only : ESMF_FieldBundleIsCreated + use NUOPC , only : NUOPC_IsConnected + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use ESMF , only : ESMF_FieldBundleGet, ESMF_StateIsCreated, ESMF_StateGet + use ESMF , only : ESMF_FieldBundleIsCreated, ESMF_Field, ESMF_FieldGet ! input/output variables type(ESMF_GridComp) :: gcomp @@ -77,8 +81,20 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) integer, intent(out) :: rc ! local variables - type(InternalState) :: is_local - integer :: i,j,n,ncnt + type(InternalState) :: is_local + integer :: i,j,n,ncnt + integer :: fieldCount + integer :: ungriddedUBound(1) + logical :: exists + real(r8), pointer :: dataptr1d(:) => null() + real(r8), pointer :: dataptr2d(:,:) => null() + real(r8), pointer :: dataptr1d_accum(:) => null() + real(r8), pointer :: dataptr2d_accum(:,:) => null() + type(ESMF_Field) :: lfield + type(ESMF_Field) :: lfield_accum + type(ESMF_Field), pointer :: fieldlist(:) => null() + type(ESMF_Field), pointer :: fieldlist_accum(:) => null() + character(CL), pointer :: lfieldnamelist(:) => null() character(len=*), parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof_accum)' !--------------------------------------- @@ -89,49 +105,48 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) end if rc = ESMF_SUCCESS - !--------------------------------------- ! Get the internal state - !--------------------------------------- - nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - ! Count the number of fields outside of scalar data, if zero, then return - !--------------------------------------- - - if (.not. ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(complnd,complnd))) then - ncnt = 0 - call ESMF_LogWrite(trim(subname)//": FBImp(complnd,complnd) is not created", & - ESMF_LOGMSG_INFO) - else - ! The scalar field has been removed from all mediator field bundles - so check if the fieldCount is - ! 0 and not 1 here - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldCount=ncnt, rc=rc) + ! Accumulate lnd input on lnd grid for fields that will be sent to rof + do n = 1,size(lnd2rof_flds) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + isPresent=exists, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": only scalar data is present in FBimp(complnd), returning", & - ESMF_LOGMSG_INFO) - end if - - !--------------------------------------- - ! Accumulate lnd input on lnd grid - !--------------------------------------- + if (exists) then + call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBImpaccum(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + field=lfield_accum, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call field_getdata2d(lfield, dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata2d(lfield_accum, dataptr2d_accum, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d_accum(:,:) = dataptr2d_accum(:,:) + dataptr2d(:,:) + else + call field_getdata1d(lfield, dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata1d(lfield_accum, dataptr1d_accum, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d_accum(:) = dataptr1d_accum(:) + dataptr1d(:) + end if + end if + end do - ! Note that all import fields from the land are accumulated - but - ! only a few will actaully be sent to the river model + ! Accumulate counter + is_local%wrap%FBImpAccumCnt(complnd) = is_local%wrap%FBImpAccumCnt(complnd) + 1 - if (ncnt > 0) then - call fldbun_accum(is_local%wrap%FBImpAccum(complnd,complnd), is_local%wrap%FBImp(complnd,complnd), rc=rc) + if (dbug_flag > 1) then + call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & + string=trim(subname)//' FBImpAccum(complnd,complnd) ', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - - is_local%wrap%FBImpAccumCnt(complnd) = is_local%wrap%FBImpAccumCnt(complnd) + 1 - - if (dbug_flag > 1) then - call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & - string=trim(subname)//' FBImpAccum(complnd,complnd) ', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if end if if (dbug_flag > 20) then @@ -142,19 +157,20 @@ subroutine med_phases_prep_rof_accum(gcomp, rc) end subroutine med_phases_prep_rof_accum !=============================================================================== - subroutine med_phases_prep_rof_avg(gcomp, rc) + subroutine med_phases_prep_rof(gcomp, rc) !------------------------------------ ! Prepare the ROF export Fields from the mediator !------------------------------------ - use NUOPC , only : NUOPC_IsConnected - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet - use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldGet - use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS - use esmFlds , only : fldListTo - use med_map_mod , only : med_map_field_packed - use med_merge_mod , only : med_merge_auto + use NUOPC , only : NUOPC_IsConnected + use ESMF , only : ESMF_GridComp, ESMF_GridCompGet + use ESMF , only : ESMF_FieldBundleGet, ESMF_FieldGet + use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS + use esmFlds , only : fldListTo + use med_map_mod , only : med_map_field_packed + use med_merge_mod , only : med_merge_auto + use med_constants_mod , only : czero => med_constants_czero ! input/output variables type(ESMF_GridComp) :: gcomp @@ -163,15 +179,18 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: i,j,n,n1,ncnt - logical :: connected + integer :: count + logical :: exists real(r8), pointer :: dataptr(:) => null() real(r8), pointer :: dataptr1d(:) => null() real(r8), pointer :: dataptr2d(:,:) => null() type(ESMF_Field) :: field_irrig_flux integer :: fieldcount + type(ESMF_Field) :: lfield type(ESMF_Field), pointer :: fieldlist(:) => null() - integer :: ungriddedUBound(1) - character(len=*),parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof_avg)' + integer :: ungriddedUBound(1) + character(CL), pointer :: lfieldnamelist(:) => null() + character(len=*),parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof)' !--------------------------------------- call t_startf('MED:'//subname) @@ -181,7 +200,7 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) rc = ESMF_SUCCESS !--------------------------------------- - ! --- Get the internal state + ! Get the internal state !--------------------------------------- nullify(is_local%wrap) @@ -189,106 +208,147 @@ subroutine med_phases_prep_rof_avg(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return !--------------------------------------- - ! Count the number of fields outside of scalar data, if zero, then return + ! Average import from land accumuled FB !--------------------------------------- - ! Note - the scalar field has been removed from all mediator field bundles - so this is why we check if the - ! fieldCount is 0 and not 1 here - call ESMF_FieldBundleGet(is_local%wrap%FBExp(comprof), fieldCount=ncnt, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + count = is_local%wrap%FBImpAccumCnt(complnd) + if (count == 0) then + if (mastertask) then + write(logunit,'(a)')trim(subname)//'accumulation count for land input averging to river is 0 '// & + ' accumulation field is set to zero' + end if + end if - if (ncnt == 0) then + do n = 1,size(lnd2rof_flds) + call ESMF_FieldBundleGet(is_local%wrap%FBImpAccum(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + isPresent=exists, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (exists) then + call ESMF_FieldBundleGet(is_local%wrap%FBImpAccum(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call field_getdata2d(lfield, dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (count == 0) then + dataptr2d(:,:) = czero + else + dataptr2d(:,:) = dataptr2d(:,:) / real(count, r8) + end if + else + call field_getdata1d(lfield, dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (count == 0) then + dataptr1d(:) = czero + else + dataptr1d(:) = dataptr1d(:) / real(count, r8) + end if + end if + end if + end do - call ESMF_LogWrite(trim(subname)//": only scalar data is present in FBexp(comprof), returning", & - ESMF_LOGMSG_INFO) - else + if (dbug_flag > 1) then + call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & + string=trim(subname)//' FBImpAccum(complnd,complnd) after avg ', rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if - !--------------------------------------- - ! average import from land accumuled FB - !--------------------------------------- + !--------------------------------------- + ! Map to create FBImpAccum(complnd,comprof) + !--------------------------------------- - call fldbun_average(is_local%wrap%FBImpAccum(complnd,complnd), is_local%wrap%FBImpAccumCnt(complnd), rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! The following assumes that only land import fields are needed to create the + ! export fields for the river component and that ALL mappings are done with mapconsf + + if (is_local%wrap%med_coupling_active(complnd,comprof)) then + call med_map_field_packed( & + FBSrc=is_local%wrap%FBImpAccum(complnd,complnd), & + FBDst=is_local%wrap%FBImpAccum(complnd,comprof), & + FBFracSrc=is_local%wrap%FBFrac(complnd), & + field_normOne=is_local%wrap%field_normOne(complnd,comprof,:), & + packed_data=is_local%wrap%packed_data(complnd,comprof,:), & + routehandles=is_local%wrap%RH(complnd,comprof,:), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return if (dbug_flag > 1) then - call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & - string=trim(subname)//' FBImpAccum(complnd,complnd) after avg ', rc=rc) + call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,comprof), & + string=trim(subname)//' FBImpAccum(complnd,comprof) after map ', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - !--------------------------------------- - ! map to create FBImpAccum(complnd,comprof) - !--------------------------------------- - - ! The following assumes that only land import fields are needed to create the - ! export fields for the river component and that ALL mappings are done with mapconsf - - if (is_local%wrap%med_coupling_active(complnd,comprof)) then - call med_map_field_packed( & - FBSrc=is_local%wrap%FBImpAccum(complnd,complnd), & - FBDst=is_local%wrap%FBImpAccum(complnd,comprof), & - FBFracSrc=is_local%wrap%FBFrac(complnd), & - field_normOne=is_local%wrap%field_normOne(complnd,comprof,:), & - packed_data=is_local%wrap%packed_data(complnd,comprof,:), & - routehandles=is_local%wrap%RH(complnd,comprof,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - if (dbug_flag > 1) then - call fldbun_diagnose(is_local%wrap%FBImpAccum(complnd,comprof), & - string=trim(subname)//' FBImpAccum(complnd,comprof) after map ', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + ! Reset the irrig_flux_field with the map_lnd2rof_irrig calculation below if appropriate + if ( NUOPC_IsConnected(is_local%wrap%NStateImp(complnd), fieldname=trim(irrig_flux_field))) then + call med_phases_prep_rof_irrig( gcomp, rc=rc ) + if (chkerr(rc,__LINE__,u_FILE_u)) return + else + ! This will ensure that no irrig is sent from the land + call fldbun_getdata1d(is_local%wrap%FBImpAccum(complnd,comprof), irrig_flux_field, dataptr, rc) + dataptr(:) = czero + end if + endif - ! Reset the irrig_flux_field with the map_lnd2rof_irrig calculation below if appropriate - if ( NUOPC_IsConnected(is_local%wrap%NStateImp(complnd), fieldname=trim(irrig_flux_field))) then - call med_phases_prep_rof_irrig( gcomp, rc=rc ) - if (chkerr(rc,__LINE__,u_FILE_u)) return - else - ! This will ensure that no irrig is sent from the land - call fldbun_getdata1d(is_local%wrap%FBImpAccum(complnd,comprof), irrig_flux_field, dataptr, rc) - dataptr(:) = czero - end if - endif + !--------------------------------------- + ! auto merges to create FBExp(comprof) + !--------------------------------------- - !--------------------------------------- - ! auto merges to create FBExp(comprof) - !--------------------------------------- + if (dbug_flag > 1) then + call fldbun_diagnose(is_local%wrap%FBFrac(comprof), & + string=trim(subname)//' FBFrac(comprof) before merge ', rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end if - if (dbug_flag > 1) then - call fldbun_diagnose(is_local%wrap%FBFrac(comprof), & - string=trim(subname)//' FBFrac(comprof) before merge ', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + call med_merge_auto(comprof, & + is_local%wrap%med_coupling_active(:,comprof), & + is_local%wrap%FBExp(comprof), & + is_local%wrap%FBFrac(comprof), & + is_local%wrap%FBImpAccum(:,comprof), & + fldListTo(comprof), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - call med_merge_auto(comprof, & - is_local%wrap%med_coupling_active(:,comprof), & - is_local%wrap%FBExp(comprof), & - is_local%wrap%FBFrac(comprof), & - is_local%wrap%FBImpAccum(:,comprof), & - fldListTo(comprof), rc=rc) + if (dbug_flag > 1) then + call fldbun_diagnose(is_local%wrap%FBExp(comprof), & + string=trim(subname)//' FBexp(comprof) ', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + end if - if (dbug_flag > 1) then - call fldbun_diagnose(is_local%wrap%FBExp(comprof), & - string=trim(subname)//' FBexp(comprof) ', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + !--------------------------------------- + ! zero accumulator and FBAccum + !--------------------------------------- - !--------------------------------------- - ! zero accumulator and FBAccum - !--------------------------------------- + ! zero counter + is_local%wrap%FBImpAccumCnt(complnd) = 0 - is_local%wrap%FBImpAccumCnt(complnd) = 0 - call fldbun_reset(is_local%wrap%FBImpAccum(complnd,complnd), czero, rc) + ! zero lnd2rof fields in FBImpAccum + do n = 1,size(lnd2rof_flds) + call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + isPresent=exists, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + if (exists) then + call ESMF_FieldBundleGet(is_local%wrap%FBImpaccum(complnd,complnd), fieldName=trim(lnd2rof_flds(n)), & + field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (ungriddedUBound(1) > 0) then + call field_getdata2d(lfield, dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr2d(:,:) = czero + else + call field_getdata1d(lfield, dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + dataptr1d(:) = czero + end if + end if + end do - endif if (dbug_flag > 20) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) - end subroutine med_phases_prep_rof_avg + end subroutine med_phases_prep_rof !=============================================================================== subroutine med_phases_prep_rof_irrig(gcomp, rc) @@ -314,12 +374,12 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) ! (non-volr-normalized) flux on the rof grid. !--------------------------------------------------------------- - use ESMF , only : ESMF_GridComp, ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate - use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldIsCreated - use ESMF , only : ESMF_Mesh, ESMF_TYPEKIND_R8, ESMF_MESHLOC_ELEMENT - use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_LOGMSG_ERROR - use med_map_mod , only : med_map_rh_is_created, med_map_field, med_map_field_normalized + use ESMF , only : ESMF_GridComp, ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate + use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldIsCreated + use ESMF , only : ESMF_Mesh, ESMF_TYPEKIND_R8, ESMF_MESHLOC_ELEMENT + use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE + use ESMF , only : ESMF_LOGMSG_INFO, ESMF_LogWrite, ESMF_LOGMSG_ERROR + use med_map_mod , only : med_map_rh_is_created, med_map_field, med_map_field_normalized ! input/output variables type(ESMF_GridComp) :: gcomp @@ -356,7 +416,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) rc = ESMF_SUCCESS !--------------------------------------- - ! --- Get the internal state + ! Get the internal state !--------------------------------------- nullify(is_local%wrap) diff --git a/mediator/med_phases_profile_mod.F90 b/mediator/med_phases_profile_mod.F90 index f69696733..447b1e4c2 100644 --- a/mediator/med_phases_profile_mod.F90 +++ b/mediator/med_phases_profile_mod.F90 @@ -9,7 +9,7 @@ module med_phases_profile_mod use med_utils_mod , only : med_utils_chkerr, med_memcheck use med_internalstate_mod , only : mastertask, logunit use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_time_mod , only : alarmInit => med_time_alarmInit + use med_time_mod , only : alarmInit => med_time_alarmInit use perf_mod , only : t_startf, t_stopf use shr_mem_mod , only : shr_mem_getusage @@ -38,7 +38,7 @@ subroutine med_phases_profile(gcomp, rc) use ESMF , only : ESMF_TimeSyncToRealTime, ESMF_Time, ESMF_TimeSet use ESMF , only : ESMF_TimeInterval, ESMF_AlarmGet, ESMF_TimeIntervalGet use ESMF , only : ESMF_ClockGetNextTime, ESMF_TimeGet, ESMF_ClockGet - use ESMF , only : ESMF_ClockAdvance, ESMF_ClockSet, ESMF_ClockIsStopTime + use ESMF , only : ESMF_ClockAdvance, ESMF_ClockSet, ESMF_ClockIsStopTime use ESMF , only : operator(-) use NUOPC , only : NUOPC_CompAttributeGet @@ -102,7 +102,7 @@ subroutine med_phases_profile(gcomp, rc) call ESMF_ClockSet(clock, currTime=currtime, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! intialize + ! intialize call ESMF_VMWtime(previous_time, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -150,21 +150,18 @@ subroutine med_phases_profile(gcomp, rc) wallclockelapsed = current_time - previous_time accumulated_time = accumulated_time + wallclockelapsed - + ringdays = timestep_length if (alarmison) then call ESMF_AlarmGet( alarm, ringInterval=ringInterval, rc=rc) if (med_utils_chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_TimeIntervalGet(ringInterval, d_r8=ringdays, rc=rc) if (med_utils_chkerr(rc,__LINE__,u_FILE_u)) return - avgdt = accumulated_time/(ringdays*real(iterations-1)) else if (stopalarmison) then ! Here we need the interval since the last call to this function call ESMF_TimeIntervalGet(nexttime-prevtime, d_r8=ringdays, rc=rc) if (med_utils_chkerr(rc,__LINE__,u_FILE_u)) return - else - avgdt = wallclockelapsed/timestep_length - ringdays = timestep_length endif + avgdt = accumulated_time/(timestep_length*real(iterations-1, kind=r8)) prevtime = nexttime call ESMF_TimeGet(nexttime, timestring=nexttimestr, rc=rc) if (med_utils_ChkErr(rc,__LINE__,u_FILE_u)) return @@ -177,12 +174,11 @@ subroutine med_phases_profile(gcomp, rc) call ESMF_TimeGet(wallclocktime,timeString=walltimestr, rc=rc) if (med_utils_ChkErr(rc,__LINE__,u_FILE_u)) return - ! 1 model day/ x seconds = 1/365 yrs/ (wallclockelapsed s/86400spd ypd = ringdays*86400.0_R8/(365.0_R8*wallclockelapsed) write(logunit,101) 'Model Date: ',trim(nexttimestr), ' wall clock = ',trim(walltimestr),' avg dt = ', & - avgdt, 's/day, dt = ',wallclockelapsed/ringdays,'s/day, rate = ',ypd,' ypd' + avgdt, ' s/day, dt = ',wallclockelapsed/ringdays,' s/day, rate = ',ypd,' ypd' call shr_mem_getusage(msize,mrss,.true.) write(logunit,105) ' memory_write: model date = ',trim(nexttimestr), &