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/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..14e0ef046 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,48 @@ +cmake_minimum_required(VERSION 3.10) +include(ExternalProject) + +if (DEFINED CIMEROOT) + message("Using CIME in ${CIMEROOT} with compiler ${COMPILER}") + include(${CASEROOT}/Macros.cmake) + if (${PIO_VERSION} LESS 2) + message( FATAL_ERROR "Version 2 of the PIO library required") + endif() + if (${MPILIB} STREQUAL "mpi-serial") + set(CMAKE_C_COMPILER ${SCC}) + set(CMAKE_Fortran_COMPILER ${SFC}) + set(CMAKE_CXX_COMPILER ${SCXX}) + else() + set(CMAKE_C_COMPILER ${MPICC}) + set(CMAKE_Fortran_COMPILER ${MPIFC}) + set(CMAKE_CXX_COMPILER ${MPICXX}) + endif() + set(CMAKE_Fortran_FLAGS "${FFLAGS} -I${LIBROOT}/include -I${LIBROOT}/finclude -I${LIBROOT}/nuopc/esmf/${NINST_VALUE}/include") +else() + set(BLD_STANDALONE TRUE) +endif() + +project(CMEPS LANGUAGES Fortran VERSION 0.1) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) + +message("CMAKE_MODULE_PATH is ${CMAKE_MODULE_PATH}") + +find_package(ESMF REQUIRED) +if (DEFINED PIO) + set(PIO_PATH ${PIO}) +else() + set(PIO_PATH $ENV{PIO}) +endif() +find_package(PIO REQUIRED COMPONENT C Fortran PATH ${PIO_PATH}) + +if (NOT DEFINED MPILIB OR NOT ${MPILIB} STREQUAL "mpi-serial") + find_package(MPI REQUIRED) +endif() + +if(BLD_STANDALONE) + add_subdirectory(nems/util) + list(APPEND EXTRA_LIBS cmeps_share) + list(APPEND EXTRA_INCLUDES "${CMAKE_BINARY_DIR}/nems/util") +endif() + +add_subdirectory(mediator) diff --git a/cime_config/buildnml b/cime_config/buildnml index 9d18d7136..7422bc576 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -399,8 +399,6 @@ def _create_runseq(case, coupling_times, valid_comps): from runseq_D import gen_runseq elif (comp_lnd == 'dlnd' and comp_glc == "cism"): from runseq_TG import gen_runseq - elif (comp_atm == 'ufsatm' and comp_ocn == "mom" and comp_ice == 'cice'): - from runseq_NEMS import gen_runseq else: from runseq_general import gen_runseq @@ -571,10 +569,8 @@ def buildnml(case, caseroot, component): filename = os.path.join(fd_dir,"fd_cesm.yaml") elif coupling_mode == 'hafs': filename = os.path.join(fd_dir,"fd_hafs.yaml") - elif 'nems' in coupling_mode: - filename = os.path.join(fd_dir,"fd_nems.yaml") else: - expect(False, "coupling mode currently only supports cesm, hafs and nems") + expect(False, "coupling mode currently only supports cesm") shutil.copy(filename, os.path.join(rundir, "fd.yaml")) ############################################################################### diff --git a/cime_config/namelist_definition_drv.xml b/cime_config/namelist_definition_drv.xml index 3bbc58483..d36e61c2b 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 @@ -768,6 +768,31 @@ + + logical + flds + ALLCOMP_attributes + + .true. if ocean sends fields at multiple ocean levels to the land-ice component + + + .false. + + + + + char + flds + ALLCOMP_attributes + + if the ocean component sends fields at multiple ocean levels to the + land-ice component, these are the colon deliminted level indices + + + 1:10:19:26:30:33:35 + + + char control @@ -826,6 +851,161 @@ + + integer + control + MED_attributes + + number of atm cells in i direction + + + $ATM_NX + + + + integer + control + MED_attributes + + number of atm cells in j direction + + + $ATM_NY + + + + integer + control + MED_attributes + + number of ice cells in i direction + + + $ICE_NX + + + + integer + control + MED_attributes + + number of ice cells in j direction + + + $ICE_NY + + + + integer + control + MED_attributes + + number of glc cells in i direction + + + $GLC_NX + + + + integer + control + MED_attributes + + number of glc cells in j direction + + + $GLC_NY + + + + integer + control + MED_attributes + + number of lnd cells in i direction + + + $LND_NX + + + + integer + control + MED_attributes + + number of lnd cells in j direction + + + $LND_NY + + + + integer + control + MED_attributes + + number of ocn cells in i direction + + + $OCN_NX + + + + integer + control + MED_attributes + + number of ocn cells in j direction + + + $OCN_NY + + + + integer + control + MED_attributes + + number of rof cells in i direction + + + $ROF_NX + + + + integer + control + MED_attributes + + number of rof cells in j direction + + + $ROF_NY + + + + integer + control + MED_attributes + + number of wav cells in i direction + + + $WAV_NX + + + + integer + control + MED_attributes + + number of wav cells in j direction + + + $WAV_NY + + + char control 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 e0a4cfb36..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 @@ -61,104 +73,118 @@ def gen_runseq(case, coupling_times): runseq.enter_time_loop(glc_cpl_time, newtime=run_glc, active=med_to_glc) #------------------ - runseq.add_action("MED med_phases_prep_glc_avg" , 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.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_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 and not ocn_outer_loop) - 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" , 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/cime_config/testdefs/testlist_drv.xml b/cime_config/testdefs/testlist_drv.xml index ad1d2514d..67393e5f6 100644 --- a/cime_config/testdefs/testlist_drv.xml +++ b/cime_config/testdefs/testlist_drv.xml @@ -309,26 +309,6 @@ - - - - - - - - - - - - - - - - - - - - @@ -354,26 +334,6 @@ - - - - - - - - - - - - - - - - - - - - @@ -399,7 +359,7 @@ - + @@ -409,7 +369,7 @@ - + @@ -419,32 +379,22 @@ - + + + + + + - - - - - - - - - - - + - - - - - - + @@ -454,7 +404,7 @@ - + @@ -466,7 +416,7 @@ - + @@ -488,6 +438,4 @@ - - diff --git a/cmake/FindESMF.cmake b/cmake/FindESMF.cmake new file mode 100644 index 000000000..175a39488 --- /dev/null +++ b/cmake/FindESMF.cmake @@ -0,0 +1,47 @@ + +if (DEFINED ENV{ESMFMKFILE}) + message("ESMFMKFILE: $ENV{ESMFMKFILE}") +else() + message(FATAL_ERROR "ESMFMKFILE env variable is not defined") +endif() + +set(ESMFMKFILE $ENV{ESMFMKFILE}) + +# convert esmf.mk makefile variables to cmake variables until ESMF +# provides proper cmake package +file(STRINGS ${ESMFMKFILE} esmf_mk_text) +foreach(line ${esmf_mk_text}) + string(REGEX REPLACE "^[ ]+" "" line ${line}) # strip leading spaces + if (line MATCHES "^ESMF_*") # process only line starting with ESMF_ + string(REGEX MATCH "^ESMF_[^=]+" esmf_name ${line}) + string(REPLACE "${esmf_name}=" "" emsf_value ${line}) + set(${esmf_name} "${emsf_value}") + endif() +endforeach() +string(REPLACE "-I" "" ESMF_F90COMPILEPATHS ${ESMF_F90COMPILEPATHS}) +string(REPLACE " " ";" ESMF_F90COMPILEPATHS ${ESMF_F90COMPILEPATHS}) + +# We use only these 4 variables in our build system. Make sure they are all set +if(ESMF_VERSION_MAJOR AND + ESMF_F90COMPILEPATHS AND + ESMF_F90ESMFLINKRPATHS AND + ESMF_F90ESMFLINKLIBS) + message(" Found ESMF:") + message("ESMF_VERSION_MAJOR: ${ESMF_VERSION_MAJOR}") + message("ESMF_F90COMPILEPATHS: ${ESMF_F90COMPILEPATHS}") + message("ESMF_F90ESMFLINKRPATHS: ${ESMF_F90ESMFLINKRPATHS}") + message("ESMF_F90ESMFLINKLIBS: ${ESMF_F90ESMFLINKLIBS}") +else() + message("One of the ESMF_ variables is not defined") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(ESMF + FOUND_VAR + ESMF_FOUND + REQUIRED_VARS + ESMF_F90COMPILEPATHS + ESMF_F90ESMFLINKRPATHS + ESMF_F90ESMFLINKLIBS + VERSION_VAR + ESMF_VERSION_STRING) diff --git a/cmake/FindPIO.cmake b/cmake/FindPIO.cmake new file mode 100644 index 000000000..2a7af648a --- /dev/null +++ b/cmake/FindPIO.cmake @@ -0,0 +1,103 @@ +# - Try to find PIO +# +# This can be controled by setting PIO_PATH or PIO__PATH Cmake variables, +# where is the COMPONENT language one needs. +# +# Once done, this will define: +# +# PIO__FOUND (BOOL) - system has PIO +# PIO__IS_SHARED (BOOL) - whether the library is shared/dynamic +# PIO__INCLUDE_DIR (PATH) - Location of the header files and modules +# PIO__LIBRARY (File) - Path to the library files +# PIO__LIBRARIES (List) - link these to use PIO +# +# Available COMPONENTS are: C Fortran +# If no components are specified only C is assumed +include (LibFind) +include (LibCheck) + +# Define PIO C Component +define_package_component(PIO DEFAULT + COMPONENT C + INCLUDE_NAMES pio.h + LIBRARY_NAMES pioc) + +# Define PIO Fortran Component +define_package_component(PIO + COMPONENT Fortran + INCLUDE_NAMES pio.mod pio.inc + LIBRARY_NAMES piof) + +# Search for list of valid components requested +find_valid_components(PIO) + +#============================================================================== +# SEARCH FOR VALIDATED COMPONENTS +foreach (pcomp IN LISTS PIO_FIND_VALID_COMPONENTS) + + # If not found already, search... + if (NOT PIO_${pcomp}_FOUND) + + # Manually add the MPI include and library dirs to search paths + # and search for the package component + if (MPI_${pcomp}_FOUND) + initialize_paths (PIO_${pcomp}_PATHS + INCLUDE_DIRECTORIES ${MPI_${pcomp}_INCLUDE_PATH} + LIBRARIES ${MPI_${pcomp}_LIBRARIES}) + find_package_component(PIO COMPONENT ${pcomp} + PATHS ${PIO_${pcomp}_PATHS}) + else () + find_package_component(PIO COMPONENT ${pcomp} HINT PIO_${pcomp}_PATH=${PIO_PATH}) + endif () + + # Continue only if component found + if (PIO_${pcomp}_FOUND) + + # Checks + if (pcomp STREQUAL C) + + # Check version + check_version (PIO + NAME "pio_meta.h" + HINTS ${PIO_C_INCLUDE_DIRS} + MACRO_REGEX "PIO_VERSION_") + + endif () + + # Dependencies + if (pcomp STREQUAL C AND NOT PIO_C_IS_SHARED) + + # DEPENDENCY: PnetCDF (if PnetCDF enabled) + check_macro (PIO_HAS_PNETCDF + NAME TryPIO_PNETCDF.c + HINTS ${CMAKE_MODULE_PATH} + DEFINITIONS -I${PIO_C_INCLUDE_DIR} + COMMENT "whether PIO has PnetCDF support") + if (PIO_HAS_PNETCDF) + find_package (PnetCDF COMPONENTS C) + endif () + + + elseif (pcomp STREQUAL Fortran AND NOT PIO_Fortran_IS_SHARED) + + # DEPENDENCY: PIO + set (orig_comp ${pcomp}) + set (orig_comps ${PIO_FIND_VALID_COMPONENTS}) + find_package (PIO COMPONENTS C) + set (PIO_FIND_VALID_COMPONENTS ${orig_comps}) + set (pcomp ${orig_comp}) + if (PIO_C_FOUND) + list (APPEND PIO_Fortran_INCLUDE_DIRS ${PIO_C_INCLUDE_DIRS}) + list (APPEND PIO_Fortran_LIBRARIES ${PIO_C_LIBRARIES}) + endif () + + endif () + + endif () + + endif () + +endforeach () +message("PIO_C_FOUND ${PIO_C_FOUND}") +message("PIO_Fortran_FOUND ${PIO_Fortran_FOUND}") +message("PIO_Fortran_INCLUDE_DIR ${PIO_Fortran_INCLUDE_DIR}") diff --git a/cmake/LibCheck.cmake b/cmake/LibCheck.cmake new file mode 100644 index 000000000..3f12bdf79 --- /dev/null +++ b/cmake/LibCheck.cmake @@ -0,0 +1,104 @@ +include (CMakeParseArguments) +include (CheckFunctionExists) +#============================================================================== +# +# FUNCTIONS TO HELP WITH Check* MODULES +# +#============================================================================== + +#______________________________________________________________________________ +# - Basic function to check a property of a package using a try_compile step +# +# SYNTAX: check_macro ( +# NAME +# HINTS ... +# DEFINITIONS ... +# COMMENT ) +# +function (check_macro VARIABLE) + + # Parse the input arguments + set (oneValueArgs COMMENT NAME) + set (multiValueArgs HINTS DEFINITIONS) + cmake_parse_arguments (${VARIABLE} "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # If the return variable is defined, already, don't continue + if (NOT DEFINED ${VARIABLE}) + + message (STATUS "Checking ${${VARIABLE}_COMMENT}") + find_file (${VARIABLE}_TRY_FILE + NAMES ${${VARIABLE}_NAME} + HINTS ${${VARIABLE}_HINTS}) + if (${VARIABLE}_TRY_FILE) + try_compile (COMPILE_RESULT + ${CMAKE_CURRENT_BINARY_DIR}/try${VARIABLE} + SOURCES ${${VARIABLE}_TRY_FILE} + COMPILE_DEFINITIONS ${${VARIABLE}_DEFINITIONS} + OUTPUT_VARIABLE TryOUT) + if (COMPILE_RESULT) + message (STATUS "Checking ${${VARIABLE}_COMMENT} - yes") + else () + message (STATUS "Checking ${${VARIABLE}_COMMENT} - no") + endif () + + set (${VARIABLE} ${COMPILE_RESULT} + CACHE BOOL "${${VARIABLE}_COMMENT}") + + else () + message (STATUS "Checking ${${VARIABLE}_COMMENT} - failed") + endif () + + unset (${VARIABLE}_TRY_FILE CACHE) + endif () + +endfunction () + +#______________________________________________________________________________ +# - Basic function to check the version of a package using a try_run step +# +# SYNTAX: check_version ( +# NAME +# HINTS ... +# DEFINITIONS ...) +# +function (check_version PKG) + + # Parse the input arguments + set (oneValueArgs NAME MACRO_REGEX) + set (multiValueArgs HINTS) + cmake_parse_arguments (${PKG} "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # If the return variable is defined, already, don't continue + if (NOT DEFINED ${PKG}_VERSION) + + message (STATUS "Checking ${PKG} version") + find_file (${PKG}_VERSION_HEADER + NAMES ${${PKG}_NAME} + HINTS ${${PKG}_HINTS}) + if (${PKG}_VERSION_HEADER) + set (def) + file (STRINGS ${${PKG}_VERSION_HEADER} deflines + REGEX "^#define[ \\t]+${${PKG}_MACRO_REGEX}") + foreach (defline IN LISTS deflines) + string (REPLACE "\"" "" defline "${defline}") + string (REPLACE "." "" defline "${defline}") + string (REGEX REPLACE "[ \\t]+" ";" deflist "${defline}") + list (GET deflist 2 arg) + list (APPEND def ${arg}) + endforeach () + string (REPLACE ";" "." vers "${def}") + message (STATUS "Checking ${PKG} version - ${vers}") + set (${PKG}_VERSION ${vers} + CACHE STRING "${PKG} version string") + if (${PKG}_VERSION VERSION_LESS ${PKG}_FIND_VERSION}) + message (FATAL_ERROR "${PKG} version insufficient") + endif () + else () + message (STATUS "Checking ${PKG} version - failed") + endif () + + unset (${PKG}_VERSION_HEADER CACHE) + + endif () + +endfunction () \ No newline at end of file diff --git a/cmake/LibFind.cmake b/cmake/LibFind.cmake new file mode 100644 index 000000000..61cd93aa3 --- /dev/null +++ b/cmake/LibFind.cmake @@ -0,0 +1,333 @@ +include (CMakeParseArguments) +include(FindPackageHandleStandardArgs) + +#============================================================================== +# +# FUNCTIONS TO HELP WITH Find* MODULES +# +#============================================================================== + +#______________________________________________________________________________ +# - Wrapper for finding static libraries ONLY +# +macro (find_static_library) + set (_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX}) + find_library(${ARGN}) + set (CMAKE_FIND_LIBRARY_SUFFIXES ${_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset (_CMAKE_FIND_LIBRARY_SUFFIXES) +endmacro () + + +#______________________________________________________________________________ +# - Wrapper for finding shared/dynamic libraries ONLY +# +macro (find_shared_library) + set (_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set (CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX}) + find_library(${ARGN}) + set (CMAKE_FIND_LIBRARY_SUFFIXES ${_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset (_CMAKE_FIND_LIBRARY_SUFFIXES) +endmacro () + + +#______________________________________________________________________________ +# - Function to determine type (SHARED or STATIC) of library +# +# Input: +# LIB (FILE) +# +# Returns: +# RETURN_VAR (BOOL) +# +function (is_shared_library RETURN_VAR LIB) + get_filename_component(libext ${LIB} EXT) + if (libext MATCHES ${CMAKE_SHARED_LIBRARY_SUFFIX}) + set (${RETURN_VAR} TRUE PARENT_SCOPE) + else () + set (${RETURN_VAR} FALSE PARENT_SCOPE) + endif () +endfunction () + + +#______________________________________________________________________________ +# - Function to define a valid package component +# +# Input: +# ${PKG}_DEFAULT (BOOL) +# ${PKG}_COMPONENT (STRING) +# ${PKG}_INCLUDE_NAMES (LIST) +# ${PKG}_LIBRARY_NAMES (LIST) +# +# Returns: +# ${PKG}_DEFAULT_COMPONENT (STRING) +# ${PKG}_VALID_COMPONENTS (LIST) +# ${PKG}_${COMPONENT}_INCLUDE_NAMES (LIST) +# ${PKG}_${COMPONENT}_LIBRARY_NAMES (LIST) +# +function (define_package_component PKG) + + # Parse the input arguments + set (options DEFAULT) + set (oneValueArgs COMPONENT) + set (multiValueArgs INCLUDE_NAMES LIBRARY_NAMES) + cmake_parse_arguments (${PKG} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if (${PKG}_COMPONENT) + set (PKGCOMP ${PKG}_${${PKG}_COMPONENT}) + else () + set (PKGCOMP ${PKG}) + endif () + + # Set return values + if (${PKG}_COMPONENT) + if (${PKG}_DEFAULT) + set (${PKG}_DEFAULT_COMPONENT ${${PKG}_COMPONENT} PARENT_SCOPE) + endif () + set (VALID_COMPONENTS ${${PKG}_VALID_COMPONENTS}) + list (APPEND VALID_COMPONENTS ${${PKG}_COMPONENT}) + set (${PKG}_VALID_COMPONENTS ${VALID_COMPONENTS} PARENT_SCOPE) + endif () + set (${PKGCOMP}_INCLUDE_NAMES ${${PKG}_INCLUDE_NAMES} PARENT_SCOPE) + set (${PKGCOMP}_LIBRARY_NAMES ${${PKG}_LIBRARY_NAMES} PARENT_SCOPE) + +endfunction () + + +#______________________________________________________________________________ +# - Function to find valid package components +# +# Assumes pre-defined variables: +# ${PKG}_FIND_COMPONENTS (LIST) +# ${PKG}_DEFAULT_COMPONENT (STRING) +# ${PKG}_VALID_COMPONENTS (LIST) +# +# Returns: +# ${PKG}_FIND_VALID_COMPONENTS (LIST) +# +function (find_valid_components PKG) + + if (NOT ${PKG}_FIND_COMPONENTS) + set (${PKG}_FIND_COMPONENTS ${${PKG}_DEFAULT_COMPONENT}) + endif () + + set (FIND_VALID_COMPONENTS) + foreach (comp IN LISTS ${PKG}_FIND_COMPONENTS) + if (";${${PKG}_VALID_COMPONENTS};" MATCHES ";${comp};") + list (APPEND FIND_VALID_COMPONENTS ${comp}) + endif () + endforeach () + + set (${PKG}_FIND_VALID_COMPONENTS ${FIND_VALID_COMPONENTS} PARENT_SCOPE) + +endfunction () + + +#______________________________________________________________________________ +# - Initialize a list of paths from a list of includes and libraries +# +# Input: +# INCLUDE_DIRECTORIES +# LIBRARIES +# +# Ouput: +# ${PATHLIST} +# +function (initialize_paths PATHLIST) + + # Parse the input arguments + set (multiValueArgs INCLUDE_DIRECTORIES LIBRARIES) + cmake_parse_arguments (INIT "" "" "${multiValueArgs}" ${ARGN}) + + set (paths) + foreach (inc IN LISTS INIT_INCLUDE_DIRECTORIES) + list (APPEND paths ${inc}) + get_filename_component (dname ${inc} NAME) + if (dname MATCHES "include") + get_filename_component (prefx ${inc} PATH) + list (APPEND paths ${prefx}) + endif () + endforeach () + foreach (lib IN LISTS INIT_LIBRARIES) + get_filename_component (libdir ${lib} PATH) + list (APPEND paths ${libdir}) + get_filename_component (dname ${libdir} PATH) + if (dname MATCHES "lib") + get_filename_component (prefx ${libdir} PATH) + list (APPEND paths ${prefx}) + endif () + endforeach () + + set (${PATHLIST} ${paths} PARENT_SCOPE) + +endfunction () + + +#______________________________________________________________________________ +# - Basic find package macro for a specific component +# +# Assumes pre-defined variables: +# ${PKG}_${COMP}_INCLUDE_NAMES or ${PKG}_INCLUDE_NAMES +# ${PKG}_${COMP}_LIBRARY_NAMES or ${PKG}_LIBRARY_NAMES +# +# Input: +# ${PKG}_COMPONENT +# ${PKG}_HINTS +# ${PKG}_PATHS +# +function (find_package_component PKG) + + # Parse the input arguments + set (options) + set (oneValueArgs COMPONENT) + set (multiValueArgs HINTS PATHS) + cmake_parse_arguments (${PKG} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + set (COMP ${${PKG}_COMPONENT}) + if (COMP) + set (PKGCOMP ${PKG}_${COMP}) + else () + set (PKGCOMP ${PKG}) + endif () + string (TOUPPER ${PKG} PKGUP) + string (TOUPPER ${PKGCOMP} PKGCOMPUP) + + # Only continue if package not found already + if (NOT ${PKGCOMP}_FOUND) + + # Handle QUIET and REQUIRED arguments + if (${${PKG}_FIND_QUIETLY}) + set (${PKGCOMP}_FIND_QUIETLY TRUE) + endif () + if (${${PKG}_FIND_REQUIRED}) + set (${PKGCOMP}_FIND_REQUIRED TRUE) + endif () + + # Determine search order + set (SEARCH_DIRS) + if (${PKG}_HINTS) + list (APPEND SEARCH_DIRS ${${PKG}_HINTS}) + endif () + if (${PKGCOMP}_PATH) + list (APPEND SEARCH_DIRS ${${PKGCOMP}_PATH}) + endif () + if (${PKG}_PATH) + list (APPEND SEARCH_DIRS ${${PKG}_PATH}) + endif () + if (DEFINED ENV{${PKGCOMPUP}}) + list (APPEND SEARCH_DIRS $ENV{${PKGCOMPUP}}) + endif () + if (DEFINED ENV{${PKGUP}}) + list (APPEND SEARCH_DIRS $ENV{${PKGUP}}) + endif () + if (CMAKE_SYSTEM_PREFIX_PATH) + list (APPEND SEARCH_DIRS ${CMAKE_SYSTEM_PREFIX_PATH}) + endif () + if (${PKG}_PATHS) + list (APPEND SEARCH_DIRS ${${PKG}_PATHS}) + endif () + + # Start the search for the include file and library file. Only overload + # if the variable is not defined. + foreach (suffix PREFIX LIBRARY INCLUDE_DIR) + if (NOT DEFINED ${PKGCOMP}_${suffix}) + set (${PKGCOMP}_${suffix} ${PKGCOMP}_${suffix}-NOTFOUND) + endif () + endforeach () + + foreach (dir IN LISTS SEARCH_DIRS) + + # Search for include file names in current dirrectory + foreach (iname IN LISTS ${PKGCOMP}_INCLUDE_NAMES) + if (EXISTS ${dir}/${iname}) + set (${PKGCOMP}_PREFIX ${dir}) + set (${PKGCOMP}_INCLUDE_DIR ${dir}) + break () + endif () + if (EXISTS ${dir}/include/${iname}) + set (${PKGCOMP}_PREFIX ${dir}) + set (${PKGCOMP}_INCLUDE_DIR ${dir}/include) + break () + endif () + endforeach () + + # Search for library file names in the found prefix only! + if (${PKGCOMP}_PREFIX) + find_library (${PKGCOMP}_LIBRARY + NAMES ${${PKGCOMP}_LIBRARY_NAMES} + PATHS ${${PKGCOMP}_PREFIX} + PATH_SUFFIXES lib + NO_DEFAULT_PATH) + + # If found, check if library is static or dynamic + if (${PKGCOMP}_LIBRARY) + is_shared_library (${PKGCOMP}_IS_SHARED ${${PKGCOMP}_LIBRARY}) + + # If we want only shared libraries, and it isn't shared... + if (PREFER_SHARED AND NOT ${PKGCOMP}_IS_SHARED) + find_shared_library (${PKGCOMP}_SHARED_LIBRARY + NAMES ${${PKGCOMP}_LIBRARY_NAMES} + PATHS ${${PKGCOMP}_PREFIX} + PATH_SUFFIXES lib + NO_DEFAULT_PATH) + if (${PKGCOMP}_SHARED_LIBRARY) + set (${PKGCOMP}_LIBRARY ${${PKGCOMP}_SHARED_LIBRARY}) + set (${PKGCOMP}_IS_SHARED TRUE) + endif () + + # If we want only static libraries, and it is shared... + elseif (PREFER_STATIC AND ${PKGCOMP}_IS_SHARED) + find_static_library (${PKGCOMP}_STATIC_LIBRARY + NAMES ${${PKGCOMP}_LIBRARY_NAMES} + PATHS ${${PKGCOMP}_PREFIX} + PATH_SUFFIXES lib + NO_DEFAULT_PATH) + if (${PKGCOMP}_STATIC_LIBRARY) + set (${PKGCOMP}_LIBRARY ${${PKGCOMP}_STATIC_LIBRARY}) + set (${PKGCOMP}_IS_SHARED FALSE) + endif () + endif () + endif () + + # If include dir and library both found, then we're done + if (${PKGCOMP}_INCLUDE_DIR AND ${PKGCOMP}_LIBRARY) + break () + + # Otherwise, reset the search variables and continue + else () + set (${PKGCOMP}_PREFIX ${PKGCOMP}_PREFIX-NOTFOUND) + set (${PKGCOMP}_INCLUDE_DIR ${PKGCOMP}_INCLUDE_DIR-NOTFOUND) + set (${PKGCOMP}_LIBRARY ${PKGCOMP}_LIBRARY-NOTFOUND) + endif () + endif () + + endforeach () + + # handle the QUIETLY and REQUIRED arguments and + # set NetCDF_C_FOUND to TRUE if all listed variables are TRUE + find_package_handle_standard_args (${PKGCOMP} DEFAULT_MSG + ${PKGCOMP}_LIBRARY + ${PKGCOMP}_INCLUDE_DIR) + mark_as_advanced (${PKGCOMP}_INCLUDE_DIR ${PKGCOMP}_LIBRARY) + + # HACK For bug in CMake v3.0: + set (${PKGCOMP}_FOUND ${${PKGCOMPUP}_FOUND}) + + # Set return variables + if (${PKGCOMP}_FOUND) + set (${PKGCOMP}_INCLUDE_DIRS ${${PKGCOMP}_INCLUDE_DIR}) + set (${PKGCOMP}_LIBRARIES ${${PKGCOMP}_LIBRARY}) + endif () + + # Set variables in parent scope + set (${PKGCOMP}_FOUND ${${PKGCOMP}_FOUND} PARENT_SCOPE) + set (${PKGCOMP}_INCLUDE_DIR ${${PKGCOMP}_INCLUDE_DIR} PARENT_SCOPE) + set (${PKGCOMP}_INCLUDE_DIRS ${${PKGCOMP}_INCLUDE_DIRS} PARENT_SCOPE) + set (${PKGCOMP}_LIBRARY ${${PKGCOMP}_LIBRARY} PARENT_SCOPE) + set (${PKGCOMP}_LIBRARIES ${${PKGCOMP}_LIBRARIES} PARENT_SCOPE) + set (${PKGCOMP}_IS_SHARED ${${PKGCOMP}_IS_SHARED} PARENT_SCOPE) + + endif () + +endfunction () + + + diff --git a/mediator/CMakeLists.txt b/mediator/CMakeLists.txt new file mode 100644 index 000000000..91f2921e9 --- /dev/null +++ b/mediator/CMakeLists.txt @@ -0,0 +1,39 @@ +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_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}") + list(REMOVE_ITEM SRCFILES ${FILE}) + list(APPEND SRCFILES "${CASEROOT}/SourceMods/src.cmeps/${FILE}") + message("Using ${FILE} from ${CASEROOT}/SourceMods/src.cmeps") + endif() +endforeach() +add_library(cmeps ${SRCFILES}) + +if(BLD_STANDALONE) + add_dependencies(cmeps cmeps_share) +endif() + +target_include_directories (cmeps PUBLIC ${ESMF_F90COMPILEPATHS}) +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) diff --git a/mediator/Makefile b/mediator/Makefile index acf5cb68c..e9a29d09f 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -3,6 +3,8 @@ $(error Environment variable ESMFMKFILE was not set.) endif include $(ESMFMKFILE) +ESMF_VERSION_MAJOR ?= 0 +ESMF_VERSION_MINOR ?= 0 CPPDEFS += -DESMF_VERSION_MAJOR=$(ESMF_VERSION_MAJOR) -DESMF_VERSION_MINOR=$(ESMF_VERSION_MINOR) ifndef PIO_INCLUDE_DIR @@ -20,13 +22,13 @@ OBJ = $(patsubst %.F90, %.o, $(wildcard *.F90)) all default: $(LIBRARY) $(LIBRARY): $(OBJ) - $(AR) $(ARFLAGS) $@ $? + $(AR) $(ARFLAGS) $@ $? -%.o: %.F90 +%.o: %.F90 $(ESMF_F90COMPILER) -c $(ESMF_F90COMPILEOPTS) $(ESMF_F90COMPILEPATHS) $(CPPDEFS) -I$(PIO_ROOT)/include -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 @@ -38,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 @@ -55,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 6f2396923..e41d4289f 100644 --- a/mediator/esmFlds.F90 +++ b/mediator/esmFlds.F90 @@ -9,18 +9,30 @@ module esmflds ! Set components !----------------------------------------------- - integer, public, parameter :: ncomps = 8 - integer, public, parameter :: compmed = 1 - integer, public, parameter :: compatm = 2 - integer, public, parameter :: complnd = 3 - integer, public, parameter :: compocn = 4 - integer, public, parameter :: compice = 5 - integer, public, parameter :: comprof = 6 - integer, public, parameter :: compwav = 7 - integer, public, parameter :: compglc = 8 + integer, public, parameter :: compmed = 1 + integer, public, parameter :: compatm = 2 + integer, public, parameter :: complnd = 3 + integer, public, parameter :: compocn = 4 + integer, public, parameter :: compice = 5 + integer, public, parameter :: comprof = 6 + integer, public, parameter :: compwav = 7 + integer, public, parameter :: compglc1 = 8 + integer, public, parameter :: ncomps = 8 character(len=*), public, parameter :: compname(ncomps) = & - (/'med','atm','lnd','ocn','ice','rof','wav','glc'/) + (/'med ',& + 'atm ',& + 'lnd ',& + 'ocn ',& + 'ice ',& + 'rof ',& + 'wav ',& + 'glc '/) + + integer, public, parameter :: max_icesheets = 1 + integer, public :: compglc(max_icesheets) = (/compglc1/) + integer, public :: num_icesheets = 1 + logical, public :: ocn2glc_coupling ! obtained from attribute !----------------------------------------------- ! Set mappers @@ -36,10 +48,10 @@ module esmflds integer , public, parameter :: mapnstod_consd = 7 ! nearest source to destination followed by conservative dst integer , public, parameter :: mapnstod_consf = 8 ! nearest source to destination followed by conservative frac integer , public, parameter :: mappatch_uv3d = 9 ! rotate u,v to 3d cartesian space, map from src->dest, then rotate back - integer , public, parameter :: map_glc2ocn_ice = 10 ! custom smoothing map to map ice from glc->ocn (cesm only) - integer , public, parameter :: map_glc2ocn_liq = 11 ! custom smoothing map to map liq from glc->ocn (cesm only) - integer , public, parameter :: map_rof2ocn_ice = 12 ! custom smoothing map to map ice from rof->ocn (cesm only) - integer , public, parameter :: map_rof2ocn_liq = 13 ! custom smoothing map to map liq from rof->ocn (cesm only) + integer , public, parameter :: map_rof2ocn_ice = 10 ! custom smoothing map to map ice from rof->ocn (cesm only) + integer , public, parameter :: map_rof2ocn_liq = 11 ! custom smoothing map to map liq from rof->ocn (cesm only) + integer , public, parameter :: map_glc2ocn_liq = 12 ! custom smoothing map to map liq from glc->ocn (cesm only) + integer , public, parameter :: map_glc2ocn_ice = 13 ! custom smoothing map to map ice from glc->ocn (cesm only) integer , public, parameter :: nmappers = 13 character(len=*) , public, parameter :: mapnames(nmappers) = & @@ -52,10 +64,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 @@ -211,43 +223,25 @@ end subroutine med_fldList_AddFld !================================================================================ - subroutine med_fldList_AddMrg(flds, fldname, & - mrg_from1, mrg_fld1, mrg_type1, mrg_fracname1, & - mrg_from2, mrg_fld2, mrg_type2, mrg_fracname2, & - mrg_from3, mrg_fld3, mrg_type3, mrg_fracname3, & - mrg_from4, mrg_fld4, mrg_type4, mrg_fracname4) + subroutine med_fldList_AddMrg(flds, fldname, mrg_from, mrg_fld, mrg_type, mrg_fracname) ! ---------------------------------------------- ! Determine mrg entry or entries in flds aray ! ---------------------------------------------- - use ESMF, only : ESMF_FAILURE, ESMF_LogWrite - use ESMF, only : ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR + use ESMF, only : ESMF_LogWrite, ESMF_END_ABORT, ESMF_LOGMSG_ERROR, ESMF_Finalize ! input/output variables - type(med_fldList_entry_type) , pointer :: flds(:) - character(len=*) , intent(in) :: fldname - integer , intent(in) , optional :: mrg_from1 - character(len=*) , intent(in) , optional :: mrg_fld1 - character(len=*) , intent(in) , optional :: mrg_type1 - character(len=*) , intent(in) , optional :: mrg_fracname1 - integer , intent(in) , optional :: mrg_from2 - character(len=*) , intent(in) , optional :: mrg_fld2 - character(len=*) , intent(in) , optional :: mrg_type2 - character(len=*) , intent(in) , optional :: mrg_fracname2 - integer , intent(in) , optional :: mrg_from3 - character(len=*) , intent(in) , optional :: mrg_fld3 - character(len=*) , intent(in) , optional :: mrg_type3 - character(len=*) , intent(in) , optional :: mrg_fracname3 - integer , intent(in) , optional :: mrg_from4 - character(len=*) , intent(in) , optional :: mrg_fld4 - character(len=*) , intent(in) , optional :: mrg_type4 - character(len=*) , intent(in) , optional :: mrg_fracname4 + type(med_fldList_entry_type) , pointer :: flds(:) + character(len=*) , intent(in) :: fldname + integer , intent(in) :: mrg_from + character(len=*) , intent(in) :: mrg_fld + character(len=*) , intent(in) :: mrg_type + character(len=*) , intent(in), optional :: mrg_fracname ! local variables integer :: n, id - integer :: rc - character(len=*), parameter :: subname='(med_fldList_MrgFld)' + character(len=*), parameter :: subname='(med_fldList_AddMrg)' ! ---------------------------------------------- id = 0 @@ -261,42 +255,15 @@ subroutine med_fldList_AddMrg(flds, fldname, & do n = 1,size(flds) write(6,*) trim(subname)//' input flds entry is ',trim(flds(n)%stdname) end do - call ESMF_LogWrite(subname // 'ERROR: fldname '// trim(fldname) // ' not found in input flds', ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - return + call ESMF_LogWrite(subname // 'ERROR: fldname '// trim(fldname) // ' not found in input flds', ESMF_LOGMSG_ERROR) + call ESMF_Finalize(endflag=ESMF_END_ABORT) end if - if (present(mrg_from1) .and. present(mrg_fld1) .and. present(mrg_type1)) then - n = mrg_from1 - flds(id)%merge_fields(n) = mrg_fld1 - flds(id)%merge_types(n) = mrg_type1 - if (present(mrg_fracname1)) then - flds(id)%merge_fracnames(n) = mrg_fracname1 - end if - end if - if (present(mrg_from2) .and. present(mrg_fld2) .and. present(mrg_type2)) then - n = mrg_from2 - flds(id)%merge_fields(n) = mrg_fld2 - flds(id)%merge_types(n) = mrg_type2 - if (present(mrg_fracname2)) then - flds(id)%merge_fracnames(n) = mrg_fracname2 - end if - end if - if (present(mrg_from3) .and. present(mrg_fld3) .and. present(mrg_type3)) then - n = mrg_from3 - flds(id)%merge_fields(n) = mrg_fld3 - flds(id)%merge_types(n) = mrg_type3 - if (present(mrg_fracname3)) then - flds(id)%merge_fracnames(n) = mrg_fracname3 - end if - end if - if (present(mrg_from4) .and. present(mrg_fld4) .and. present(mrg_type4)) then - n = mrg_from4 - flds(id)%merge_fields(n) = mrg_fld4 - flds(id)%merge_types(n) = mrg_type4 - if (present(mrg_fracname4)) then - flds(id)%merge_fracnames(n) = mrg_fracname4 - end if + n = mrg_from + flds(id)%merge_fields(n) = mrg_fld + flds(id)%merge_types(n) = mrg_type + if (present(mrg_fracname)) then + flds(id)%merge_fracnames(n) = mrg_fracname end if end subroutine med_fldList_AddMrg @@ -373,9 +340,11 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num use ESMF , only : ESMF_StateGet, ESMF_LogFoundError use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_ERROR, ESMF_FAILURE, ESMF_LOGERR_PASSTHRU use ESMF , only : ESMF_LOGMSG_INFO, ESMF_StateRemove, ESMF_SUCCESS -#if ESMF_VERSION_MINOR > 0 +#if ESMF_VERSION_MAJOR >= 8 +#if ESMF_VERSION_MINOR > 0 use ESMF , only : ESMF_STATEINTENT_IMPORT, ESMF_STATEINTENT_EXPORT, ESMF_StateIntent_Flag use ESMF , only : ESMF_RC_ARG_BAD, ESMF_LogSetError, operator(==) +#endif #endif ! input/output variables type(ESMF_State) , intent(inout) :: state @@ -393,9 +362,11 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num type(ESMF_Field) :: field character(CS) :: shortname character(CS) :: stdname -#if ESMF_VERSION_MINOR > 0 - type(ESMF_StateIntent_Flag) :: stateIntent character(ESMF_MAXSTR) :: transferActionAttr +#if ESMF_VERSION_MAJOR >= 8 +#if ESMF_VERSION_MINOR > 0 + type(ESMF_StateIntent_Flag) :: stateIntent +#endif #endif character(ESMF_MAXSTR) :: transferAction character(ESMF_MAXSTR), pointer :: StandardNameList(:) => null() @@ -460,7 +431,9 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num #endif nflds = size(fldList%flds) -#if ESMF_VERSION_MINOR > 0 + transferActionAttr="TransferActionGeomObject" +#if ESMF_VERSION_MAJOR >= 8 +#if ESMF_VERSION_MINOR > 0 call ESMF_StateGet(state, stateIntent=stateIntent, rc=rc) if (stateIntent==ESMF_STATEINTENT_EXPORT) then transferActionAttr="ProducerTransferAction" @@ -474,6 +447,7 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num rcToReturn=rc) return ! bail out endif +#endif #endif do n = 1, nflds @@ -484,12 +458,8 @@ subroutine med_fldList_Realize(state, fldList, flds_scalar_name, flds_scalar_num call ESMF_StateGet(state, field=field, itemName=trim(shortname), rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return -#if ESMF_VERSION_MINOR > 0 - call NUOPC_GetAttribute(field, name=TransferActionAttr, value=transferAction, rc=rc) -#else - call NUOPC_GetAttribute(field, name="TransferActionGeomObject", value=transferAction, rc=rc) -#endif + call NUOPC_GetAttribute(field, name=TransferActionAttr, value=transferAction, rc=rc) if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=u_FILE_u)) return if (trim(transferAction) == "accept") then ! accept diff --git a/mediator/esmFldsExchange_cesm_mod.F90 b/mediator/esmFldsExchange_cesm_mod.F90 index 1040f6c46..3d082892e 100644 --- a/mediator/esmFldsExchange_cesm_mod.F90 +++ b/mediator/esmFldsExchange_cesm_mod.F90 @@ -19,7 +19,8 @@ module esmFldsExchange_cesm_mod ! mappings between the atm and ocn needed for these computations. !-------------------------------------- - use med_kind_mod, only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 + 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 : logunit, mastertask implicit none public @@ -44,9 +45,9 @@ module esmFldsExchange_cesm_mod character(len=CX) :: wav2ocn_smap='unset' logical :: mapuv_with_cart3d logical :: flds_i2o_per_cat - logical :: flds_co2a - logical :: flds_co2b - logical :: flds_co2c + logical :: flds_co2a + logical :: flds_co2b + logical :: flds_co2c character(*), parameter :: u_FILE_u = & __FILE__ @@ -67,7 +68,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) use esmFlds , only : addmap => med_fldList_AddMap use esmFlds , only : addmrg => med_fldList_AddMrg use esmflds , only : compmed, compatm, complnd, compocn - use esmflds , only : compice, comprof, compwav, compglc, ncomps + use esmflds , only : compice, comprof, compwav, ncomps + use esmflds , only : compglc, num_icesheets, ocn2glc_coupling ! compglc is an array of integers use esmflds , only : mapbilnr, mapconsf, mapconsd, mappatch, mappatch_uv3d use esmflds , only : mapfcopy, mapnstod, mapnstod_consd, mapnstod_consf use esmflds , only : map_glc2ocn_ice, map_glc2ocn_liq, map_rof2ocn_ice, map_rof2ocn_liq @@ -81,7 +83,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! local variables: type(InternalState) :: is_local - integer :: n + integer :: n, ns + logical :: is_lnd, is_glc character(len=5) :: iso(2) character(len=CL) :: cvalue character(len=CS) :: name, fldname @@ -148,12 +151,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) @@ -162,27 +168,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) @@ -227,14 +241,25 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call NUOPC_CompAttributeGet(gcomp, name='flds_co2c', value=cvalue, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return read(cvalue,*) flds_co2c - if (mastertask) write(logunit,'(a)') trim(subname)//' flds_co2a = '// trim(cvalue) - if (mastertask) write(logunit,'(a)') trim(subname)//' flds_co2b = '// trim(cvalue) - if (mastertask) write(logunit,'(a)') trim(subname)//' flds_co2c = '// trim(cvalue) + ! are multiple ice categories being sent from the ice and ocn? call NUOPC_CompAttributeGet(gcomp, name='flds_i2o_per_cat', value=cvalue, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return read(cvalue,*) flds_i2o_per_cat - call ESMF_LogWrite('flds_i2o_per_cat = '// trim(cvalue), ESMF_LOGMSG_INFO) + + ! are multiple ocean depths for temperature and salinity sent from the ocn to glc? + call NUOPC_CompAttributeGet(gcomp, name='ocn2glc_coupling', value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) ocn2glc_coupling + + ! write diagnostic output + if (mastertask) then + write(logunit,'(a)') trim(subname)//' flds_co2a = '// trim(cvalue) + write(logunit,'(a)') trim(subname)//' flds_co2b = '// trim(cvalue) + write(logunit,'(a)') trim(subname)//' flds_co2c = '// trim(cvalue) + write(logunit,'(a)') trim(subname)//' flds_i2o_per_cat = '// trim(cvalue) + write(logunit,'(a)') trim(subname)//' ocn2glc_coupling = '// trim(cvalue) + end if end if @@ -262,6 +287,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(complnd)%flds, 'Sl_lfrin') call addfld(fldListFr(compocn)%flds, 'So_omask') call addfld(fldListFr(compice)%flds, 'Si_imask') + do ns = 1,num_icesheets + call addfld(fldlistFr(compglc(ns))%flds, 'Sg_area') + end do else call addmap(fldListFr(compocn)%flds, 'So_omask', compice, mapfcopy, 'unset', 'unset') end if @@ -339,8 +367,15 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! --------------------------------------------------------------------- allocate(flds(9)) - flds = (/'Sa_z ', 'Sa_topo ', 'Sa_u ', 'Sa_v ', 'Sa_tbot ', & - 'Sa_ptem ', 'Sa_pbot ', 'Sa_shum ', 'Sa_shum_wiso'/) + flds = (/'Sa_z ',& + 'Sa_topo ',& + 'Sa_u ',& + 'Sa_v ',& + 'Sa_tbot ',& + 'Sa_ptem ',& + 'Sa_pbot ',& + 'Sa_shum ',& + 'Sa_shum_wiso'/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -350,9 +385,10 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else if ( fldchk(is_local%wrap%FBexp(complnd) , trim(fldname), rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm ), trim(fldname), rc=rc)) then - call addmap(fldListFr(compatm)%flds, trim(fldname), complnd, mapbilnr, 'one', atm2lnd_smap) + call addmap(fldListFr(compatm)%flds, trim(fldname), & + complnd, mapbilnr, 'one', atm2lnd_smap) call addmrg(fldListTo(complnd)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -384,9 +420,20 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! TODO (mvertens, 2019-03-10): add water isotopes from atm allocate(flds(14)) - flds = (/'Faxa_rainc ', 'Faxa_rainl ', 'Faxa_snowc ', 'Faxa_snowl ', & - 'Faxa_lwdn ', 'Faxa_swndr ', 'Faxa_swvdr ', 'Faxa_swndf ', 'Faxa_swvdf ', & - 'Faxa_bcph ', 'Faxa_ocph ', 'Faxa_dstwet', 'Faxa_dstdry', 'Faxa_ndep ' /) + flds = (/'Faxa_rainc ',& + 'Faxa_rainl ',& + 'Faxa_snowc ',& + 'Faxa_snowl ',& + 'Faxa_lwdn ',& + 'Faxa_swndr ',& + 'Faxa_swvdr ',& + 'Faxa_swndf ',& + 'Faxa_swvdf ',& + 'Faxa_bcph ',& + 'Faxa_ocph ',& + 'Faxa_dstwet',& + 'Faxa_dstdry',& + 'Faxa_ndep ' /) do n = 1,size(flds) fldname = trim(flds(n)) @@ -394,11 +441,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListFr(compatm)%flds, trim(fldname)) call addfld(fldListTo(complnd)%flds, trim(fldname)) else - if ( fldchk(is_local%wrap%FBexp(complnd) , trim(fldname), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compatm,compatm ), trim(fldname), rc=rc)) then - call addmap(fldListFr(compatm)%flds, trim(fldname), complnd, mapconsf, 'one', atm2lnd_fmap) + if (fldchk(is_local%wrap%FBexp(complnd) , trim(fldname), rc=rc) .and. & + fldchk(is_local%wrap%FBImp(compatm,compatm ), trim(fldname), rc=rc)) then + call addmap(fldListFr(compatm)%flds, trim(fldname), & + complnd, mapconsf, 'one', atm2lnd_fmap) call addmrg(fldListTo(complnd)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -410,8 +458,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! to lnd: river water flux back to land due to flooding ! --------------------------------------------------------------------- allocate(flds(6)) - flds = (/'Flrr_volr ', 'Flrr_volr_wiso ', 'Flrr_volrmch ', & - 'Flrr_volrmch_wiso', 'Flrr_flood ', 'Flrr_flood_wiso '/) + flds = (/'Flrr_volr ',& + 'Flrr_volr_wiso ',& + 'Flrr_volrmch ',& + 'Flrr_volrmch_wiso',& + 'Flrr_flood ',& + 'Flrr_flood_wiso '/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -421,9 +473,10 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else if ( fldchk(is_local%wrap%FBExp(complnd) , trim(fldname), rc=rc) .and. & fldchk(is_local%wrap%FBImp(comprof, comprof), trim(fldname), rc=rc)) then - call addmap(fldListFr(comprof)%flds, trim(fldname), complnd, mapconsf, 'one', rof2lnd_fmap) + call addmap(fldListFr(comprof)%flds, trim(fldname), & + complnd, mapconsf, 'one', rof2lnd_fmap) call addmrg(fldListTo(complnd)%flds, trim(fldname), & - mrg_from1=comprof, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=comprof, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -434,52 +487,42 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! to lnd: ice sheet mask where we are potentially sending non-zero fluxes from glc ! to lnd: fields with multiple elevation classes from glc ! --------------------------------------------------------------------- - allocate(flds(2)) - flds = (/'Sg_icemask ', 'Sg_icemask_coupled_fluxes'/) - - do n = 1,size(flds) - fldname = trim(flds(n)) - if (phase == 'advertise') then - call addfld(fldListFr(compglc)%flds , trim(fldname)) - call addfld(fldListTo(complnd)%flds , trim(fldname)) - else - if ( fldchk(is_local%wrap%FBExp(complnd) , trim(fldname), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compglc, compglc), trim(fldname), rc=rc)) then - call addmap(fldListFr(compglc)%flds, trim(fldname), complnd, mapconsd, 'one', glc2lnd_smap) - call addmrg(fldListTo(complnd)%flds, trim(fldname), & - mrg_from1=compglc, mrg_fld1=trim(fldname), mrg_type1='copy') - end if - end if - end do - deallocate(flds) - ! for glc fields with multiple elevation classes in glc->lnd - ! fields from glc->med do NOT have elevation classes - ! fields from med->lnd are BROKEN into multiple elevation classes + ! The suffix _elev on land fields designates fields with elevation classes + ! fields from glc->med do not have elevation classes whereas + ! fields from med->lnd are in multiple elevation classes if (phase == 'advertise') then - call addfld(fldListFr(compglc)%flds, 'Sg_ice_covered') ! fraction of glacier area - call addfld(fldListFr(compglc)%flds, 'Sg_topo') ! surface height of glacer - call addfld(fldListFr(compglc)%flds, 'Flgg_hflx') ! downward heat flux from glacier interior - + do ns = 1, num_icesheets + call addfld(fldListFr(compglc(ns))%flds, 'Sg_icemask') ! ice sheet grid coverage + call addfld(fldListFr(compglc(ns))%flds, 'Sg_icemask_coupled_fluxes') + call addfld(fldListFr(compglc(ns))%flds, 'Sg_ice_covered') ! fraction of glacier area + call addfld(fldListFr(compglc(ns))%flds, 'Sg_topo') ! surface height of glacer + call addfld(fldListFr(compglc(ns))%flds, 'Flgg_hflx') ! downward heat flux from glacier interior + end do + call addfld(fldListTo(complnd)%flds, 'Sg_icemask') + call addfld(fldListTo(complnd)%flds, 'Sg_icemask_coupled_fluxes') call addfld(fldListTo(complnd)%flds, 'Sg_ice_covered_elev') call addfld(fldListTo(complnd)%flds, 'Sg_topo_elev') call addfld(fldListTo(complnd)%flds, 'Flgg_hflx_elev') else - if ( fldchk(is_local%wrap%FBExp(complnd) , 'Sg_ice_covered_elev', rc=rc) .and. & - fldchk(is_local%wrap%FBExp(complnd) , 'Sg_topo_elev' , rc=rc) .and. & - fldchk(is_local%wrap%FBExp(complnd) , 'Flgg_hflx_elev' , rc=rc) .and. & - - fldchk(is_local%wrap%FBImp(compglc,compglc) , 'Sg_ice_covered' , rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compglc,compglc) , 'Sg_topo' , rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compglc,compglc) , 'Flgg_hflx' , rc=rc)) then - - ! Custom merges will be done here - call addmap(FldListFr(compglc)%flds, 'Sg_ice_covered' , complnd, mapconsf, 'unset' , glc2lnd_fmap) - call addmap(FldListFr(compglc)%flds, 'Sg_topo' , compglc, mapconsf, 'custom', glc2lnd_fmap) - call addmap(FldListFr(compglc)%flds, 'Flgg_hflx' , compglc, mapconsf, 'custom', glc2lnd_fmap) - - ! Custom merge in med_phases_prep_lnd + ! custom merge in med_phases_prep_lnd for Sg_icemask and Sg_icemask_coupled_fluxes + ! custom map merge in med_phases_prep_lnd for Sg_ice_covered_elev, Sg_topo_elev and Flgg_hflx_elev + if ( fldchk(is_local%wrap%FBExp(complnd), 'Sg_icemask', rc=rc)) then + do ns = 1, num_icesheets + if (fldchk(is_local%wrap%FBImp(compglc(ns), compglc(ns)), 'Sg_icemask', rc=rc)) then + call addmap(fldListFr(compglc(ns))%flds, 'Sg_icemask', & + complnd, mapconsd, 'one', 'unset') + end if + end do + end if + if ( fldchk(is_local%wrap%FBExp(complnd), 'Sg_icemask_coupled_fluxes', rc=rc)) then + do ns = 1, num_icesheets + if (fldchk(is_local%wrap%FBImp(compglc(ns), compglc(ns)), 'Sg_icemask_coupled_fluxes', rc=rc)) then + call addmap(fldListFr(compglc(ns))%flds, 'Sg_icemask_coupled_fluxes', & + complnd, mapconsd, 'one', 'unset') + end if + end do end if end if @@ -504,7 +547,10 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! to atm: merged diffuse albedo (near-infrared radiation) ! --------------------------------------------------------------------- allocate(suffix(4)) - suffix = (/'avsdr', 'avsdf', 'anidr', 'anidf'/) + suffix = (/'avsdr',& + 'avsdf',& + 'anidr',& + 'anidf'/) do n = 1,size(suffix) if (phase == 'advertise') then @@ -513,25 +559,27 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListMed_ocnalb%flds , 'So_'//trim(suffix(n))) call addfld(fldListTo(compatm)%flds, 'Sx_'//trim(suffix(n))) else - ! (cam, non-aqua-planet) - if ( fldchk(is_local%wrap%FBexp(compatm) , 'Sx_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(complnd,complnd), 'Sl_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice), 'Si_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBMed_ocnalb_a , 'So_'//trim(suffix(n)), rc=rc)) then - call addmap(fldListFr(complnd)%flds, 'Sl_'//trim(suffix(n)), compatm, mapconsf, 'lfrin', lnd2atm_smap) - call addmap(fldListFr(compice)%flds, 'Si_'//trim(suffix(n)), compatm, mapconsf, 'ifrac', ice2atm_smap) - call addmap(fldListMed_ocnalb%flds , 'So_'//trim(suffix(n)), compatm, mapconsf, 'ofrac', ocn2atm_smap) - call addmrg(fldListTo(compatm)%flds, 'Sx_'//trim(suffix(n)), & - mrg_from1=complnd, mrg_fld1='Sl_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='lfrac', & - mrg_from2=compice, mrg_fld2='Si_'//trim(suffix(n)), mrg_type2='merge', mrg_fracname2='ifrac', & - mrg_from3=compmed, mrg_fld3='So_'//trim(suffix(n)), mrg_type3='merge', mrg_fracname3='ofrac') - - ! (cam, aqua-planet) - else if (fldchk(is_local%wrap%FBMed_ocnalb_a, 'So_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBexp(compatm), 'Sx_'//trim(suffix(n)), rc=rc)) then - call addmap(fldListMed_ocnalb%flds , 'So_'//trim(suffix(n)), compatm, mapconsf, 'ofrac', ocn2atm_smap) - call addmrg(fldListTo(compatm)%flds, 'Sx_'//trim(suffix(n)), & - mrg_from1=compmed, mrg_fld1='So_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ofrac') + if ( fldchk(is_local%wrap%FBexp(compatm), 'Sx_'//trim(suffix(n)), rc=rc)) then + ! Note that for aqua-plant there will be no import from complnd or compice - and the + ! current logic below takes care of this. + if (fldchk(is_local%wrap%FBImp(complnd,complnd), 'Sl_'//trim(suffix(n)), rc=rc)) then + call addmap(fldListFr(complnd)%flds, 'Sl_'//trim(suffix(n)), & + compatm, mapconsf, 'lfrin', lnd2atm_smap) + call addmrg(fldListTo(compatm)%flds, 'Sx_'//trim(suffix(n)), & + mrg_from=complnd, mrg_fld='Sl_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='lfrac') + end if + if (fldchk(is_local%wrap%FBImp(compice,compice), 'Si_'//trim(suffix(n)), rc=rc)) then + call addmap(fldListFr(compice)%flds, 'Si_'//trim(suffix(n)), & + compatm, mapconsf, 'ifrac', ice2atm_smap) + call addmrg(fldListTo(compatm)%flds, 'Sx_'//trim(suffix(n)), & + mrg_from=compice, mrg_fld='Si_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ifrac') + end if + if (fldchk(is_local%wrap%FBMed_ocnalb_a, 'So_'//trim(suffix(n)), rc=rc)) then + call addmap(fldListMed_ocnalb%flds , 'So_'//trim(suffix(n)), & + compatm, mapconsf, 'ofrac', ocn2atm_smap) + call addmrg(fldListTo(compatm)%flds, 'Sx_'//trim(suffix(n)), & + mrg_from=compmed, mrg_fld='So_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ofrac') + end if end if end if end do @@ -544,7 +592,10 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! to atm: merged reference specific water isoptope humidity at 2 meters ! --------------------------------------------------------------------- allocate(suffix(4)) - suffix = (/'tref ', 'u10 ', 'qref ', 'qref_wiso'/) + suffix = (/'tref ',& + 'u10 ',& + 'qref ',& + 'qref_wiso'/) do n = 1,size(suffix) if (phase == 'advertise') then @@ -553,25 +604,23 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListMed_aoflux%flds , 'So_'//trim(suffix(n))) call addfld(fldListTo(compatm)%flds , 'Sx_'//trim(suffix(n))) else - ! (cam, non-aqua-planet) - if ( fldchk(is_local%wrap%FBexp(compatm) , 'Sx_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(complnd,complnd ), 'Sl_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice ), 'Si_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBMed_aoflux_o , 'So_'//trim(suffix(n)), rc=rc)) then - call addmap(fldListFr(complnd)%flds , 'Sl_'//trim(suffix(n)), compatm, mapconsf, 'lfrin', lnd2atm_fmap) - call addmap(fldListFr(compice)%flds , 'Si_'//trim(suffix(n)), compatm, mapconsf, 'ifrac', ice2atm_fmap) - call addmap(fldListMed_aoflux%flds , 'So_'//trim(suffix(n)), compocn, mapbilnr, 'one' , atm2ocn_fmap) ! map atm->ocn - call addmap(fldListMed_aoflux%flds , 'So_'//trim(suffix(n)), compatm, mapconsf, 'ofrac', ocn2atm_fmap) ! map ocn->atm - call addmrg(fldListTo(compatm)%flds , 'Sx_'//trim(suffix(n)), & - mrg_from1=complnd, mrg_fld1='Sl_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='lfrac', & - mrg_from2=compice, mrg_fld2='Si_'//trim(suffix(n)), mrg_type2='merge', mrg_fracname2='ifrac', & - mrg_from3=compmed, mrg_fld3='So_'//trim(suffix(n)), mrg_type3='merge', mrg_fracname3='ofrac') - - ! (cam, aqua-planet) - else if (fldchk(is_local%wrap%FBMed_aoflux_o, 'So_'//trim(suffix(n)), rc=rc)) then - call addmap(fldListMed_aoflux%flds , 'So_'//trim(suffix(n)), compatm, mapconsf, 'ofrac', ocn2atm_fmap) ! map ocn->atm - call addmrg(fldListTo(compatm)%flds, 'Sx_'//trim(suffix(n)), & - mrg_from1=compmed, mrg_fld1='So_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ofrac') + if ( fldchk(is_local%wrap%FBexp(compatm), 'Sx_'//trim(suffix(n)), rc=rc)) then + if (fldchk(is_local%wrap%FBImp(complnd,complnd ), 'Sl_'//trim(suffix(n)), rc=rc)) then + call addmap(fldListFr(complnd)%flds , 'Sl_'//trim(suffix(n)), compatm, mapconsf, 'lfrin', lnd2atm_fmap) + call addmrg(fldListTo(compatm)%flds , 'Sx_'//trim(suffix(n)), & + mrg_from=complnd, mrg_fld='Sl_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='lfrac') + end if + if (fldchk(is_local%wrap%FBImp(compice,compice ), 'Si_'//trim(suffix(n)), rc=rc)) then + call addmap(fldListFr(compice)%flds , 'Si_'//trim(suffix(n)), compatm, mapconsf, 'ifrac', ice2atm_fmap) + call addmrg(fldListTo(compatm)%flds , 'Sx_'//trim(suffix(n)), & + mrg_from=compice, mrg_fld='Si_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ifrac') + end if + if (fldchk(is_local%wrap%FBMed_aoflux_o, 'So_'//trim(suffix(n)), rc=rc)) then + call addmap(fldListMed_aoflux%flds , 'So_'//trim(suffix(n)), compocn, mapbilnr, 'one' , atm2ocn_fmap) ! map atm->ocn + call addmap(fldListMed_aoflux%flds , 'So_'//trim(suffix(n)), compatm, mapconsf, 'ofrac', ocn2atm_fmap) ! map ocn->atm + call addmrg(fldListTo(compatm)%flds , 'Sx_'//trim(suffix(n)), & + mrg_from=compmed, mrg_fld='So_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ofrac') + end if end if end if end do @@ -587,33 +636,37 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! to atm: evaporation water flux from water isotopes ! --------------------------------------------------------------------- allocate(suffix(7)) - suffix = (/'taux ', 'tauy ', 'lat ', 'sen ', 'lwup ', 'evap ', 'evap_wiso'/) + suffix = (/'taux ',& + 'tauy ',& + 'lat ',& + 'sen ',& + 'lwup ',& + 'evap ',& + 'evap_wiso'/) do n = 1,size(suffix) if (phase == 'advertise') then - call addfld(fldListMed_aoflux%flds , 'Faox_'//trim(suffix(n))) + call addfld(fldListTo(compatm)%flds, 'Faxx_'//trim(suffix(n))) call addfld(fldListFr(complnd)%flds, 'Fall_'//trim(suffix(n))) call addfld(fldListFr(compice)%flds, 'Faii_'//trim(suffix(n))) - call addfld(fldListTo(compatm)%flds, 'Faxx_'//trim(suffix(n))) + call addfld(fldListMed_aoflux%flds , 'Faox_'//trim(suffix(n))) else - ! CESM (non aqua-planet) - if ( fldchk(is_local%wrap%FBImp(complnd,complnd), 'Fall_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice), 'Faii_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBMed_aoflux_o , 'Faox_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBexp(compatm) , 'Faxx_'//trim(suffix(n)), rc=rc)) then - call addmap(fldListMed_aoflux%flds , 'Faox_'//trim(suffix(n)), compatm, mapconsf, 'ofrac', ocn2atm_fmap) - call addmap(fldListFr(complnd)%flds , 'Fall_'//trim(suffix(n)), compatm, mapconsf, 'lfrin', lnd2atm_fmap) - call addmap(fldListFr(compice)%flds , 'Faii_'//trim(suffix(n)), compatm, mapconsf, 'ifrac', ice2atm_fmap) - call addmrg(fldListTo(compatm)%flds , 'Faxx_'//trim(suffix(n)), & - mrg_from1=complnd, mrg_fld1='Fall_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='lfrac', & - mrg_from2=compice, mrg_fld2='Faii_'//trim(suffix(n)), mrg_type2='merge', mrg_fracname2='ifrac', & - mrg_from3=compmed, mrg_fld3='Faox_'//trim(suffix(n)), mrg_type3='merge', mrg_fracname3='ofrac') - - else if (fldchk(is_local%wrap%FBMed_aoflux_o, 'Faox_'//trim(suffix(n)), rc=rc) .and. & - fldchk(is_local%wrap%FBexp(compatm), 'Faxx_'//trim(suffix(n)), rc=rc)) then - call addmap(fldListMed_aoflux%flds , 'Faox_'//trim(suffix(n)), compatm, mapconsf, 'ofrac', ocn2atm_fmap) - call addmrg(fldListTo(compatm)%flds, 'Faxx_'//trim(suffix(n)), & - mrg_from1=compmed, mrg_fld1='Faox_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ofrac') + if (fldchk(is_local%wrap%FBexp(compatm), 'Faxx_'//trim(suffix(n)), rc=rc)) then + if ( fldchk(is_local%wrap%FBImp(complnd,complnd), 'Fall_'//trim(suffix(n)), rc=rc)) then + call addmap(fldListFr(complnd)%flds , 'Fall_'//trim(suffix(n)), compatm, mapconsf, 'lfrin', lnd2atm_fmap) + call addmrg(fldListTo(compatm)%flds , 'Faxx_'//trim(suffix(n)), & + mrg_from=complnd, mrg_fld='Fall_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='lfrac') + end if + if (fldchk(is_local%wrap%FBImp(compice,compice), 'Faii_'//trim(suffix(n)), rc=rc)) then + call addmap(fldListFr(compice)%flds , 'Faii_'//trim(suffix(n)), compatm, mapconsf, 'ifrac', ice2atm_fmap) + call addmrg(fldListTo(compatm)%flds , 'Faxx_'//trim(suffix(n)), & + mrg_from=compice, mrg_fld='Faii_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ifrac') + end if + if (fldchk(is_local%wrap%FBMed_aoflux_o, 'Faox_'//trim(suffix(n)), rc=rc)) then + call addmap(fldListMed_aoflux%flds , 'Faox_'//trim(suffix(n)), compatm, mapconsf, 'ofrac', ocn2atm_fmap) + call addmrg(fldListTo(compatm)%flds , 'Faxx_'//trim(suffix(n)), & + mrg_from=compmed, mrg_fld='Faox_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ofrac') + end if end if end if end do @@ -629,29 +682,26 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListTo(compatm)%flds, 'So_t') call addfld(fldListTo(compatm)%flds, 'Sx_t') else - ! CESM - merged ocn/ice/lnd temp and unmerged ocn temp - if (fldchk(is_local%wrap%FBexp(compatm) , 'Sx_t', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(complnd,complnd), 'Sl_t', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compice,compice), 'Si_t', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compocn,compocn), 'So_t', rc=rc)) then - call addmap(fldListFr(complnd)%flds, 'Sl_t', compatm, mapconsf , 'lfrin', lnd2atm_fmap) - call addmap(fldListFr(compice)%flds, 'Si_t', compatm, mapconsf , 'ifrac', ice2atm_fmap) - call addmap(fldListFr(compocn)%flds, 'So_t', compatm, mapconsf , 'ofrac', ocn2atm_fmap) - call addmrg(fldListTo(compatm)%flds, 'Sx_t', & - mrg_from1=complnd, mrg_fld1='Sl_t', mrg_type1='merge', mrg_fracname1='lfrac', & - mrg_from2=compice, mrg_fld2='Si_t', mrg_type2='merge', mrg_fracname2='ifrac', & - mrg_from3=compocn, mrg_fld3='So_t', mrg_type3='merge', mrg_fracname3='ofrac') - call addmrg(fldListTo(compatm)%flds, 'So_t', & - mrg_from1=compocn, mrg_fld1='So_t', mrg_type1='copy') - - ! aqua-planet - merged and unmerged ocn temp are the same - else if ( fldchk(is_local%wrap%FBexp(compatm) , 'Sx_t', rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compocn,compocn), 'So_t', rc=rc)) then - call addmap(fldListFr(compocn)%flds, 'So_t', compatm, mapconsf, 'ofrac', ocn2atm_fmap) - call addmrg(fldListTo(compatm)%flds, 'Sx_t', & - mrg_from1=compocn, mrg_fld1='So_t', mrg_type1='merge', mrg_fracname1='ofrac') + if (fldchk(is_local%wrap%FBexp(compatm), 'Sx_t', rc=rc)) then + if (fldchk(is_local%wrap%FBImp(complnd,complnd), 'Sl_t', rc=rc)) then + call addmap(fldListFr(complnd)%flds, 'Sl_t', compatm, mapconsf , 'lfrin', lnd2atm_fmap) + call addmrg(fldListTo(compatm)%flds, 'Sx_t', & + mrg_from=complnd, mrg_fld='Sl_t', mrg_type='merge', mrg_fracname='lfrac') + end if + if (fldchk(is_local%wrap%FBImp(compice,compice), 'Si_t', rc=rc)) then + call addmap(fldListFr(compice)%flds, 'Si_t', compatm, mapconsf , 'ifrac', ice2atm_fmap) + call addmrg(fldListTo(compatm)%flds, 'Sx_t', & + mrg_from=compice, mrg_fld='Si_t', mrg_type='merge', mrg_fracname='ifrac') + end if + if (fldchk(is_local%wrap%FBImp(compocn,compocn), 'So_t', rc=rc)) then + call addmap(fldListFr(compocn)%flds, 'So_t', compatm, mapconsf, 'ofrac', ocn2atm_fmap) + call addmrg(fldListTo(compatm)%flds, 'Sx_t', & + mrg_from=compocn, mrg_fld='So_t', mrg_type='merge', mrg_fracname='ofrac') + end if + end if + if (fldchk(is_local%wrap%FBexp(compatm), 'So_t', rc=rc)) then call addmrg(fldListTo(compatm)%flds, 'So_t', & - mrg_from1=compocn, mrg_fld1='So_t', mrg_type1='copy') + mrg_from=compocn, mrg_fld='So_t', mrg_type='copy') end if end if @@ -661,7 +711,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! to atm: mean snow volume per unit area from ice ! --------------------------------------------------------------------- allocate(flds(3)) - flds = (/'Si_snowh', 'Si_vice ', 'Si_vsno '/) + flds = (/'Si_snowh',& + 'Si_vice ',& + 'Si_vsno '/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -671,9 +723,10 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else if ( fldchk(is_local%wrap%FBexp(compatm) , trim(fldname), rc=rc) .and. & fldchk(is_local%wrap%FBImp(compice,compice), trim(fldname), rc=rc)) then - call addmap(fldListFr(compice)%flds, trim(fldname), compatm, mapconsf , 'ifrac', ice2atm_fmap) + call addmap(fldListFr(compice)%flds, trim(fldname), & + compatm, mapconsf, 'ifrac', ice2atm_fmap) call addmrg(fldListTo(compatm)%flds, trim(fldname), & - mrg_from1=compice, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compice, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -685,7 +738,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! to atm: surface fraction velocity from med aoflux ! --------------------------------------------------------------------- allocate(flds(3)) - flds = (/'So_ssq ', 'So_re ', 'So_ustar'/) + flds = (/'So_ssq ',& + 'So_re ',& + 'So_ustar'/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -695,9 +750,10 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else if ( fldchk(is_local%wrap%FBexp(compatm) , trim(fldname), rc=rc) .and. & fldchk(is_local%wrap%FBMed_aoflux_o , trim(fldname), rc=rc)) then - call addmap(fldListMed_aoflux%flds , trim(fldname), compatm, mapconsf, 'ofrac', ocn2atm_fmap) ! map ocn->atm + call addmap(fldListMed_aoflux%flds , trim(fldname), & + compatm, mapconsf, 'ofrac', ocn2atm_fmap) ! map ocn->atm call addmrg(fldListTo(compatm)%flds , trim(fldname), & - mrg_from1=compmed, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compmed, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -709,7 +765,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! to atm: surface snow water equivalent from land ! --------------------------------------------------------------------- allocate(flds(3)) - flds = (/'Sl_fv ', 'Sl_ram1 ', 'Sl_snowh'/) + flds = (/'Sl_fv ',& + 'Sl_ram1 ',& + 'Sl_snowh'/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -719,9 +777,10 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else if ( fldchk(is_local%wrap%FBexp(compatm) , trim(fldname), rc=rc) .and. & fldchk(is_local%wrap%FBImp(complnd,complnd ), trim(fldname), rc=rc)) then - call addmap(fldListFr(complnd)%flds, trim(fldname), compatm, mapconsf, 'lfrin', lnd2atm_fmap) + call addmap(fldListFr(complnd)%flds, trim(fldname), & + compatm, mapconsf, 'lfrin', lnd2atm_fmap) call addmrg(fldListTo(compatm)%flds, trim(fldname), & - mrg_from1=complnd, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=complnd, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -739,7 +798,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBExp(compatm) , trim(fldname), rc=rc)) then call addmap(fldListFr(complnd)%flds, trim(fldname), compatm, mapconsf, 'lfrin', lnd2atm_fmap) call addmrg(fldListTo(compatm)%flds, trim(fldname), & - mrg_from1=complnd, mrg_fld1=trim(fldname), mrg_type1='copy_with_weights', mrg_fracname1='lfrac') + mrg_from=complnd, mrg_fld=trim(fldname), mrg_type='copy_with_weights', mrg_fracname='lfrac') end if end if @@ -755,7 +814,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBExp(compatm) , trim(fldname), rc=rc)) then call addmap(fldListFr(complnd)%flds, trim(fldname), compatm, mapconsf, 'one', atm2lnd_fmap) call addmrg(fldListTo(compatm)%flds, trim(fldname), & - mrg_from1=complnd, mrg_fld1=trim(fldname), mrg_type1='merge', mrg_fracname1='lfrac') + mrg_from=complnd, mrg_fld=trim(fldname), mrg_type='merge', mrg_fracname='lfrac') end if end if @@ -772,7 +831,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBExp(compatm) , trim(fldname), rc=rc)) then call addmap(fldListFr(complnd)%flds, trim(fldname), compatm, mapconsf, 'one', lnd2atm_fmap) call addmrg(fldListTo(compatm)%flds, trim(fldname), & - mrg_from1=complnd, mrg_fld1=trim(fldname), mrg_type1='merge', mrg_fracname1='lfrac') + mrg_from=complnd, mrg_fld=trim(fldname), mrg_type='merge', mrg_fracname='lfrac') end if end if @@ -786,7 +845,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBExp(compatm) , trim(fldname), rc=rc)) then call addmap(fldListFr(complnd)%flds, trim(fldname), compatm, mapconsf, 'one', lnd2atm_smap) call addmrg(fldListTo(compatm)%flds, trim(fldname), & - mrg_from1=complnd, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=complnd, mrg_fld=trim(fldname), mrg_type='copy') end if end if @@ -802,7 +861,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBExp(compatm) , trim(fldname), rc=rc)) then call addmap(fldListFr(complnd)%flds, trim(fldname), compatm, mapconsf, 'one', lnd2atm_smap) call addmrg(fldListTo(compatm)%flds, trim(fldname), & - mrg_from1=complnd, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=complnd, mrg_fld=trim(fldname), mrg_type='copy') end if end if @@ -818,7 +877,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addfld(fldListTo(compocn)%flds, 'Si_ifrac') else call addmap(fldListFr(compice)%flds, 'Si_ifrac', compocn, mapfcopy, 'unset', 'unset') - call addmrg(fldListTo(compocn)%flds, 'Si_ifrac', mrg_from1=compice, mrg_fld1='Si_ifrac', mrg_type1='copy') + call addmrg(fldListTo(compocn)%flds, 'Si_ifrac', mrg_from=compice, mrg_fld='Si_ifrac', mrg_type='copy') end if ! --------------------------------------------------------------------- @@ -829,7 +888,11 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! to ocn: downward diffuse visible incident solar radiation from atm ! --------------------------------------------------------------------- allocate(flds(5)) - flds = (/'Faxa_lwdn ', 'Faxa_swndr', 'Faxa_swndf', 'Faxa_swvdr', 'Faxa_swvdf'/) + flds = (/'Faxa_lwdn ',& + 'Faxa_swndr',& + 'Faxa_swndf',& + 'Faxa_swvdr',& + 'Faxa_swvdf'/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -840,8 +903,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if ( fldchk(is_local%wrap%FBExp(compocn) , trim(fldname), rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm), trim(fldname), rc=rc)) then call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, mapconsf, 'one', atm2ocn_fmap) - call addmrg(fldListTo(compocn)%flds, trim(fldname), mrg_from1=compatm, mrg_fld1=trim(fldname), & - mrg_type1='copy_with_weights', mrg_fracname1='ofrac') + call addmrg(fldListTo(compocn)%flds, trim(fldname), & + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy_with_weights', mrg_fracname='ofrac') end if end if end do @@ -857,7 +920,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if ( fldchk(is_local%wrap%FBMed_aoflux_o, 'Faox_lwup', rc=rc) .and. & fldchk(is_local%wrap%FBExp(compocn), 'Foxx_lwup', rc=rc)) then call addmrg(fldListTo(compocn)%flds, 'Foxx_lwup', & - mrg_from1=compmed, mrg_fld1='Faox_lwup', mrg_type1='merge', mrg_fracname1='ofrac') + mrg_from=compmed, mrg_fld='Faox_lwup', mrg_type='merge', mrg_fracname='ofrac') end if end if @@ -875,8 +938,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_lwdn' , rc=rc)) then call addmap(fldListFr(compatm)%flds, 'Faxa_lwdn', compocn, mapconsf, 'one' , atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & - mrg_from1=compmed, mrg_fld1='Faox_lwup', mrg_type1='merge', mrg_fracname1='ofrac', & - mrg_from2=compatm, mrg_fld2='Faxa_lwdn', mrg_type2='merge', mrg_fracname2='ofrac') + mrg_from=compmed, mrg_fld='Faox_lwup', mrg_type='merge', mrg_fracname='ofrac') + call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & + mrg_from=compatm, mrg_fld='Faxa_lwdn', mrg_type='merge', mrg_fracname='ofrac') end if end if @@ -891,7 +955,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBExp(compocn) , 'Faxa_swdn', rc=rc)) then call addmap(fldListFr(compatm)%flds, 'Faxa_swdn', compocn, mapconsf, 'one', atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, 'Faxa_swdn', & - mrg_from1=compatm, mrg_fld1='Faxa_swdn', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_swdn', mrg_type='copy') end if end if @@ -971,12 +1035,14 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! 'net shortwave radiation times atmosphere fraction' (computed in med_phases_prep_ocn) call addfld(fldListTo(compocn)%flds, 'Foxx_swnet_afracr') else - call addmap(fldListFr(compice)%flds, 'Si_ifrac_n' , compocn, mapfcopy, 'unset', 'unset') - call addmrg(fldListTo(compocn)%flds, 'Si_ifrac_n', mrg_from1=compice, mrg_fld1='Si_ifrac_n', & - mrg_type1='copy') - call addmap(fldListFr(compice)%flds, 'Fioi_swpen_ifrac_n', compocn, mapfcopy, 'unset', 'unset') - call addmrg(fldListTo(compocn)%flds, 'Fioi_swpen_ifrac_n', mrg_from1=compice, mrg_fld1='Fioi_swpen_ifrac_n', & - mrg_type1='copy') + call addmap(fldListFr(compice)%flds, 'Si_ifrac_n', & + compocn, mapfcopy, 'unset', 'unset') + call addmrg(fldListTo(compocn)%flds, 'Si_ifrac_n', & + mrg_from=compice, mrg_fld='Si_ifrac_n', mrg_type='copy') + call addmap(fldListFr(compice)%flds, 'Fioi_swpen_ifrac_n', & + compocn, mapfcopy, 'unset', 'unset') + call addmrg(fldListTo(compocn)%flds, 'Fioi_swpen_ifrac_n', & + mrg_from=compice, mrg_fld='Fioi_swpen_ifrac_n', mrg_type='copy') ! Note that 'Sf_afrac, 'Sf_afracr' and 'Foxx_swnet_afracr' will have explicit merging in med_phases_prep_ocn end if end if @@ -1017,18 +1083,18 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_rainc'//iso(n), compocn, mapconsf, 'one', atm2ocn_fmap) if (iso(n) == ' ') then call addmrg(fldListTo(compocn)%flds, 'Faxa_rain'//iso(n) , & - mrg_from1=compatm, mrg_fld1='Faxa_rainc:Faxa_rainl', & - mrg_type1='sum_with_weights', mrg_fracname1='ofrac') + mrg_from=compatm, mrg_fld='Faxa_rainc:Faxa_rainl', & + mrg_type='sum_with_weights', mrg_fracname='ofrac') else call addmrg(fldListTo(compocn)%flds, 'Faxa_rain'//iso(n) , & - mrg_from1=compatm, mrg_fld1=trim('Faxa_rainc'//iso(n))//':'//trim('Faxa_rainl'//iso(n)), & - mrg_type1='sum_with_weights', mrg_fracname1='ofrac') + mrg_from=compatm, mrg_fld=trim('Faxa_rainc'//iso(n))//':'//trim('Faxa_rainl'//iso(n)), & + mrg_type='sum_with_weights', mrg_fracname='ofrac') end if else if ( fldchk(is_local%wrap%FBExp(compocn) , 'Faxa_rain'//iso(n), rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rain'//iso(n), rc=rc)) then call addmap(fldListFr(compatm)%flds, 'Faxa_rain'//iso(n), compocn, mapconsf, 'one', atm2ocn_fmap) - call addmrg(fldListTo(compocn)%flds, 'Faxa_rain'//iso(n), mrg_from1=compatm, mrg_fld1='Faxa_rain'//iso(n), & - mrg_type1='copy') + call addmrg(fldListTo(compocn)%flds, 'Faxa_rain'//iso(n), & + mrg_from=compatm, mrg_fld='Faxa_rain'//iso(n), mrg_type='copy') end if if ( fldchk(is_local%wrap%FBExp(compocn) , 'Faxa_snow' //iso(n), rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowl'//iso(n), rc=rc) .and. & @@ -1037,18 +1103,18 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_snowc'//iso(n), compocn, mapconsf, 'one', atm2ocn_fmap) if (iso(n) == ' ') then call addmrg(fldListTo(compocn)%flds, 'Faxa_snow' //iso(n) , & - mrg_from1=compatm, mrg_fld1='Faxa_snowc:Faxa_snowl', & - mrg_type1='sum_with_weights', mrg_fracname1='ofrac') + mrg_from=compatm, mrg_fld='Faxa_snowc:Faxa_snowl', & + mrg_type='sum_with_weights', mrg_fracname='ofrac') else call addmrg(fldListTo(compocn)%flds, 'Faxa_snow' //iso(n) , & - mrg_from1=compatm, mrg_fld1=trim('Faxa_snowc'//iso(n))//':'//trim('Faxa_snowl'//iso(n)), & - mrg_type1='sum_with_weights', mrg_fracname1='ofrac') + mrg_from=compatm, mrg_fld=trim('Faxa_snowc'//iso(n))//':'//trim('Faxa_snowl'//iso(n)), & + mrg_type='sum_with_weights', mrg_fracname='ofrac') end if else if ( fldchk(is_local%wrap%FBExp(compocn) , 'Faxa_snow'//iso(n), rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snow'//iso(n), rc=rc)) then call addmap(fldListFr(compatm)%flds, 'Faxa_snow'//iso(n), compocn, mapconsf, 'one', atm2ocn_fmap) - call addmrg(fldListTo(compocn)%flds, 'Faxa_snow'//iso(n), mrg_from1=compatm, mrg_fld1='Faxa_snow'//iso(n), & - mrg_type1='copy') + call addmrg(fldListTo(compocn)%flds, 'Faxa_snow'//iso(n), & + mrg_from=compatm, mrg_fld='Faxa_snow'//iso(n), mrg_type='copy') end if end do end if @@ -1065,7 +1131,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if ( fldchk(is_local%wrap%FBexp(compocn), 'Foxx_sen', rc=rc) .and. & fldchk(is_local%wrap%FBMed_aoflux_o, 'Faox_sen', rc=rc)) then call addmrg(fldListTo(compocn)%flds, 'Foxx_sen', & - mrg_from1=compmed, mrg_fld1='Faox_sen', mrg_type1='merge', mrg_fracname1='ofrac') + mrg_from=compmed, mrg_fld='Faox_sen', mrg_type='merge', mrg_fracname='ofrac') end if end if @@ -1083,12 +1149,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if ( fldchk(is_local%wrap%FBexp(compocn), 'Foxx_lat', rc=rc) .and. & fldchk(is_local%wrap%FBMed_aoflux_o, 'Faox_lat', rc=rc)) then call addmrg(fldListTo(compocn)%flds, 'Foxx_lat', & - mrg_from1=compmed, mrg_fld1='Faox_lat', mrg_type1='merge', mrg_fracname1='ofrac') + mrg_from=compmed, mrg_fld='Faox_lat', mrg_type='merge', mrg_fracname='ofrac') end if if ( fldchk(is_local%wrap%FBExp(compocn), 'Foxx_evap', rc=rc) .and. & fldchk(is_local%wrap%FBMed_aoflux_o, 'Faox_evap', rc=rc)) then call addmrg(fldListTo(compocn)%flds, 'Foxx_evap', & - mrg_from1=compmed, mrg_fld1='Faox_evap', mrg_type1='merge', mrg_fracname1='ofrac') + mrg_from=compmed, mrg_fld='Faox_evap', mrg_type='merge', mrg_fracname='ofrac') end if end if @@ -1099,7 +1165,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if ( fldchk(is_local%wrap%FBexp(compocn), 'Foxx_lat_wiso', rc=rc) .and. & fldchk(is_local%wrap%FBMed_aoflux_o, 'Faox_lat_wiso', rc=rc)) then call addmrg(fldListTo(compocn)%flds, 'Foxx_lat_wiso', & - mrg_from1=compmed, mrg_fld1='Faox_lat_wiso', mrg_type1='merge', mrg_fracname1='ofrac') + mrg_from=compmed, mrg_fld='Faox_lat_wiso', mrg_type='merge', mrg_fracname='ofrac') end if end if @@ -1115,7 +1181,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListMed_aoflux%flds , 'So_duu10n', compatm, mapconsf, 'ofrac', ocn2atm_fmap) ! map ocn->atm call addmrg(fldListTo(compocn)%flds, 'So_duu10n', & - mrg_from1=compmed, mrg_fld1='So_duu10n', mrg_type1='copy') + mrg_from=compmed, mrg_fld='So_duu10n', mrg_type='copy') end if end if @@ -1133,7 +1199,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Sa_pslv', compice, mapbilnr, 'one', atm2ocn_smap) call addmrg(fldListTo(compocn)%flds, 'Sa_pslv', & - mrg_from1=compatm, mrg_fld1='Sa_pslv', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_pslv', mrg_type='copy') end if end if @@ -1163,7 +1229,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBExp(compocn) , trim(fldname), rc=rc)) then call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, mapconsf, 'one', atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy_with_weights', mrg_fracname1='ofrac') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy_with_weights', mrg_fracname='ofrac') end if end if end do @@ -1186,8 +1252,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBMed_aoflux_o, 'Faox_'//trim(suffix(n)), rc=rc)) then call addmap(fldListFr(compice)%flds, 'Fioi_'//trim(suffix(n)), compocn, mapfcopy, 'unset', 'unset') call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(suffix(n)), & - mrg_from1=compmed, mrg_fld1='Faox_'//trim(suffix(n)), mrg_type1='merge', mrg_fracname1='ofrac', & - mrg_from2=compice, mrg_fld2='Fioi_'//trim(suffix(n)), mrg_type2='merge', mrg_fracname2='ifrac') + mrg_from=compmed, mrg_fld='Faox_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ofrac') + call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(suffix(n)), & + mrg_from=compice, mrg_fld='Fioi_'//trim(suffix(n)), mrg_type='merge', mrg_fracname='ifrac') end if end if end do @@ -1205,7 +1272,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBImp(compice, compice), 'Fioi_meltw'//iso(n), rc=rc)) then call addmap(fldListFr(compice)%flds, 'Fioi_meltw'//iso(n), compocn, mapfcopy, 'unset', 'unset') call addmrg(fldListTo(compocn)%flds, 'Fioi_meltw'//iso(n), & - mrg_from1=compice, mrg_fld1='Fioi_meltw'//iso(n), mrg_type1='copy_with_weights', mrg_fracname1='ifrac') + mrg_from=compice, mrg_fld='Fioi_meltw'//iso(n), mrg_type='copy_with_weights', mrg_fracname='ifrac') end if end if end do @@ -1221,7 +1288,11 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! Is fd.yaml correctly aliasing Fioi_melth? allocate(flds(5)) - flds = (/'Fioi_melth ', 'Fioi_salt ', 'Fioi_bcphi ', 'Fioi_bcpho ', 'Fioi_flxdst'/) + flds = (/'Fioi_melth ',& + 'Fioi_salt ',& + 'Fioi_bcphi ',& + 'Fioi_bcpho ',& + 'Fioi_flxdst'/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -1233,7 +1304,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBImp(compice, compice), trim(fldname), rc=rc)) then call addmap(fldListFr(compice)%flds, trim(fldname), compocn, mapfcopy, 'unset', 'unset') call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compice, mrg_fld1=trim(fldname), mrg_type1='copy_with_weights', mrg_fracname1='ifrac') + mrg_from=compice, mrg_fld=trim(fldname), mrg_type='copy_with_weights', mrg_fracname='ifrac') end if end if end do @@ -1250,88 +1321,64 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! Note that Flrr_flood below needs to be added to ! fldlistFr(comprof) in order to be mapped correctly but the ocean ! does not receive it so it is advertised but it will! not be connected - - call addfld(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n)) - call addfld(fldListFr(compglc)%flds, 'Fogg_rofi'//iso(n)) + do ns = 1, num_icesheets + call addfld(fldListFr(compglc(ns))%flds, 'Fogg_rofl'//iso(n)) + end do call addfld(fldListFr(comprof)%flds, 'Forr_rofl'//iso(n)) - call addfld(fldListFr(comprof)%flds, 'Forr_rofi'//iso(n)) call addfld(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n)) - call addfld(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n)) call addfld(fldListTo(compocn)%flds, 'Flrr_flood'//iso(n)) + do ns = 1, num_icesheets + call addfld(fldListFr(compglc(ns))%flds, 'Fogg_rofi'//iso(n)) + end do + call addfld(fldListFr(comprof)%flds, 'Forr_rofi'//iso(n)) + call addfld(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n)) end do else do n = 1,size(iso) - ! liquid runoff from rof, flood and glc to ocn - if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_rofl'//iso(n) , rc=rc) .and. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofl'//iso(n) , rc=rc) .and. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Flrr_flood'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compglc, compglc), 'Fogg_rofl'//iso(n) , rc=rc)) then - call addmap(fldListFr(comprof)%flds, 'Forr_rofl'//iso(n) , compocn, map_rof2ocn_liq, 'none', rof2ocn_liq_rmap) - call addmap(fldListFr(comprof)%flds, 'Flrr_flood'//iso(n), compocn, mapconsd , 'one' , rof2ocn_fmap) - call addmap(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n) , compocn, map_glc2ocn_liq, 'one' , glc2ocn_liq_rmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & - mrg_from1=comprof, mrg_fld1='Forr_rofl:Flrr_flood', mrg_type1='sum', & - mrg_from2=compglc, mrg_fld2='Fogg_rofl'//iso(n) , mrg_type2='sum') - ! liquid runoff from both rof and glc to ocn - else if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_rofl'//iso(n) , rc=rc) .and. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofl'//iso(n) , rc=rc) .and. .not. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Flrr_flood'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compglc, compglc), 'Fogg_rofl'//iso(n) , rc=rc)) then - call addmap(fldListFr(comprof)%flds, 'Forr_rofl'//iso(n), compocn, map_rof2ocn_liq, 'none', rof2ocn_liq_rmap) - call addmap(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n), compocn, map_glc2ocn_liq, 'one' , glc2ocn_liq_rmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & - mrg_from1=comprof, mrg_fld1='Forr_rofl' , mrg_type1='sum', & - mrg_from2=compglc, mrg_fld2='Fogg_rofl'//iso(n), mrg_type2='sum') - ! liquid runoff from rof and flood to ocn - else if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_rofl'//iso(n) , rc=rc) .and. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofl'//iso(n) , rc=rc) .and. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Flrr_flood'//iso(n), rc=rc) .and. .not. & - fldchk(is_local%wrap%FBImp(compglc, compglc), 'Fogg_rofl'//iso(n) , rc=rc)) then - call addmap(fldListFr(comprof)%flds, 'Flrr_flood'//iso(n), compocn, mapconsf , 'one' , rof2ocn_fmap) - call addmap(fldListFr(comprof)%flds, 'Forr_rofl' //iso(n), compocn, map_rof2ocn_liq, 'none', rof2ocn_liq_rmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl' //iso(n), & - mrg_from1=comprof, mrg_fld1='Forr_rofl:Flrr_flood', mrg_type1='sum') - ! liquid from just rof to ocn - else if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_rofl'//iso(n) , rc=rc) .and. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofl'//iso(n) , rc=rc) .and. .not. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Flrr_flood'//iso(n), rc=rc) .and. .not. & - fldchk(is_local%wrap%FBImp(compglc, compglc), 'Fogg_rofl'//iso(n) , rc=rc)) then - call addmap(fldListFr(comprof)%flds, 'Forr_rofl'//iso(n), compocn, mapconsf, 'none', rof2ocn_liq_rmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & - mrg_from1=comprof, mrg_fld1='Forr_rofl', mrg_type1='copy') - ! liquid runoff from just glc to ocn - else if ( .not. fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_rofl'//iso(n) , rc=rc) .and. & - .not. fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofl'//iso(n) , rc=rc) .and. & - .not. fldchk(is_local%wrap%FBImp(comprof, comprof), 'Flrr_flood'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compglc, compglc), 'Fogg_rofl'//iso(n) , rc=rc)) then - else if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_rofl'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compglc, compglc), 'Fogg_rofl'//iso(n), rc=rc)) then - call addmap(fldListFr(compglc)%flds, 'Fogg_rofl'//iso(n), compocn, mapconsf, 'one', glc2ocn_liq_rmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & - mrg_from1=compglc, mrg_fld1='Fogg_rofl'//iso(n), mrg_type1='copy') + if ( fldchk(is_local%wrap%FBExp(compocn), 'Foxx_rofl'//iso(n) , rc=rc)) then + ! liquid from river and possibly flood from river to ocean + if (fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofl'//iso(n) , rc=rc)) then + call addmap(fldListFr(comprof)%flds, 'Forr_rofl'//iso(n), & + compocn, map_rof2ocn_liq, 'none', rof2ocn_liq_rmap) + if (fldchk(is_local%wrap%FBImp(comprof, comprof), 'Flrr_flood'//iso(n), rc=rc)) then + call addmap(fldListFr(comprof)%flds, 'Flrr_flood'//iso(n), & + compocn, mapconsd, 'one', rof2ocn_fmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & + mrg_from=comprof, mrg_fld='Forr_rofl:Flrr_flood', mrg_type='sum') + else + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & + mrg_from=comprof, mrg_fld='Forr_rofl', mrg_type='sum') + end if + end if + ! liquid from glc to ocean + do ns = 1, num_icesheets + if (fldchk(is_local%wrap%FBImp(compglc(ns), compglc(ns)), 'Fogg_rofl'//iso(n) , rc=rc)) then + ! TODO: this custom map needs to be different for every ice sheet - how will this be handled? + call addmap(fldListFr(compglc(ns))%flds, 'Fogg_rofl'//iso(n), & + compocn, map_glc2ocn_liq, 'one' , glc2ocn_liq_rmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofl'//iso(n), & + mrg_from=compglc(ns), mrg_fld='Fogg_rofl'//iso(n), mrg_type='sum') + end if + end do end if - - ! ice runoff from both rof and glc to ocn - if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_rofi'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofi'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compglc, compglc), 'Fogg_rofi'//iso(n), rc=rc)) then - call addmap(fldListFr(comprof)%flds, 'Forr_rofi'//iso(n), compocn, map_rof2ocn_ice, 'none', rof2ocn_ice_rmap) - call addmap(fldListFr(compglc)%flds, 'Fogg_rofi'//iso(n), compocn, map_glc2ocn_ice, 'one' , glc2ocn_ice_rmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n), & - mrg_from1=comprof, mrg_fld1='Forr_rofi'//iso(n), mrg_type1='sum', & - mrg_from2=compglc, mrg_fld2='Fogg_rofi'//iso(n), mrg_type2='sum') - ! ice runoff from just rof to ocn - else if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_rofi'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofi'//iso(n), rc=rc)) then - call addmap(fldListFr(comprof)%flds, 'Forr_rofi'//iso(n), compocn, map_rof2ocn_ice, 'none', rof2ocn_ice_rmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n), & - mrg_from1=comprof, mrg_fld1='Forr_rofi', mrg_type1='copy') - ! ice runoff from just glc to ocn - else if ( fldchk(is_local%wrap%FBExp(compocn) , 'Foxx_rofi'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compglc, compglc), 'Fogg_rofi'//iso(n), rc=rc)) then - call addmap(fldListFr(compglc)%flds, 'Fogg_rofi'//iso(n), compocn, map_glc2ocn_ice, 'one', glc2ocn_ice_rmap) - call addmrg(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n), & - mrg_from1=compglc, mrg_fld1='Fogg_rofi'//iso(n), mrg_type1='copy') + if ( fldchk(is_local%wrap%FBExp(compocn), 'Foxx_rofi'//iso(n) , rc=rc)) then + ! ice from river to ocean + if (fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofi'//iso(n) , rc=rc)) then + call addmap(fldListFr(comprof)%flds, 'Forr_rofi'//iso(n), & + compocn, map_rof2ocn_ice, 'none', rof2ocn_ice_rmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n), & + mrg_from=comprof, mrg_fld='Forr_rofi', mrg_type='sum') + end if + ! ice from glc to ocean + do ns = 1, num_icesheets + if (fldchk(is_local%wrap%FBImp(compglc(ns), compglc(ns)), 'Fogg_rofi'//iso(n) , rc=rc)) then + ! TODO: this custom map needs to be different for every ice sheet - how will this be handled? + call addmap(fldListFr(compglc(ns))%flds, 'Fogg_rofi'//iso(n), & + compocn, map_glc2ocn_ice, 'one', glc2ocn_ice_rmap) + call addmrg(fldListTo(compocn)%flds, 'Foxx_rofi'//iso(n), & + mrg_from=compglc(ns), mrg_fld='Fogg_rofi'//iso(n), mrg_type='sum') + end if + end do end if end do end if @@ -1343,7 +1390,10 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! to ocn: Stokes drift depth from wave !----------------------------- allocate(flds(4)) - flds = (/'Sw_lamult ', 'Sw_ustokes', 'Sw_vstokes', 'Sw_hstokes'/) + flds = (/'Sw_lamult ',& + 'Sw_ustokes',& + 'Sw_vstokes',& + 'Sw_hstokes'/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -1353,9 +1403,10 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else if ( fldchk(is_local%wrap%FBExp(compocn) , trim(fldname), rc=rc) .and. & fldchk(is_local%wrap%FBImp(compwav, compwav), trim(fldname), rc=rc)) then - call addmap(fldListFr(compwav)%flds, trim(fldname), compocn, mapbilnr, 'one', wav2ocn_smap) + call addmap(fldListFr(compwav)%flds, trim(fldname), & + compocn, mapbilnr, 'one', wav2ocn_smap) call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compwav, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compwav, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -1400,7 +1451,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBImp(compatm,compatm), trim(fldname), rc=rc)) then call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mapconsf, 'one', atm2ice_fmap) call addmrg(fldListTo(compice)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -1427,12 +1478,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_rainc', compice, mapconsf, 'one', atm2ice_fmap) call addmap(fldListFr(compatm)%flds, 'Faxa_rainl', compice, mapconsf, 'one', atm2ice_fmap) call addmrg(fldListTo(compice)%flds, 'Faxa_rain' , & - mrg_from1=compatm, mrg_fld1='Faxa_rainc:Faxa_rainl', mrg_type1='sum') + mrg_from=compatm, mrg_fld='Faxa_rainc:Faxa_rainl', mrg_type='sum') else if ( fldchk(is_local%wrap%FBexp(compice) , 'Faxa_rain', rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rain', rc=rc)) then call addmap(fldListFr(compatm)%flds, 'Faxa_rain', compice, mapconsf, 'one', atm2ice_fmap) call addmrg(fldListTo(compice)%flds, 'Faxa_rain', & - mrg_from1=compatm, mrg_fld1='Faxa_rain', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_rain', mrg_type='copy') end if if ( fldchk(is_local%wrap%FBexp(compice) , 'Faxa_rain_wiso' , rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainl_wiso', rc=rc) .and. & @@ -1440,12 +1491,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_rainc_wiso', compice, mapconsf, 'one', atm2ice_fmap) call addmap(fldListFr(compatm)%flds, 'Faxa_rainl_wiso', compice, mapconsf, 'one', atm2ice_fmap) call addmrg(fldListTo(compice)%flds, 'Faxa_rain_wiso' , & - mrg_from1=compatm, mrg_fld1='Faxa_rainc_wiso:Faxa_rainl_wiso', mrg_type1='sum') + mrg_from=compatm, mrg_fld='Faxa_rainc_wiso:Faxa_rainl_wiso', mrg_type='sum') else if ( fldchk(is_local%wrap%FBexp(compice) , 'Faxa_rain_wiso', rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rain_wiso', rc=rc)) then call addmap(fldListFr(compatm)%flds, 'Faxa_rain_wiso', compice, mapconsf, 'one', atm2ice_fmap) call addmrg(fldListTo(compice)%flds, 'Faxa_rain_wiso', & - mrg_from1=compatm, mrg_fld1='Faxa_rain_wiso', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_rain_wiso', mrg_type='copy') end if end if @@ -1466,12 +1517,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_snowc', compice, mapconsf, 'one', atm2ice_fmap) call addmap(fldListFr(compatm)%flds, 'Faxa_snowl', compice, mapconsf, 'one', atm2ice_fmap) call addmrg(fldListTo(compice)%flds, 'Faxa_snow' , & - mrg_from1=compatm, mrg_fld1='Faxa_snowc:Faxa_snowl', mrg_type1='sum') + mrg_from=compatm, mrg_fld='Faxa_snowc:Faxa_snowl', mrg_type='sum') else if ( fldchk(is_local%wrap%FBexp(compice) , 'Faxa_snow', rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snow', rc=rc)) then call addmap(fldListFr(compatm)%flds, 'Faxa_snow', compice, mapconsf, 'one', atm2ice_fmap) call addmrg(fldListTo(compice)%flds, 'Faxa_snow', & - mrg_from1=compatm, mrg_fld1='Faxa_snow', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_snow', mrg_type='copy') end if if ( fldchk(is_local%wrap%FBexp(compice) , 'Faxa_snow_wiso', rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowl_wiso', rc=rc) .and. & @@ -1479,12 +1530,12 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_snowc_wiso', compice, mapconsf, 'one', atm2ice_fmap) call addmap(fldListFr(compatm)%flds, 'Faxa_snowl_wiso', compice, mapconsf, 'one', atm2ice_fmap) call addmrg(fldListTo(compice)%flds, 'Faxa_snow_wiso' , & - mrg_from1=compatm, mrg_fld1='Faxa_snowc_wiso:Faxa_snowl_wiso', mrg_type1='sum') + mrg_from=compatm, mrg_fld='Faxa_snowc_wiso:Faxa_snowl_wiso', mrg_type='sum') else if ( fldchk(is_local%wrap%FBexp(compice) , 'Faxa_snow_wiso', rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snow_wiso', rc=rc)) then call addmap(fldListFr(compatm)%flds, 'Faxa_snow_wiso', compice, mapconsf, 'one', atm2ice_fmap) call addmrg(fldListTo(compice)%flds, 'Faxa_snow_wiso', & - mrg_from1=compatm, mrg_fld1='Faxa_snow_wiso', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_snow_wiso', mrg_type='copy') end if end if @@ -1517,7 +1568,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, trim(fldname), compice, mapbilnr, 'one', atm2ice_smap) end if call addmrg(fldListTo(compice)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -1544,7 +1595,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBImp(compocn,compocn), trim(fldname), rc=rc)) then call addmap(fldListFr(compocn)%flds, trim(fldname), compice, mapfcopy , 'unset', 'unset') call addmrg(fldListTo(compice)%flds, trim(fldname), & - mrg_from1=compocn, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compocn, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -1560,7 +1611,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if ( fldchk(is_local%wrap%FBImp(compocn, compocn), 'Fioo_q', rc=rc) .and. & fldchk(is_local%wrap%FBExp(compice) , 'Fioo_q', rc=rc)) then call addmap(fldListFr(compocn)%flds, 'Fioo_q', compice, mapfcopy, 'unset', 'unset') - call addmrg(fldListTo(compice)%flds, 'Fioo_q', mrg_from1=compocn, mrg_fld1='Fioo_q', mrg_type1='copy') + call addmrg(fldListTo(compice)%flds, 'Fioo_q', & + mrg_from=compocn, mrg_fld='Fioo_q', mrg_type='copy') end if end if @@ -1574,7 +1626,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if ( fldchk(is_local%wrap%FBImp(compocn, compocn), 'So_roce_wiso', rc=rc) .and. & fldchk(is_local%wrap%FBExp(compice) , 'So_roce_wiso', rc=rc)) then call addmap(fldListFr(compocn)%flds, 'So_roce_wiso', compice, mapfcopy, 'unset', 'unset') - call addmrg(fldListTo(compice)%flds, 'So_roce_wiso', mrg_from1=compocn, mrg_fld1='So_roce_wiso', mrg_type1='copy') + call addmrg(fldListTo(compice)%flds, 'So_roce_wiso', & + mrg_from=compocn, mrg_fld='So_roce_wiso', mrg_type='copy') end if end if @@ -1584,25 +1637,26 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) do n = 1,size(iso) if (phase == 'advertise') then call addfld(fldListFr(comprof)%flds, 'Firr_rofi'//iso(n)) ! water flux into sea ice due to runoff (frozen) - call addfld(fldListFr(compglc)%flds, 'Figg_rofi'//iso(n)) ! glc frozen runoff_iceberg flux to ice + do ns = 1, num_icesheets + call addfld(fldListFr(compglc(ns))%flds, 'Figg_rofi'//iso(n)) ! glc frozen runoff_iceberg flux to ice + end do call addfld(fldListTo(compice)%flds, 'Fixx_rofi'//iso(n)) ! total frozen water flux into sea ice else - if ( fldchk(is_local%wrap%FBExp(compice) , 'Fixx_rofi'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofi'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(compglc, compglc), 'Figg_rofi'//iso(n), rc=rc)) then - - call addmap(fldListFr(comprof)%flds, 'Forr_rofi'//iso(n), compice, mapconsf, 'none', rof2ocn_ice_rmap) - call addmap(fldListFr(compglc)%flds, 'Figg_rofi'//iso(n), compice, mapconsf, 'one' , glc2ice_rmap) - call addmrg(fldListTo(compice)%flds, 'Fixx_rofi'//iso(n), & - mrg_from1=comprof, mrg_fld1='Firr_rofi'//iso(n), mrg_type1='sum', & - mrg_from2=compglc, mrg_fld2='Figg_rofi'//iso(n), mrg_type2='sum') - - else if ( fldchk(is_local%wrap%FBExp(compice) , 'Fixx_rofi'//iso(n), rc=rc) .and. & - fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofi'//iso(n), rc=rc)) then - - call addmap(fldListFr(comprof)%flds, 'Forr_rofi'//iso(n), compice, mapconsf, 'none', rof2ocn_ice_rmap) - call addmrg(fldListTo(compice)%flds, 'Fixx_rofi'//iso(n), & - mrg_from1=comprof, mrg_fld1='Firr_rofi'//iso(n), mrg_type1='sum') + if ( fldchk(is_local%wrap%FBExp(compice), 'Fixx_rofi'//iso(n), rc=rc)) then + if (fldchk(is_local%wrap%FBImp(comprof, comprof), 'Forr_rofi'//iso(n), rc=rc)) then + call addmap(fldListFr(comprof)%flds, 'Forr_rofi'//iso(n), & + compice, mapconsf, 'none', rof2ocn_ice_rmap) + call addmrg(fldListTo(compice)%flds, 'Fixx_rofi'//iso(n), & + mrg_from=comprof, mrg_fld='Firr_rofi'//iso(n), mrg_type='sum') + end if + do ns = 1, num_icesheets + if (fldchk(is_local%wrap%FBImp(compglc(ns), compglc(ns)), 'Figg_rofi'//iso(n), rc=rc)) then + call addmap(fldListFr(compglc(ns))%flds, 'Figg_rofi'//iso(n), & + compice, mapconsf, 'one' , glc2ice_rmap) + call addmrg(fldListTo(compice)%flds, 'Fixx_rofi'//iso(n), & + mrg_from=compglc(ns), mrg_fld='Figg_rofi'//iso(n), mrg_type='sum') + end if + end do end if end if end do @@ -1623,7 +1677,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! By default will be using a custom map - but if one is not available, use a generated bilinear instead call addmap(fldListFr(compice)%flds, 'Si_ifrac', compwav, mapbilnr, 'one', ice2wav_smap) call addmrg(fldListTo(compwav)%flds, 'Si_ifrac', & - mrg_from1=compice, mrg_fld1='Si_ifrac', mrg_type1='copy') + mrg_from=compice, mrg_fld='Si_ifrac', mrg_type='copy') end if end if @@ -1645,7 +1699,8 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBExp(compwav) , trim(fldname), rc=rc)) then ! By default will be using a custom map - but if one is not available, use a generated bilinear instead call addmap(fldListFr(compocn)%flds, trim(fldname), compwav, mapbilnr, 'one', ocn2wav_smap) - call addmrg(fldListTo(compwav)%flds, trim(fldname), mrg_from1=compocn, mrg_fld1=trim(fldname), mrg_type1='copy') + call addmrg(fldListTo(compwav)%flds, trim(fldname), & + mrg_from=compocn, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -1668,7 +1723,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBImp(compatm,compatm ), trim(fldname), rc=rc)) then call addmap(fldListFr(compatm)%flds, trim(fldname), compwav, mapbilnr, 'one', atm2wav_smap) call addmrg(fldListTo(compwav)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end if end if end do @@ -1704,7 +1759,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) fldchk(is_local%wrap%FBExp(comprof) , trim(fldname), rc=rc)) then call addmap(fldListFr(complnd)%flds, trim(fldname), comprof, mapconsf, 'lfrac', lnd2rof_fmap) call addmrg(fldListTo(comprof)%flds, trim(fldname), & - mrg_from1=complnd, mrg_fld1=trim(fldname), mrg_type1='copy_with_weights', mrg_fracname1='lfrac') + mrg_from=complnd, mrg_fld=trim(fldname), mrg_type='copy_with_weights', mrg_fracname='lfrac') end if end if end do @@ -1726,22 +1781,50 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) if (phase == 'advertise') then call addfld(fldListFr(complnd)%flds, 'Sl_tsrf_elev') ! surface temperature of glacier (1->glc_nec+1) - call addfld(fldListTo(compglc)%flds, 'Sl_tsrf') call addfld(fldListFr(complnd)%flds, 'Sl_topo_elev') ! surface heights of glacier (1->glc_nec+1) - call addfld(fldListTo(compglc)%flds, 'Flgl_qice') call addfld(fldListFr(complnd)%flds, 'Flgl_qice_elev') ! glacier ice flux (1->glc_nec+1) + do ns = 1,num_icesheets + call addfld(fldListTo(compglc(ns))%flds, 'Sl_tsrf') + call addfld(fldListTo(compglc(ns))%flds, 'Flgl_qice') + end do else - if ( fldchk(is_local%wrap%FBImp(complnd,complnd) , 'Flgl_qice_elev', rc=rc)) then - ! custom merging will be done here - call addmap(FldListFr(complnd)%flds, 'Flgl_qice_elev', compglc, mapbilnr, 'lfrac', lnd2glc_smap) - end if - if ( fldchk(is_local%wrap%FBImp(complnd,complnd) , 'Sl_tsrf_elev' , rc=rc)) then - ! custom merging will be done here - call addmap(FldListFr(complnd)%flds, 'Sl_tsrf_elev', compglc, mapbilnr, 'lfrac', lnd2glc_smap) - end if - if ( fldchk(is_local%wrap%FBImp(complnd,complnd) , 'Sl_topo_elev' , rc=rc)) then - ! This is needed just for mappingn to glc - but is not sent as a field - call addmap(FldListFr(complnd)%flds, 'Sl_topo_elev', compglc, mapbilnr, 'lfrac', lnd2glc_smap) + ! custom mapping, accumulation and merging will be done in prep_glc_mod.F90 + do ns = 1,num_icesheets + if ( fldchk(is_local%wrap%FBImp(complnd,complnd) , 'Flgl_qice_elev', rc=rc)) then + call addmap(FldListFr(complnd)%flds, 'Flgl_qice_elev', compglc(ns), mapbilnr, 'lfrac', 'unset') + end if + if ( fldchk(is_local%wrap%FBImp(complnd,complnd) , 'Sl_tsrf_elev' , rc=rc)) then + call addmap(FldListFr(complnd)%flds, 'Sl_tsrf_elev', compglc(ns), mapbilnr, 'lfrac', 'unset') + end if + if ( fldchk(is_local%wrap%FBImp(complnd,complnd) , 'Sl_topo_elev' , rc=rc)) then + ! This is needed just for mappingn to glc - but is not sent as a field + call addmap(FldListFr(complnd)%flds, 'Sl_topo_elev', compglc(ns), mapbilnr, 'lfrac', 'unset') + end if + end do + end if + + !----------------------------- + ! to glc: from ocn + !----------------------------- + if (ocn2glc_coupling) then + if (phase == 'advertise') then + call addfld(fldListFr(compocn)%flds, 'So_t_depth') + call addfld(fldListFr(compocn)%flds, 'So_s_depth') + do ns = 1,num_icesheets + call addfld(fldListTo(compglc(ns))%flds, 'So_t_depth') + call addfld(fldListTo(compglc(ns))%flds, 'So_s_depth') + end do + else + ! custom mapping, accumulation and merging will be done in prep_glc_mod.F90 + ! the following is used to create the route handle + do ns = 1,num_icesheets + if ( fldchk(is_local%wrap%FBImp(compocn,compocn) , 'So_t_depth', rc=rc)) then + call addmap(FldListFr(compocn)%flds, 'So_t_depth', compglc(ns), mapbilnr, 'none', 'unset') + end if + if ( fldchk(is_local%wrap%FBImp(compocn,compocn) , 'So_s_depth', rc=rc)) then + call addmap(FldListFr(compocn)%flds, 'So_s_depth', compglc(ns), mapbilnr, 'none', 'unset') + end if + end do end if end if @@ -1777,9 +1860,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Sa_co2prog', compocn, mapbilnr, 'one', atm2ocn_smap) call addmrg(fldListTo(complnd)%flds, 'Sa_co2prog', & - mrg_from1=compatm, mrg_fld1='Sa_co2prog', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_co2prog', mrg_type='copy') call addmrg(fldListTo(compocn)%flds, 'Sa_co2prog', & - mrg_from1=compatm, mrg_fld1='Sa_co2prog', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_co2prog', mrg_type='copy') end if ! --------------------------------------------------------------------- @@ -1794,9 +1877,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Sa_co2diag', compocn, mapbilnr, 'one', atm2ocn_smap) call addmrg(fldListTo(complnd)%flds, 'Sa_co2diag', & - mrg_from1=compatm, mrg_fld1='Sa_co2diag', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_co2diag', mrg_type='copy') call addmrg(fldListTo(compocn)%flds, 'Sa_co2diag', & - mrg_from1=compatm, mrg_fld1='Sa_co2diag', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_co2diag', mrg_type='copy') end if else if (flds_co2b) then @@ -1810,7 +1893,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else call addmap(fldListFr(compatm)%flds, 'Sa_co2prog', complnd, mapbilnr, 'one', atm2lnd_smap) call addmrg(fldListTo(complnd)%flds, 'Sa_co2prog', & - mrg_from1=compatm, mrg_fld1='Sa_co2prog', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_co2prog', mrg_type='copy') end if ! --------------------------------------------------------------------- @@ -1822,7 +1905,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else call addmap(fldListFr(compatm)%flds, 'Sa_co2diag', complnd, mapbilnr, 'one', atm2lnd_smap) call addmrg(fldListTo(complnd)%flds, 'Sa_co2diag', & - mrg_from1=compatm, mrg_fld1='Sa_co2diag', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_co2diag', mrg_type='copy') end if ! --------------------------------------------------------------------- @@ -1834,7 +1917,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else call addmap(fldListFr(complnd)%flds, 'Fall_fco2_lnd', compatm, mapconsf, 'one', lnd2atm_fmap) call addmrg(fldListTo(compatm)%flds, 'Fall_fco2_lnd', & - mrg_from1=complnd, mrg_fld1='Fall_fco2_lnd', mrg_type1='copy_with_weights', mrg_fracname1='lfrac') + mrg_from=complnd, mrg_fld='Fall_fco2_lnd', mrg_type='copy_with_weights', mrg_fracname='lfrac') end if else if (flds_co2c) then @@ -1851,9 +1934,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Sa_co2prog', compocn, mapbilnr, 'one', atm2ocn_smap) call addmrg(fldListTo(complnd)%flds, 'Sa_co2prog', & - mrg_from1=compatm, mrg_fld1='Sa_co2prog', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_co2prog', mrg_type='copy') call addmrg(fldListTo(compocn)%flds, 'Sa_co2prog', & - mrg_from1=compatm, mrg_fld1='Sa_co2prog', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_co2prog', mrg_type='copy') end if ! --------------------------------------------------------------------- @@ -1868,9 +1951,9 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Sa_co2diag', compocn, mapbilnr, 'one', atm2ocn_smap) call addmrg(fldListTo(complnd)%flds, 'Sa_co2diag', & - mrg_from1=compatm, mrg_fld1='Sa_co2diag', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_co2diag', mrg_type='copy') call addmrg(fldListTo(compocn)%flds, 'Sa_co2diag', & - mrg_from1=compatm, mrg_fld1='Sa_co2diag', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Sa_co2diag', mrg_type='copy') end if ! --------------------------------------------------------------------- @@ -1882,7 +1965,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) else call addmap(fldListFr(complnd)%flds, 'Fall_fco2_lnd', compatm, mapconsf, 'one', lnd2atm_fmap) call addmrg(fldListTo(compatm)%flds, 'Fall_fco2_lnd', & - mrg_from1=complnd, mrg_fld1='Fall_fco2_lnd', mrg_type1='copy_with_weights', mrg_fracname1='lfrac') + mrg_from=complnd, mrg_fld='Fall_fco2_lnd', mrg_type='copy_with_weights', mrg_fracname='lfrac') end if ! --------------------------------------------------------------------- @@ -1905,7 +1988,7 @@ subroutine esmFldsExchange_cesm(gcomp, phase, rc) ! do n = 1,)number_of_fields in carm_flds) ! call addfld(fldListFr(complnd)%flds, trim(fldname)) ! call addmap(fldListFr(complnd)%flds, trim(fldname), compatm, mapconsf, 'one',lnd2atm_smap) - ! call addfld(fldListTo(compatm)%flds, trim(fldname), mrg_from1=complnd, mrg_fld1=trim(fldname), mrg_type1='copy') + ! call addfld(fldListTo(compatm)%flds, trim(fldname), mrg_from=complnd, mrg_fld=trim(fldname), mrg_type='copy') ! enddo ! endif diff --git a/mediator/esmFldsExchange_hafs_mod.F90 b/mediator/esmFldsExchange_hafs_mod.F90 index 29fd506ed..38f294fcf 100644 --- a/mediator/esmFldsExchange_hafs_mod.F90 +++ b/mediator/esmFldsExchange_hafs_mod.F90 @@ -138,7 +138,8 @@ subroutine esmFldsExchange_hafs_advt(gcomp, phase, rc) ! to ocn: req. fields to satisfy mediator (can be removed later) !---------------------------------------------------------- allocate(flds(2)) - flds = (/'Faxa_snowc', 'Faxa_snowl'/) + flds = (/'Faxa_snowc',& + 'Faxa_snowl'/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -148,7 +149,10 @@ subroutine esmFldsExchange_hafs_advt(gcomp, phase, rc) deallocate(flds) allocate(flds(4)) - flds = (/'Sa_topo', 'Sa_z ', 'Sa_ptem', 'Sa_pbot'/) + flds = (/'Sa_topo',& + 'Sa_z ',& + 'Sa_ptem',& + 'Sa_pbot'/) do n = 1,size(flds) fldname = trim(flds(n)) @@ -171,7 +175,10 @@ subroutine esmFldsExchange_hafs_advt(gcomp, phase, rc) ! to ocn: downward diffuse visible incident solar radiation from atm ! --------------------------------------------------------------------- allocate(flds(5)) - flds = (/'Faxa_lwdn ', 'Faxa_swndr', 'Faxa_swndf', 'Faxa_swvdr', & + flds = (/'Faxa_lwdn ', & + 'Faxa_swndr', & + 'Faxa_swndf', & + 'Faxa_swvdr', & 'Faxa_swvdf'/) do n = 1,size(flds) @@ -229,7 +236,12 @@ subroutine esmFldsExchange_hafs_advt(gcomp, phase, rc) ! to ocn: specific humidity at the lowest model level from atm ! --------------------------------------------------------------------- allocate(flds(7)) - flds = (/'Sa_pslv', 'Sa_u ', 'Sa_v ', 'Sa_wspd', 'Sa_tbot', 'Sa_tskn', & + flds = (/'Sa_pslv', & + 'Sa_u ', & + 'Sa_v ', & + 'Sa_wspd', & + 'Sa_tbot', & + 'Sa_tskn', & 'Sa_shum'/) do n = 1,size(flds) @@ -430,7 +442,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, & mapconsf, 'one', hafs_attr%atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end if end do deallocate(flds) @@ -446,7 +458,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, & mapbilnr, 'one', hafs_attr%atm2ocn_smap) call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end if end do deallocate(flds) @@ -457,7 +469,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compice)%flds, 'Si_ifrac', compocn, & mapfcopy, 'unset', 'unset') call addmrg(fldListTo(compocn)%flds, 'Si_ifrac', & - mrg_from1=compice, mrg_fld1='Si_ifrac', mrg_type1='copy') + mrg_from=compice, mrg_fld='Si_ifrac', mrg_type='copy') ! --------------------------------------------------------------------- ! to ocn: downward longwave heat flux from atm @@ -478,8 +490,8 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, & mapconsf, 'one', hafs_attr%atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), & - mrg_type1='copy_with_weights', mrg_fracname1='ofrac') + mrg_from=compatm, mrg_fld=trim(fldname), & + mrg_type='copy_with_weights', mrg_fracname='ofrac') end if end do deallocate(flds) @@ -490,7 +502,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_lwnet', compocn, & mapconsf, 'one', hafs_attr%atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & - mrg_from1=compatm, mrg_fld1='Faxa_lwnet', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_lwnet', mrg_type='copy') ! --------------------------------------------------------------------- ! to ocn: downward shortwave heat flux @@ -501,7 +513,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_swdn', compocn, & mapconsf, 'one', hafs_attr%atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, 'Faxa_swdn', & - mrg_from1=compatm, mrg_fld1='Faxa_swdn', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_swdn', mrg_type='copy') end if ! --------------------------------------------------------------------- @@ -510,7 +522,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_swnet', compocn, & mapconsf, 'one', hafs_attr%atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, 'Foxx_swnet', & - mrg_from1=compatm, mrg_fld1='Faxa_swnet', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_swnet', mrg_type='copy') ! --------------------------------------------------------------------- ! to ocn: precipitation rate from atm @@ -524,15 +536,15 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_rainc', compocn, & mapconsf, 'one', hafs_attr%atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, 'Faxa_rain', & - mrg_from1=compatm, mrg_fld1='Faxa_rainc:Faxa_rainl', & - mrg_type1='sum_with_weights', mrg_fracname1='ofrac') + mrg_from=compatm, mrg_fld='Faxa_rainc:Faxa_rainl', & + mrg_type='sum_with_weights', mrg_fracname='ofrac') else if (fldchk(is_local%wrap%FBExp(compocn),'Faxa_rain',rc=rc) .and. & fldchk(is_local%wrap%FBImp(compatm,compatm),'Faxa_rain',rc=rc) & ) then call addmap(fldListFr(compatm)%flds, 'Faxa_rain', compocn, & mapconsf, 'one', hafs_attr%atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, 'Faxa_rain', & - mrg_from1=compatm, mrg_fld1='Faxa_rain', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_rain', mrg_type='copy') end if ! --------------------------------------------------------------------- @@ -541,7 +553,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_sen', compocn, & mapconsf, 'one', hafs_attr%atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, 'Foxx_sen', & - mrg_from1=compatm, mrg_fld1='Faxa_sen', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_sen', mrg_type='copy') ! --------------------------------------------------------------------- ! to ocn: surface latent heat flux and evaporation water flux @@ -549,7 +561,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_lat', compocn, & mapconsf, 'one', hafs_attr%atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, 'Foxx_lat', & - mrg_from1=compatm, mrg_fld1='Faxa_lat', mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_lat', mrg_type='copy') ! --------------------------------------------------------------------- ! to ocn: sea level pressure from atm @@ -572,7 +584,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, & mapbilnr, 'one', hafs_attr%atm2ocn_smap) call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end if end do deallocate(flds) @@ -587,8 +599,8 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, 'Faxa_'//trim(suffix(n)), compocn, & mapconsf, 'one', hafs_attr%atm2ocn_fmap) call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(suffix(n)), & - mrg_from1=compatm, mrg_fld1='Faxa_'//trim(suffix(n)), & - mrg_type1='copy') + mrg_from=compatm, mrg_fld='Faxa_'//trim(suffix(n)), & + mrg_type='copy') end do deallocate(suffix) @@ -610,7 +622,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compatm)%flds, trim(fldname), compice, & mapbilnr, 'one', hafs_attr%atm2ice_smap) call addmrg(fldListTo(compice)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end if end do deallocate(flds) @@ -629,7 +641,7 @@ subroutine esmFldsExchange_hafs_init(gcomp, phase, rc) call addmap(fldListFr(compocn)%flds, trim(fldname), compice, & mapfcopy , 'unset', 'unset') call addmrg(fldListTo(compice)%flds, trim(fldname), & - mrg_from1=compocn, mrg_fld1=trim(fldname), mrg_type1='copy') + mrg_from=compocn, mrg_fld=trim(fldname), mrg_type='copy') end if end do deallocate(flds) diff --git a/mediator/esmFldsExchange_nems_mod.F90 b/mediator/esmFldsExchange_nems_mod.F90 index edb938990..8bf7b73dd 100644 --- a/mediator/esmFldsExchange_nems_mod.F90 +++ b/mediator/esmFldsExchange_nems_mod.F90 @@ -138,7 +138,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListFr(compice)%flds, trim(fldname)) call addfld(fldListTo(compatm)%flds, trim(fldname)) call addmap(fldListFr(compice)%flds, trim(fldname), compatm, maptype, 'ifrac', 'unset') - call addmrg(fldListTo(compatm)%flds, trim(fldname), mrg_from1=compice, mrg_fld1=trim(fldname), mrg_type1='copy') + call addmrg(fldListTo(compatm)%flds, trim(fldname), mrg_from=compice, mrg_fld=trim(fldname), mrg_type='copy') end do deallocate(flds) @@ -146,7 +146,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListFr(compocn)%flds, 'So_t') call addfld(fldListTo(compatm)%flds, 'So_t') call addmap(fldListFr(compocn)%flds, 'So_t', compatm, maptype, 'ofrac', 'unset') - call addmrg(fldListTo(compatm)%flds, 'So_t', mrg_from1=compocn, mrg_fld1='So_t', mrg_type1='copy') + call addmrg(fldListTo(compatm)%flds, 'So_t', mrg_from=compocn, mrg_fld='So_t', mrg_type='copy') !===================================================================== ! FIELDS TO OCEAN (compocn) @@ -156,7 +156,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListTo(compocn)%flds, 'Sa_pslv') call addfld(fldListFr(compatm)%flds, 'Sa_pslv') call addmap(fldListFr(compatm)%flds, 'Sa_pslv', compocn, maptype, 'none', 'unset') - call addmrg(fldListTo(compocn)%flds, 'Sa_pslv', mrg_from1=compatm, mrg_fld1='Sa_pslv', mrg_type1='copy') + call addmrg(fldListTo(compocn)%flds, 'Sa_pslv', mrg_from=compatm, mrg_fld='Sa_pslv', mrg_type='copy') ! to ocn: from atm (custom merge in med_phases_prep_ocn) ! - downward direct near-infrared incident solar radiation @@ -196,7 +196,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListFr(compatm)%flds, trim(fldname)) call addmap(fldListFr(compatm)%flds, trim(fldname), compocn, maptype, 'none', 'unset') call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy_with_weights', mrg_fracname1='ofrac') + mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy_with_weights', mrg_fracname='ofrac') end do deallocate(flds) @@ -218,7 +218,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListFr(compatm)%flds, 'Faxa_lwnet') call addmap(fldListFr(compatm)%flds, 'Faxa_lwnet', compocn, maptype, 'none', 'unset') call addmrg(fldListTo(compocn)%flds, 'Faxa_lwnet', & - mrg_from1=compatm, mrg_fld1='Faxa_lwnet', mrg_type1='copy_with_weights', mrg_fracname1='ofrac') + mrg_from=compatm, mrg_fld='Faxa_lwnet', mrg_type='copy_with_weights', mrg_fracname='ofrac') ! to ocn: merged sensible heat flux (custom merge in med_phases_prep_ocn) call addfld(fldListTo(compocn)%flds, 'Faxa_sen') @@ -238,8 +238,9 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListFr(compice)%flds , 'Fioi_'//trim(flds(n))) call addmap(fldListFr(compice)%flds, 'Fioi_'//trim(flds(n)), compocn, mapfcopy, 'unset', 'unset') call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(flds(n)), & - mrg_from1=compmed, mrg_fld1='Faox_'//trim(flds(n)), mrg_type1='merge', mrg_fracname1='ofrac', & - mrg_from2=compice, mrg_fld2='Fioi_'//trim(flds(n)), mrg_type2='merge', mrg_fracname2='ifrac') + mrg_from=compmed, mrg_fld='Faox_'//trim(flds(n)), mrg_type='merge', mrg_fracname='ofrac') + call addmrg(fldListTo(compocn)%flds, 'Foxx_'//trim(flds(n)), & + mrg_from=compice, mrg_fld='Fioi_'//trim(flds(n)), mrg_type='merge', mrg_fracname='ifrac') end do deallocate(flds) @@ -248,18 +249,19 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListFr(compatm)%flds, 'Faxa_lwdn') call addmap(fldListFr(compatm)%flds, 'Faxa_lwdn', compocn, maptype, 'none', 'unset') call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & - mrg_from1=compmed, mrg_fld1='Faox_lwup', mrg_type1='merge', mrg_fracname1='ofrac', & - mrg_from2=compatm, mrg_fld2='Faxa_lwdn', mrg_type2='merge', mrg_fracname2='ofrac') + mrg_from=compmed, mrg_fld='Faox_lwup', mrg_type='merge', mrg_fracname='ofrac') + call addmrg(fldListTo(compocn)%flds, 'Foxx_lwnet', & + mrg_from=compatm, mrg_fld='Faxa_lwdn', mrg_type='merge', mrg_fracname='ofrac') ! to ocn: sensible heat flux from mediator via auto merge call addfld(fldListTo(compocn)%flds, 'Faox_sen') call addmrg(fldListTo(compocn)%flds, 'Faox_sen', & - mrg_from1=compmed, mrg_fld1='Faox_sen', mrg_type1='copy_with_weights', mrg_fracname1='ofrac') + mrg_from=compmed, mrg_fld='Faox_sen', mrg_type='copy_with_weights', mrg_fracname='ofrac') ! to ocn: evaporation water flux from mediator via auto merge call addfld(fldListTo(compocn)%flds, 'Faox_evap') call addmrg(fldListTo(compocn)%flds, 'Faox_evap', & - mrg_from1=compmed, mrg_fld1='Faox_evap', mrg_type1='copy_with_weights', mrg_fracname1='ofrac') + mrg_from=compmed, mrg_fld='Faox_evap', mrg_type='copy_with_weights', mrg_fracname='ofrac') end if ! to ocn: water flux due to melting ice from ice @@ -273,7 +275,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListTo(compocn)%flds, trim(fldname)) call addmap(fldListFr(compice)%flds, trim(fldname), compocn, mapfcopy, 'unset', 'unset') call addmrg(fldListTo(compocn)%flds, trim(fldname), & - mrg_from1=compice, mrg_fld1=trim(fldname), mrg_type1='copy_with_weights', mrg_fracname1='ifrac') + mrg_from=compice, mrg_fld=trim(fldname), mrg_type='copy_with_weights', mrg_fracname='ifrac') end do deallocate(flds) @@ -298,7 +300,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListFr(compatm)%flds, trim(fldname)) call addfld(fldListTo(compice)%flds, trim(fldname)) call addmap(fldListFr(compatm)%flds, trim(fldname), compice, maptype, 'none', 'unset') - call addmrg(fldListTo(compice)%flds, trim(fldname), mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + call addmrg(fldListTo(compice)%flds, trim(fldname), mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end do deallocate(flds) @@ -316,7 +318,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListTo(compice)%flds, trim(fldname)) call addfld(fldListFr(compatm)%flds, trim(fldname)) call addmap(fldListFr(compatm)%flds, trim(fldname), compice, maptype, 'none', 'unset') - call addmrg(fldListTo(compice)%flds, trim(fldname), mrg_from1=compatm, mrg_fld1=trim(fldname), mrg_type1='copy') + call addmrg(fldListTo(compice)%flds, trim(fldname), mrg_from=compatm, mrg_fld=trim(fldname), mrg_type='copy') end do deallocate(flds) @@ -335,7 +337,7 @@ subroutine esmFldsExchange_nems(gcomp, phase, rc) call addfld(fldListTo(compice)%flds, trim(fldname)) call addfld(fldListFr(compocn)%flds, trim(fldname)) call addmap(fldListFr(compocn)%flds, trim(fldname), compice, mapfcopy , 'unset', 'unset') - call addmrg(fldListTo(compice)%flds, trim(fldname), mrg_from1=compocn, mrg_fld1=trim(fldname), mrg_type1='copy') + call addmrg(fldListTo(compice)%flds, trim(fldname), mrg_from=compocn, mrg_fld=trim(fldname), mrg_type='copy') end do deallocate(flds) diff --git a/mediator/fd_cesm.yaml b/mediator/fd_cesm.yaml index 08cba35a1..ab4c5cd9a 100644 --- a/mediator/fd_cesm.yaml +++ b/mediator/fd_cesm.yaml @@ -496,6 +496,10 @@ description: mediator land-ice export to lnd (elevation classes 1->glc_nec) Downward heat flux from glacier interior, from mediator, elev class 1->glc_nec # + - standard_name: Sg_area + canonical_units: area internal to the CISM grid in radians**2 + description: land-ice export to mediator (no elevation classes) + # - standard_name: Sg_ice_covered canonical_units: 1 description: land-ice export to mediator (no elevation classes) @@ -811,6 +815,11 @@ canonical_units: g kg-1 description: ocean export # + - standard_name: So_s_depth + alias: s_surf_depths + canonical_units: g kg-1 + description: ocean salinity at multiple depths + # - standard_name: So_ssq canonical_units: kg kg-1 description: ocean export @@ -820,6 +829,11 @@ canonical_units: K description: ocean export # + - standard_name: So_t_depth + alias: sea_surface_temperature_depths + canonical_units: K + description: ocean temperatures at multiple depths + # - standard_name: So_tref canonical_units: K description: ocean export diff --git a/mediator/med.F90 b/mediator/med.F90 index d65d935f1..4c0366b97 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -4,40 +4,39 @@ module MED ! Mediator Component. !----------------------------------------------------------------------------- - use ESMF , only : ESMF_VMLogMemInfo - 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 : dbug_flag => med_constants_dbug_flag - use med_constants_mod , only : spval_init => med_constants_spval_init - use med_constants_mod , only : spval => med_constants_spval - use med_constants_mod , only : czero => med_constants_czero - use med_constants_mod , only : ispval_mask => med_constants_ispval_mask - use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_methods_mod , only : Field_GeomPrint => med_methods_Field_GeomPrint - use med_methods_mod , only : State_GeomPrint => med_methods_State_GeomPrint - use med_methods_mod , only : State_reset => med_methods_State_reset - use med_methods_mod , only : State_getNumFields => med_methods_State_getNumFields - use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar - use med_methods_mod , only : FB_Init => med_methods_FB_init - use med_methods_mod , only : FB_Init_pointer => med_methods_FB_Init_pointer - use med_methods_mod , only : FB_Reset => med_methods_FB_Reset - use med_methods_mod , only : FB_FldChk => med_methods_FB_FldChk - use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN - use med_methods_mod , only : clock_timeprint => med_methods_clock_timeprint - use med_time_mod , only : alarmInit => med_time_alarmInit - use med_utils_mod , only : memcheck => med_memcheck - use med_internalstate_mod , only : InternalState - use med_internalstate_mod , only : med_coupling_allowed, logunit, mastertask - use med_phases_profile_mod , only : med_phases_profile_finalize - use esmFlds , only : ncomps, compname - use esmFlds , only : fldListFr, fldListTo, med_fldList_Realize - use esmFlds , only : ncomps, compname, ncomps, compmed, compatm, compocn - use esmFlds , only : compice, complnd, comprof, compwav, compglc, compname - use esmFlds , only : fldListMed_ocnalb, fldListMed_aoflux - use esmFlds , only : med_fldList_GetNumFlds - use esmFlds , only : med_fldList_GetFldNames - use esmFlds , only : med_fldList_Document_Mapping - use esmFlds , only : med_fldList_Document_Merging + use ESMF , only : ESMF_VMLogMemInfo + 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 : dbug_flag => med_constants_dbug_flag + use med_constants_mod , only : spval_init => med_constants_spval_init + use med_constants_mod , only : spval => med_constants_spval + use med_constants_mod , only : czero => med_constants_czero + use med_constants_mod , only : ispval_mask => med_constants_ispval_mask + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_methods_mod , only : Field_GeomPrint => med_methods_Field_GeomPrint + use med_methods_mod , only : State_GeomPrint => med_methods_State_GeomPrint + use med_methods_mod , only : State_reset => med_methods_State_reset + use med_methods_mod , only : State_getNumFields => med_methods_State_getNumFields + use med_methods_mod , only : State_GetScalar => med_methods_State_GetScalar + use med_methods_mod , only : FB_Init => med_methods_FB_init + use med_methods_mod , only : FB_Init_pointer => med_methods_FB_Init_pointer + use med_methods_mod , only : FB_Reset => med_methods_FB_Reset + use med_methods_mod , only : FB_FldChk => med_methods_FB_FldChk + use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose + use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN + use med_methods_mod , only : clock_timeprint => med_methods_clock_timeprint + use med_time_mod , only : alarmInit => med_time_alarmInit + use med_utils_mod , only : memcheck => med_memcheck + use med_internalstate_mod , only : InternalState + use med_internalstate_mod , only : med_coupling_allowed, logunit, mastertask + use med_phases_profile_mod , only : med_phases_profile_finalize + use esmFlds , only : ncomps, compname + use esmFlds , only : fldListFr, fldListTo, med_fldList_Realize + use esmFlds , only : ncomps, compname, ncomps + use esmFlds , only : compmed, compatm, compocn, compice, complnd, comprof, compwav ! not arrays + use esmFlds , only : num_icesheets, max_icesheets, compglc, ocn2glc_coupling ! compglc is an array + use esmFlds , only : fldListMed_ocnalb, fldListMed_aoflux + use esmFlds , only : med_fldList_GetNumFlds, med_fldList_GetFldNames, med_fldList_GetFldInfo + use esmFlds , only : med_fldList_Document_Mapping, med_fldList_Document_Merging use esmFlds , only : coupling_mode use esmFldsExchange_nems_mod , only : esmFldsExchange_nems use esmFldsExchange_cesm_mod , only : esmFldsExchange_cesm @@ -64,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 !----------------------------------------------------------------------------- @@ -73,7 +77,7 @@ subroutine SetServices(gcomp, rc) use ESMF , only: ESMF_SUCCESS, ESMF_GridCompSetEntryPoint use ESMF , only: ESMF_METHOD_INITIALIZE, ESMF_METHOD_RUN use ESMF , only: ESMF_GridComp, ESMF_MethodRemove - use NUOPC , only: NUOPC_CompDerive, NUOPC_CompSetEntryPoint, NUOPC_CompSpecialize, NUOPC_NOOP + use NUOPC , only: NUOPC_CompDerive, NUOPC_CompSetEntryPoint, NUOPC_CompSpecialize, NUOPC_NoOP use NUOPC_Mediator , only: mediator_routine_SS => SetServices use NUOPC_Mediator , only: mediator_routine_Run => routine_Run use NUOPC_Mediator , only: mediator_label_DataInitialize => label_DataInitialize @@ -88,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 @@ -190,6 +197,9 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_history_write", specRoutine=med_phases_history_write, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_history_write", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ ! setup mediator restart phase @@ -201,6 +211,9 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_restart_write", specRoutine=med_phases_restart_write, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_restart_write", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ ! setup mediator profile phase @@ -212,9 +225,12 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_profile", specRoutine=med_phases_profile, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_profile", specRoutine=NUOPC_NoOp, rc=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, & @@ -224,40 +240,46 @@ subroutine SetServices(gcomp, rc) specPhaseLabel="med_phases_prep_atm", specRoutine=med_phases_prep_atm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - !------------------ - ! prep 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_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_prep_ocn_map", specRoutine=med_phases_prep_ocn_map, rc=rc) + specPhaseLabel="med_phases_post_atm", specRoutine=med_phases_post_atm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + !------------------ + ! prep and post routines for ocn + !------------------ + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & - phaseLabelList=(/"med_phases_prep_ocn_merge"/), 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_merge", specRoutine=med_phases_prep_ocn_merge, 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_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_accum_fast"/), 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_accum_fast", specRoutine=med_phases_prep_ocn_accum_fast, 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_avg"/), 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_avg", specRoutine=med_phases_prep_ocn_accum_avg, 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_post_ocn", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + !------------------ - ! prep routines for ice + ! prep and post routines for ice !------------------ call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & @@ -267,6 +289,17 @@ subroutine SetServices(gcomp, rc) specPhaseLabel="med_phases_prep_ice", specRoutine=med_phases_prep_ice, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! note that med_fraction_set is now called from post_ice + call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & + 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_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 + !------------------ ! prep routines for lnd !------------------ @@ -278,26 +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_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, & @@ -307,22 +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_post_glc", specRoutine=NUOPC_NoOp, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ @@ -335,6 +396,9 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_ocnalb_run", specRoutine=med_phases_ocnalb_run, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_ocnalb_run", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ ! phase routine for ocn/atm flux computation @@ -346,6 +410,9 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_aofluxes_run", specRoutine=med_phases_aofluxes_run, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_aofluxes_run", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ ! phase routine for updating fractions @@ -357,6 +424,9 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_fraction_set", specRoutine=med_fraction_set, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_fraction_set", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ ! phase routines for budget diagnostics @@ -367,54 +437,81 @@ subroutine SetServices(gcomp, rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaselabel="med_phases_diag_atm", specRoutine=med_phases_diag_atm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_diag_atm", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & phaseLabelList=(/"med_phases_diag_lnd"/), userRoutine=mediator_routine_Run, rc=rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaselabel="med_phases_diag_lnd", specRoutine=med_phases_diag_lnd, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_diag_lnd", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & phaseLabelList=(/"med_phases_diag_rof"/), userRoutine=mediator_routine_Run, rc=rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaselabel="med_phases_diag_rof", specRoutine=med_phases_diag_rof, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_diag_rof", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & phaseLabelList=(/"med_phases_diag_ocn"/), userRoutine=mediator_routine_Run, rc=rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaselabel="med_phases_diag_ocn", specRoutine=med_phases_diag_ocn, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_diag_ocn", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & phaseLabelList=(/"med_phases_diag_glc"/), userRoutine=mediator_routine_Run, rc=rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaselabel="med_phases_diag_glc", specRoutine=med_phases_diag_glc, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_diag_glc", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & phaseLabelList=(/"med_phases_diag_ice_ice2med"/), userRoutine=mediator_routine_Run, rc=rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaselabel="med_phases_diag_ice_ice2med", specRoutine=med_phases_diag_ice_ice2med, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_diag_ice_ice2med", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & phaseLabelList=(/"med_phases_diag_ice_med2ice"/), userRoutine=mediator_routine_Run, rc=rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaselabel="med_phases_diag_ice_med2ice", specRoutine=med_phases_diag_ice_med2ice, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_diag_ice_med2ice", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & phaseLabelList=(/"med_phases_diag_accum"/), userRoutine=mediator_routine_Run, rc=rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaselabel="med_phases_diag_accum", specRoutine=med_phases_diag_accum, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_diag_accum", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return call NUOPC_CompSetEntryPoint(gcomp, ESMF_METHOD_RUN, & phaseLabelList=(/"med_phases_diag_print"/), userRoutine=mediator_routine_Run, rc=rc) call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_Advance, & specPhaseLabel="med_phases_diag_print", specRoutine=med_phases_diag_print, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_CompSpecialize(gcomp, specLabel=mediator_label_TimestampExport, & + specPhaselabel="med_phases_diag_print", specRoutine=NUOPC_NoOp, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return !------------------ ! attach specializing method(s) @@ -501,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) @@ -537,19 +640,10 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) ! Mediator advertises its import and export Fields and sets the ! TransferOfferGeomObject Attribute. - use ESMF , only : ESMF_GridComp, ESMF_State, ESMF_Clock, ESMF_SUCCESS, ESMF_LogFoundAllocError - use ESMF , only : ESMF_LogMsg_Info, ESMF_LogWrite - use NUOPC , only : NUOPC_AddNamespace, NUOPC_Advertise - use NUOPC , only : NUOPC_CompAttributeGet, NUOPC_CompAttributeSet, NUOPC_CompAttributeAdd - use med_internalstate_mod , only : InternalState - use esmFlds , only : ncomps, compmed, compatm, compocn - use esmFlds , only : compice, complnd, comprof, compwav, compglc, compname - use esmFlds , only : fldListFr, fldListTo - use esmFlds , only : med_fldList_GetNumFlds - use esmFlds , only : med_fldList_GetFldInfo - use esmFldsExchange_nems_mod, only : esmFldsExchange_nems - use esmFldsExchange_hafs_mod, only : esmFldsExchange_hafs - use med_internalstate_mod , only : mastertask + use ESMF , only : ESMF_GridComp, ESMF_State, ESMF_Clock, ESMF_SUCCESS, ESMF_LogFoundAllocError + use ESMF , only : ESMF_LogMsg_Info, ESMF_LogWrite + use NUOPC , only : NUOPC_AddNamespace, NUOPC_Advertise, NUOPC_AddNestedState + use NUOPC , only : NUOPC_CompAttributeGet, NUOPC_CompAttributeSet, NUOPC_CompAttributeAdd ! input/output variables type(ESMF_GridComp) :: gcomp @@ -559,16 +653,13 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) ! local variables character(len=CS) :: stdname, shortname - integer :: n, n1, n2, ncomp, nflds + integer :: n, n1, n2, ncomp, nflds, ns logical :: isPresent, isSet character(len=CS) :: transferOffer character(len=CS) :: cvalue + 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) ' !----------------------------------------------------------- @@ -598,44 +689,59 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) ! state. The nested state is returned as nestedState. nestedStateName will be used to name the ! newly created nested state. - call NUOPC_AddNamespace(importState, namespace="ATM", nestedStateName="NestedState-AtmImp", & + call NUOPC_AddNamespace(importState, namespace="ATM", nestedStateName="AtmImp", & nestedState=is_local%wrap%NStateImp(compatm), rc=rc) - call NUOPC_AddNamespace(importState, namespace="OCN", nestedStateName="NestedState-OcnImp", & - nestedState=is_local%wrap%NStateImp(compocn), rc=rc) - call NUOPC_AddNamespace(importState, namespace="ICE", nestedStateName="NestedState-IceImp", & - nestedState=is_local%wrap%NStateImp(compice), rc=rc) - call NUOPC_AddNamespace(importState, namespace="LND", nestedStateName="NestedState-LndImp", & - nestedState=is_local%wrap%NStateImp(complnd), rc=rc) - call NUOPC_AddNamespace(importState, namespace="ROF", nestedStateName="NestedState-RofImp", & - nestedState=is_local%wrap%NStateImp(comprof), rc=rc) - call NUOPC_AddNamespace(importState, namespace="WAV", nestedStateName="NestedState-WavImp", & - nestedState=is_local%wrap%NStateImp(compwav), rc=rc) - call NUOPC_AddNamespace(importState, namespace="GLC", nestedStateName="NestedState-GlcImp", & - nestedState=is_local%wrap%NStateImp(compglc), rc=rc) - call NUOPC_AddNamespace(exportState, namespace="ATM", nestedStateName="NestedState-AtmExp", & + call NUOPC_AddNamespace(exportState, namespace="ATM", nestedStateName="AtmExp", & nestedState=is_local%wrap%NStateExp(compatm), rc=rc) - call NUOPC_AddNamespace(exportState, namespace="OCN", nestedStateName="NestedState-OcnExp", & + + call NUOPC_AddNamespace(importState, namespace="OCN", nestedStateName="OcnImp", & + nestedState=is_local%wrap%NStateImp(compocn), rc=rc) + call NUOPC_AddNamespace(exportState, namespace="OCN", nestedStateName="OcnExp", & nestedState=is_local%wrap%NStateExp(compocn), rc=rc) - call NUOPC_AddNamespace(exportState, namespace="ICE", nestedStateName="NestedState-IceExp", & + + call NUOPC_AddNamespace(importState, namespace="ICE", nestedStateName="IceImp", & + nestedState=is_local%wrap%NStateImp(compice), rc=rc) + call NUOPC_AddNamespace(exportState, namespace="ICE", nestedStateName="IceExp", & nestedState=is_local%wrap%NStateExp(compice), rc=rc) - call NUOPC_AddNamespace(exportState, namespace="LND", nestedStateName="NestedState-LndExp", & + + call NUOPC_AddNamespace(importState, namespace="LND", nestedStateName="LndImp", & + nestedState=is_local%wrap%NStateImp(complnd), rc=rc) + call NUOPC_AddNamespace(exportState, namespace="LND", nestedStateName="LndExp", & nestedState=is_local%wrap%NStateExp(complnd), rc=rc) - call NUOPC_AddNamespace(exportState, namespace="ROF", nestedStateName="NestedState-RofExp", & + + call NUOPC_AddNamespace(importState, namespace="ROF", nestedStateName="RofImp", & + nestedState=is_local%wrap%NStateImp(comprof), rc=rc) + call NUOPC_AddNamespace(exportState, namespace="ROF", nestedStateName="RofExp", & nestedState=is_local%wrap%NStateExp(comprof), rc=rc) - call NUOPC_AddNamespace(exportState, namespace="WAV", nestedStateName="NestedState-WavExp", & + + call NUOPC_AddNamespace(importState, namespace="WAV", nestedStateName="WavImp", & + nestedState=is_local%wrap%NStateImp(compwav), rc=rc) + call NUOPC_AddNamespace(exportState, namespace="WAV", nestedStateName="WavExp", & nestedState=is_local%wrap%NStateExp(compwav), rc=rc) - call NUOPC_AddNamespace(exportState, namespace="GLC", nestedStateName="NestedState-GlcExp", & - nestedState=is_local%wrap%NStateExp(compglc), rc=rc) + + ! Only create nested states for active ice sheets + do ns = 1,num_icesheets + write(cnum,'(i0)') ns + call NUOPC_AddNestedState(importState, CplSet="GLC"//trim(cnum), & + nestedState=is_local%wrap%NStateImp(compglc(ns)), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call NUOPC_AddNestedState(exportState, CplSet="GLC"//trim(cnum), & + nestedState=is_local%wrap%NStateExp(compglc(ns)), rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end do !------------------ - ! Initialize mediator flds (should be identical to the list in esmDict_Init) + ! Initialize mediator flds !------------------ call NUOPC_CompAttributeGet(gcomp, name='coupling_mode', value=coupling_mode, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_LogWrite('coupling_mode = '// trim(coupling_mode), ESMF_LOGMSG_INFO) if (mastertask) then - write(logunit,*)' Mediator Coupling Mode is ',trim(coupling_mode) + write(logunit,*) '========================================================' + write(logunit,'(a)')trim(subname)//' Mediator Coupling Mode is '//trim(coupling_mode) + write(logunit,*) '========================================================' + write(logunit,*) end if if (trim(coupling_mode) == 'cesm') then @@ -667,6 +773,7 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) wav_present = "false" glc_present = "false" + ! Note that the present flag is set to true if the component is not stub call NUOPC_CompAttributeGet(gcomp, name='ATM_model', value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (isPresent .and. isSet) then @@ -755,7 +862,8 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return read(cvalue,*) is_local%wrap%flds_scalar_index_ny - call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldIdxNextSwCday", value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) + call NUOPC_CompAttributeGet(gcomp, name="ScalarFieldIdxNextSwCday", value=cvalue, & + isPresent=isPresent, isSet=isSet, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (isPresent .and. isSet) then read(cvalue,*) is_local%wrap%flds_scalar_index_nextsw_cday @@ -777,9 +885,13 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) do ncomp = 1,ncomps if (ncomp /= compmed) then + if (mastertask) write(logunit,*) nflds = med_fldList_GetNumFlds(fldListFr(ncomp)) do n = 1,nflds call med_fldList_GetFldInfo(fldListFr(ncomp), n, stdname, shortname) + if (mastertask) then + write(logunit,'(a)') trim(subname)//':Fr_'//trim(compname(ncomp))//': '//trim(shortname) + end if if (trim(shortname) == is_local%wrap%flds_scalar_name) then transferOffer = 'will provide' else @@ -794,6 +906,9 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) nflds = med_fldList_GetNumFlds(fldListTo(ncomp)) do n = 1,nflds call med_fldList_GetFldInfo(fldListTo(ncomp), n, stdname, shortname) + if (mastertask) then + write(logunit,'(a)') trim(subname)//':To_'//trim(compname(ncomp))//': '//trim(shortname) + end if if (trim(shortname) == is_local%wrap%flds_scalar_name) then transferOffer = 'will provide' else @@ -802,7 +917,6 @@ subroutine InitializeIPDv03p1(gcomp, importState, exportState, clock, rc) call NUOPC_Advertise(is_local%wrap%NStateExp(ncomp), standardName=stdname, shortname=shortname, name=shortname, & TransferOfferGeomObject=transferOffer, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(subname//':To_'//trim(compname(ncomp))//': '//trim(shortname), ESMF_LOGMSG_INFO) end do end if @@ -822,9 +936,11 @@ subroutine InitializeIPDv03p3(gcomp, importState, exportState, clock, rc) use ESMF , only : ESMF_GridComp, ESMF_State, ESMF_Clock, ESMF_VM, ESMF_SUCCESS use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_TimeInterval use ESMF , only : ESMF_VMGet, ESMF_StateIsCreated, ESMF_GridCompGet -#if ESMF_VERSION_MINOR > 0 +#if ESMF_VERSION_MAJOR >= 8 +#if ESMF_VERSION_MINOR > 0 use ESMF , only : ESMF_StateSet, ESMF_StateIntent_Import, ESMF_StateIntent_Export use ESMF , only : ESMF_StateIntent_Flag +#endif #endif ! Input/output variables type(ESMF_GridComp) :: gcomp @@ -856,9 +972,11 @@ subroutine InitializeIPDv03p3(gcomp, importState, exportState, clock, rc) ! Realize States do n = 1,ncomps if (ESMF_StateIsCreated(is_local%wrap%NStateImp(n), rc=rc)) then -#if ESMF_VERSION_MINOR > 0 +#if ESMF_VERSION_MAJOR >= 8 +#if ESMF_VERSION_MINOR > 0 call ESMF_StateSet(is_local%wrap%NStateImp(n), stateIntent=ESMF_StateIntent_Import, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return +#endif #endif call med_fldList_Realize(is_local%wrap%NStateImp(n), fldListFr(n), & is_local%wrap%flds_scalar_name, is_local%wrap%flds_scalar_num, & @@ -866,9 +984,11 @@ subroutine InitializeIPDv03p3(gcomp, importState, exportState, clock, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif if (ESMF_StateIsCreated(is_local%wrap%NStateExp(n), rc=rc)) then -#if ESMF_VERSION_MINOR > 0 +#if ESMF_VERSION_MAJOR >= 8 +#if ESMF_VERSION_MINOR > 0 call ESMF_StateSet(is_local%wrap%NStateExp(n), stateIntent=ESMF_StateIntent_Export, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return +#endif #endif call med_fldList_Realize(is_local%wrap%NStateExp(n), fldListTo(n), & is_local%wrap%flds_scalar_name, is_local%wrap%flds_scalar_num, & @@ -1567,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 @@ -1589,14 +1715,14 @@ subroutine DataInitialize(gcomp, rc) type(ESMF_Field) :: field type(ESMF_StateItem_Flag) :: itemType logical :: atCorrectTime, connected - integer :: n1,n2,n + integer :: n1,n2,n,ns integer :: nsrc,ndst integer :: cntn1, cntn2 integer :: fieldCount character(ESMF_MAXSTR),allocatable :: fieldNameList(:) - character(CL) :: value character(CL), pointer :: fldnames(:) => null() character(CL) :: cvalue + character(CL) :: cname character(CL) :: start_type logical :: read_restart logical :: allDone = .false. @@ -1633,36 +1759,110 @@ subroutine DataInitialize(gcomp, rc) if (first_call) then - ! initialize the present flags in the mediator - call ESMF_LogWrite("Starting to initialize present flags", ESMF_LOGMSG_INFO) - call ESMF_LogFlush() - !---------------------------------------------------------- - !--- Check present flags + ! Initialize mediator present flags !---------------------------------------------------------- - do n1 = 1,ncomps - call ESMF_AttributeGet(gcomp, name=trim(compname(n1))//"_present", value=value, defaultValue="false", & - convention="NUOPC", purpose="Instance", rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (mastertask) then + write(logunit,'(a)') trim(subname) // "Initializing present flags" + end if - is_local%wrap%comp_present(n1) = (value == "true") - write(msgString,'(A,L4)') trim(subname)//' comp_present(comp'//trim(compname(n1))//') = ',& - is_local%wrap%comp_present(n1) - call ESMF_LogWrite(trim(msgString), ESMF_LOGMSG_INFO) - enddo + do n1 = 1,ncomps + cname = trim(compname(n1)) + if (cname(1:3) == 'glc') then + ! Special logic for glc since there can be multiple ice sheets + call ESMF_AttributeGet(gcomp, name="glc_present", value=cvalue, & + convention="NUOPC", purpose="Instance", rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (trim(cvalue) == 'true') then + do ns = 1,max_icesheets + if (ns <= num_icesheets) then + is_local%wrap%comp_present(compglc(ns)) = .true. + else + is_local%wrap%comp_present(compglc(ns)) = .false. + end if + end do + end if + else + call ESMF_AttributeGet(gcomp, name=trim(compname(n1))//"_present", value=cvalue, & + convention="NUOPC", purpose="Instance", rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (trim(cvalue) == "true") then + is_local%wrap%comp_present(n1) = .true. + else + is_local%wrap%comp_present(n1) = .false. + end if + end if + if (mastertask) then + write(msgString,'(A,L4)') trim(subname)//' comp_present(comp'//trim(compname(n1))//') = ',& + is_local%wrap%comp_present(n1) + write(logunit,'(a)') trim(subname) // trim(msgString) + end if + end do !---------------------------------------------------------- - !--- Check for active coupling interactions - ! must be allowed, bundles created, and both sides have some fields + ! Check for active coupling interactions + ! must be allowed, bundles created, and both sides have some fields !---------------------------------------------------------- - call ESMF_LogWrite("Starting to initialize active flags", ESMF_LOGMSG_INFO) - call ESMF_LogFlush() + ! 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. + ! are allowed, just update the table below. - ! initialize med_coupling_active - is_local%wrap%med_coupling_active(:,:) = .false. + if (mastertask) then + write(logunit,'(a)') trim(subname) // "Initializing active coupling flags" + end if + ! Initialize med_coupling_allowed + med_coupling_allowed(:,:) = .false. + + ! to atmosphere + med_coupling_allowed(complnd,compatm) = .true. + med_coupling_allowed(compice,compatm) = .true. + med_coupling_allowed(compocn,compatm) = .true. + + ! to land + med_coupling_allowed(compatm,complnd) = .true. + med_coupling_allowed(comprof,complnd) = .true. + do ns = 1,num_icesheets + med_coupling_allowed(compglc(ns),complnd) = .true. + end do + + ! to ocean + med_coupling_allowed(compatm,compocn) = .true. + med_coupling_allowed(compice,compocn) = .true. + med_coupling_allowed(comprof,compocn) = .true. + med_coupling_allowed(compwav,compocn) = .true. + do ns = 1,num_icesheets + med_coupling_allowed(compglc(ns),compocn) = .true. + end do + + ! to ice + med_coupling_allowed(compatm,compice) = .true. + med_coupling_allowed(compocn,compice) = .true. + med_coupling_allowed(comprof,compice) = .true. + med_coupling_allowed(compwav,compice) = .true. + do ns = 1,num_icesheets + med_coupling_allowed(compglc(ns),compice) = .true. + end do + + ! to river + med_coupling_allowed(complnd,comprof) = .true. + + ! to wave + med_coupling_allowed(compatm,compwav) = .true. + med_coupling_allowed(compocn,compwav) = .true. + med_coupling_allowed(compice,compwav) = .true. + + ! to land-ice + do ns = 1,num_icesheets + med_coupling_allowed(complnd,compglc(ns)) = .true. + med_coupling_allowed(compocn,compglc(ns)) = .true. + end do + + ! initialize med_coupling_active table + is_local%wrap%med_coupling_active(:,:) = .false. do n1 = 1,ncomps if (is_local%wrap%comp_present(n1) .and. ESMF_StateIsCreated(is_local%wrap%NStateImp(n1),rc=rc)) then call State_GetNumFields(is_local%wrap%NStateImp(n1), cntn1, rc=rc) ! Import Field Count @@ -1682,55 +1882,61 @@ subroutine DataInitialize(gcomp, rc) endif enddo - ! create tables of output + ! Reset ocn2glc coupling based in input attribute + if (.not. ocn2glc_coupling) then + do ns = 1,num_icesheets + is_local%wrap%med_coupling_active(compocn,compglc(ns)) = .false. + end do + end if + + ! create tables of allowed and active coupling flags + ! - the rows are the destination of coupling + ! - the columns are the source of coupling + ! - So, the second column indicates which models the atm is coupled to. + ! - And the second row indicates which models are coupled to the atm. if (mastertask) then - if (dbug_flag > 5) then - write(logunit,*) ' ' - write(logunit,'(A)') subname//' Allowed coupling flags' - write(logunit,'(2x,A10,20(A5))') '|from to->',(compname(n2),n2=1,ncomps) - do n1 = 1,ncomps - write(msgString,'(2x,a1,A,5x,20(L5))') '|',trim(compname(n1)),(med_coupling_allowed(n1,n2),n2=1,ncomps) - do n2 = 1,len_trim(msgString) - if (msgString(n2:n2) == 'F') msgString(n2:n2)='-' - enddo - write(logunit,'(A)') trim(msgString) + write(logunit,*) ' ' + write(logunit,'(A)') trim(subname)//' Allowed coupling flags' + write(logunit,'(2x,A10,20(A5))') '|from to->',(compname(n2),n2=1,ncomps) + do n1 = 1,ncomps + write(msgString,'(2x,a1,A,5x,20(L5))') '|',trim(compname(n1)), & + (med_coupling_allowed(n1,n2),n2=1,ncomps) + do n2 = 1,len_trim(msgString) + if (msgString(n2:n2) == 'F') msgString(n2:n2)='-' enddo - write(logunit,*) ' ' - endif - - if (dbug_flag >= 0) then - write(logunit,*) ' ' - write(logunit,'(A)') subname//' Active coupling flags' - write(logunit,'(2x,A10,20(A5))') '|from to->',(compname(n2),n2=1,ncomps) - do n1 = 1,ncomps - write(msgString,'(2x,a1,A,5x,20(L5))') '|',trim(compname(n1)),& - (is_local%wrap%med_coupling_active(n1,n2),n2=1,ncomps) - do n2 = 1,len_trim(msgString) - if (msgString(n2:n2) == 'F') msgString(n2:n2)='-' - enddo - write(logunit,'(A)') trim(msgString) + write(logunit,'(A)') trim(msgString) + enddo + + write(logunit,*) ' ' + write(logunit,'(A)') subname//' Active coupling flags' + write(logunit,'(2x,A10,20(A5))') '|from to->',(compname(n2),n2=1,ncomps) + do n1 = 1,ncomps + write(msgString,'(2x,a1,A,5x,20(L5))') '|',trim(compname(n1)), & + (is_local%wrap%med_coupling_active(n1,n2),n2=1,ncomps) + do n2 = 1,len_trim(msgString) + if (msgString(n2:n2) == 'F') msgString(n2:n2)='-' enddo - write(logunit,*) ' ' - endif + write(logunit,'(A)') trim(msgString) + enddo + write(logunit,*) ' ' endif - !---------------------------------------------------------- - ! Initialize connector count - !---------------------------------------------------------- - - call ESMF_LogWrite("Starting to Create FBs", ESMF_LOGMSG_INFO) - call ESMF_LogFlush() - !---------------------------------------------------------- ! Create field bundles FBImp, FBExp, FBImpAccum, FBExpAccum !---------------------------------------------------------- + if (mastertask) then + write(logunit,'(a)') 'Creating mediator field bundles ' + end if + do n1 = 1,ncomps if (is_local%wrap%comp_present(n1) .and. & ESMF_StateIsCreated(is_local%wrap%NStateImp(n1),rc=rc) .and. & ESMF_StateIsCreated(is_local%wrap%NStateExp(n1),rc=rc)) then - if (mastertask) write(logunit,*) subname,' initializing FBs for '//trim(compname(n1)) + if (mastertask) then + write(logunit,'(a)') trim(subname)//' initializing FBs for '//trim(compname(n1)) + end if ! Create FBImp(:) with pointers directly into NStateImp(:) call FB_init_pointer(is_local%wrap%NStateImp(n1), is_local%wrap%FBImp(n1,n1), & @@ -1764,7 +1970,7 @@ subroutine DataInitialize(gcomp, rc) call med_meshinfo_create(is_local%wrap%FBImp(n1,n1), & is_local%wrap%mesh_info(n1), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif + end if ! The following are FBImp and FBImpAccum mapped to different grids. ! FBImp(n1,n1) and FBImpAccum(n1,n1) are handled above @@ -1775,8 +1981,10 @@ subroutine DataInitialize(gcomp, rc) ESMF_StateIsCreated(is_local%wrap%NStateImp(n1),rc=rc) .and. & ESMF_StateIsCreated(is_local%wrap%NStateImp(n2),rc=rc)) then - if (mastertask) write(logunit,*) subname,' initializing FBs for '//& - trim(compname(n1))//'_'//trim(compname(n2)) + if (mastertask) then + write(logunit,'(a)') trim(subname)//' initializing FBs for '//& + trim(compname(n1))//'_'//trim(compname(n2)) + end if call FB_init(is_local%wrap%FBImp(n1,n2), is_local%wrap%flds_scalar_name, & STgeom=is_local%wrap%NStateImp(n2), & @@ -1810,8 +2018,7 @@ subroutine DataInitialize(gcomp, rc) ! NOTE: this section must be done BEFORE the call to esmFldsExchange ! Create field bundles for mediator ocean albedo computation - if ( is_local%wrap%med_coupling_active(compocn,compatm) .or. & - is_local%wrap%med_coupling_active(compatm,compocn)) then + if ( is_local%wrap%med_coupling_active(compocn,compatm) .or. is_local%wrap%med_coupling_active(compatm,compocn)) then if (.not. is_local%wrap%med_coupling_active(compatm,compocn)) then is_local%wrap%med_coupling_active(compatm,compocn) = .true. @@ -1827,25 +2034,33 @@ subroutine DataInitialize(gcomp, rc) call FB_init(is_local%wrap%FBMed_ocnalb_a, is_local%wrap%flds_scalar_name, & STgeom=is_local%wrap%NStateImp(compatm), fieldnamelist=fldnames, name='FBMed_ocnalb_a', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (mastertask) write(logunit,*) subname,' initializing FB FBMed_ocnalb_a' + if (mastertask) then + write(logunit,'(a)') trim(subname)//' initializing FB FBMed_ocnalb_a' + end if call FB_init(is_local%wrap%FBMed_ocnalb_o, is_local%wrap%flds_scalar_name, & STgeom=is_local%wrap%NStateImp(compocn), fieldnamelist=fldnames, name='FBMed_ocnalb_o', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (mastertask) write(logunit,*) subname,' initializing FB FBMed_ocnalb_o' + if (mastertask) then + write(logunit,'(a)') trim(subname)//' initializing FB FBMed_ocnalb_o' + end if deallocate(fldnames) ! The following assumes that the mediator atm/ocn flux calculation will be done on the ocean grid if (.not. ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(compatm,compocn), rc=rc)) then - call ESMF_LogWrite(trim(subname)//' creating field bundle FBImp(compatm,compocn)', ESMF_LOGMSG_INFO) + if (mastertask) then + write(logunit,'(a)') trim(subname)//' creating field bundle FBImp(compatm,compocn)' + end if call FB_init(is_local%wrap%FBImp(compatm,compocn), is_local%wrap%flds_scalar_name, & STgeom=is_local%wrap%NStateImp(compocn), & STflds=is_local%wrap%NStateImp(compatm), & name='FBImp'//trim(compname(compatm))//'_'//trim(compname(compocn)), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if - if (mastertask) write(logunit,*) subname,' initializing FBs for '// & - trim(compname(compatm))//'_'//trim(compname(compocn)) + if (mastertask) then + write(logunit,'(a)') trim(subname)//' initializing FBs for '// & + trim(compname(compatm))//'_'//trim(compname(compocn)) + end if end if ! Create field bundles for mediator ocean/atmosphere flux computation @@ -1858,12 +2073,16 @@ subroutine DataInitialize(gcomp, rc) call FB_init(is_local%wrap%FBMed_aoflux_a, is_local%wrap%flds_scalar_name, & STgeom=is_local%wrap%NStateImp(compatm), fieldnamelist=fldnames, name='FBMed_aoflux_a', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (mastertask) write(logunit,*) subname,' initializing FB FBMed_aoflux_a' + if (mastertask) then + write(logunit,'(a)') trim(subname)//' initializing FB FBMed_aoflux_a' + end if call FB_init(is_local%wrap%FBMed_aoflux_o, is_local%wrap%flds_scalar_name, & STgeom=is_local%wrap%NStateImp(compocn), fieldnamelist=fldnames, name='FBMed_aoflux_o', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (mastertask) write(logunit,*) subname,' initializing FB FBMed_aoflux_o' + if (mastertask) then + write(logunit,'(a)') trim(subname)//' initializing FB FBMed_aoflux_o' + end if deallocate(fldnames) end if end if @@ -2052,6 +2271,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 @@ -2095,9 +2319,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 @@ -2117,7 +2343,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, & @@ -2144,13 +2373,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) @@ -2159,23 +2386,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 @@ -2207,10 +2473,6 @@ subroutine SetRunClock(gcomp, rc) type(ESMF_Time) :: currTime type(ESMF_TimeInterval) :: timeStep character(len=CL) :: cvalue - type(ESMF_ALARM) :: glc_avg_alarm - logical :: glc_present - character(len=CS) :: glc_avg_period - integer :: glc_cpl_dt logical :: first_time = .true. character(len=*),parameter :: subname=' (module_MED:SetRunClock) ' !----------------------------------------------------------- @@ -2245,47 +2507,6 @@ subroutine SetRunClock(gcomp, rc) call NUOPC_CompCheckSetClock(gcomp, driverClock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - !-------------------------------- - ! set glc averaging alarm if appropriate - !-------------------------------- - - if (first_time) then - - ! Set glc averaging alarm if appropriate - call NUOPC_CompAttributeGet(gcomp, name="glc_present", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - glc_present = (cvalue == "true") - - if (glc_present) then - call NUOPC_CompAttributeGet(gcomp, name="glc_avg_period", value=glc_avg_period, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (trim(glc_avg_period) == 'hour') then - call alarmInit(mediatorclock, glc_avg_alarm, 'nhours', opt_n=1, alarmname='alarm_glc_avg', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else if (trim(glc_avg_period) == 'day') then - call alarmInit(mediatorclock, glc_avg_alarm, 'ndays' , opt_n=1, alarmname='alarm_glc_avg', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else if (trim(glc_avg_period) == 'yearly') then - call alarmInit(mediatorclock, glc_avg_alarm, 'nyears', opt_n=1, alarmname='alarm_glc_avg', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else if (trim(glc_avg_period) == 'glc_coupling_period') then - call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", value=cvalue, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - read(cvalue,*) glc_cpl_dt - call alarmInit(mediatorclock, glc_avg_alarm, 'nseconds', opt_n=glc_cpl_dt, alarmname='alarm_glc_avg', rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - call ESMF_LogWrite(trim(subname)// ": ERROR glc_avg_period = "//trim(glc_avg_period)//" not supported", & - ESMF_LOGMSG_INFO) - rc = ESMF_FAILURE - RETURN - end if - call ESMF_AlarmSet(glc_avg_alarm, clock=mediatorclock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - first_time = .false. - end if - !-------------------------------- ! Advance med clock to trigger alarms then reset model clock back to currtime !-------------------------------- @@ -2320,8 +2541,6 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) ! local variables type(ESMF_Field) :: lfield type(ESMF_Mesh) :: lmesh - type(ESMF_Array) :: lArray - type(ESMF_DistGrid) :: lDistGrid integer :: numOwnedElements integer :: spatialDim real(r8), allocatable :: ownedElemCoords(:) @@ -2332,34 +2551,32 @@ subroutine med_meshinfo_create(FB, mesh_info, rc) rc= ESMF_SUCCESS + ! Loop over number of fields and get mesh from the first field in FB with dimcount==1 call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Find the first field in FB with dimcount==1 - do n=1,fieldCount + do n = 1,fieldCount call FB_getFieldN(FB, fieldnum=n, field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, mesh=lmesh, dimcount=dimCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return if (dimCount==1) exit enddo - call ESMF_FieldRegridGetArea(lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_MeshGet(lmesh, spatialDim=spatialDim, numOwnedElements=numOwnedElements, & - elementDistGrid=lDistGrid, rc=rc) + ! Determine dimensions in mesh + call ESMF_MeshGet(lmesh, spatialDim=spatialDim, numOwnedElements=numOwnedElements, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Allocate mesh_info data, we need a copy here because the FB may get reset later + ! Obtain mesh info areas + call ESMF_FieldRegridGetArea(lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return allocate(mesh_info%areas(numOwnedElements)) call ESMF_FieldGet(lfield, farrayPtr=dataptr, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - mesh_info%areas = dataptr + mesh_info%areas(:) = dataptr + ! Obtain mesh longitudes and latitudes allocate(mesh_info%lats(numOwnedElements)) allocate(mesh_info%lons(numOwnedElements)) - - ! Obtain mesh longitudes and latitudes allocate(ownedElemCoords(spatialDim*numOwnedElements)) call ESMF_MeshGet(lmesh, ownedElemCoords=ownedElemCoords) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -2382,15 +2599,15 @@ subroutine med_grid_write(grid, fileName, rc) use ESMF, only : ESMF_SUCCESS, ESMF_GRIDITEM_MASK, ESMF_GRIDITEM_AREA ! input/output variables - type(ESMF_Grid), intent(in) :: grid - character(len=*) :: fileName - integer, intent(out) :: rc + type(ESMF_Grid) , intent(in) :: grid + character(len=*), intent(in) :: fileName + integer , intent(out) :: rc ! local variables - type(ESMF_Array) :: array + type(ESMF_Array) :: array type(ESMF_ArrayBundle) :: arrayBundle - integer :: tileCount - logical :: isPresent + integer :: tileCount + logical :: isPresent character(len=*), parameter :: subname=' (module_MED_map:med_grid_write) ' !------------------------------------------------------------------------------- diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index cae818903..c191b7121 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -22,16 +22,18 @@ module med_diag_mod use ESMF , only : ESMF_GridComp, ESMF_Clock, ESMF_Time use ESMF , only : ESMF_VM, ESMF_VMReduce, ESMF_REDUCE_SUM use ESMF , only : ESMF_GridCompGet, ESMF_ClockGet, ESMF_TimeGet - use ESMF , only : ESMF_Alarm, ESMF_ClockGetAlarm, ESMF_AlarmIsRinging - use ESMF , only : ESMF_FieldBundle, ESMF_AlarmRingerOff + use ESMF , only : ESMF_Alarm, ESMF_ClockGetAlarm, ESMF_AlarmIsRinging, ESMF_AlarmRingerOff + use ESMF , only : ESMF_FieldBundle, ESMF_Field, ESMF_FieldGet use shr_const_mod , only : shr_const_rearth, shr_const_pi, shr_const_latice use shr_const_mod , only : shr_const_ice_ref_sal, shr_const_ocn_ref_sal, shr_const_isspval 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, logunit, mastertask - use med_methods_mod , only : FB_FldChk => med_methods_FB_FldChk - use med_methods_mod , only : FB_GetFldPtr => med_methods_FB_GetFldPtr - use med_time_mod , only : alarmInit => med_time_alarmInit - use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d + use med_methods_mod , only : fldbun_getdata1d => med_methods_FB_getdata1d + use med_methods_mod , only : fldbun_fldChk => med_methods_FB_FldChk + use med_time_mod , only : alarmInit => med_time_alarmInit + use med_utils_mod , only : chkerr => med_utils_ChkErr + use perf_mod , only : t_startf, t_stopf implicit none private @@ -39,6 +41,7 @@ module med_diag_mod public :: med_diag_init public :: med_diag_zero public :: med_phases_diag_accum + public :: med_phases_diag_print public :: med_phases_diag_atm public :: med_phases_diag_lnd public :: med_phases_diag_rof @@ -46,7 +49,6 @@ module med_diag_mod public :: med_phases_diag_ocn public :: med_phases_diag_ice_ice2med public :: med_phases_diag_ice_med2ice - public :: med_phases_diag_print private :: med_diag_sum_master private :: med_diag_print_atm @@ -56,6 +58,7 @@ module med_diag_mod type, public :: budget_diag_type character(CS) :: name end type budget_diag_type + type, public :: budget_diag_indices type(budget_diag_type), pointer :: comps(:) => null() type(budget_diag_type), pointer :: fields(:) => null() @@ -92,8 +95,8 @@ module med_diag_mod ! C for component ! --------------------------------- - ! "r" is receive from the component to the mediator - ! "s" is send from the mediator to the component + ! "r" is receive by the mediator from the component + ! "s" is send from the mediator to the component integer :: c_atm_send ! model index: atm integer :: c_atm_recv ! model index: atm @@ -205,6 +208,8 @@ module med_diag_mod real(r8), parameter :: HFLXtoWFLX = & ! water flux implied by latent heat of fusion & - (shr_const_ocn_ref_sal-shr_const_ice_ref_sal) / & & (shr_const_ocn_ref_sal*shr_const_latice) + + ! WFLX (kg/m^2s) = -SFLX (kg/m^2s) / ocn_ref_sal (psu) (34.7g/kg) / 1.e-3 kg/g real(r8), parameter :: SFLXtoWFLX = & ! water flux implied by salt flux (kg/m^2s) -1._r8/(shr_const_ocn_ref_sal*1.e-3_r8) @@ -380,6 +385,7 @@ subroutine med_diag_init(gcomp, rc) alarmname='alarm_stop', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return endif + contains integer function get_diag_attribute(gcomp, name, rc) type(ESMF_GridComp) , intent(inout) :: gcomp @@ -408,7 +414,6 @@ end function get_diag_attribute end subroutine med_diag_init !=============================================================================== - subroutine med_diag_zero( gcomp, mode, rc) ! ------------------------------------------------------------------ @@ -428,6 +433,7 @@ subroutine med_diag_zero( gcomp, mode, rc) character(*), parameter :: subName = '(med_diag_zero) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) if (present(mode)) then if (trim(mode) == 'inst') then @@ -495,10 +501,10 @@ subroutine med_diag_zero( gcomp, mode, rc) endif enddo end if + call t_stopf('MED:'//subname) end subroutine med_diag_zero !=============================================================================== - subroutine med_phases_diag_accum(gcomp, rc) ! ------------------------------------------------------------------ @@ -514,15 +520,16 @@ subroutine med_phases_diag_accum(gcomp, rc) character(*), parameter :: subName = '(med_diag_accum) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) rc = ESMF_SUCCESS do ip = period_inst+1,size(budget_diags%periods) budget_local(:,:,ip) = budget_local(:,:,ip) + budget_local(:,:,period_inst) enddo budget_counter(:,:,:) = budget_counter(:,:,:) + 1.0_r8 + call t_stopf('MED:'//subname) end subroutine med_phases_diag_accum !=============================================================================== - subroutine med_diag_sum_master(gcomp, rc) ! ------------------------------------------------------------------ @@ -542,6 +549,7 @@ subroutine med_diag_sum_master(gcomp, rc) character(*), parameter :: subName = '(med_diag_sum_master) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) rc = ESMF_SUCCESS call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) @@ -560,10 +568,11 @@ subroutine med_diag_sum_master(gcomp, rc) budget_global = reshape(budget_global_1d,(/f_size,c_size,p_size/)) budget_local(:,:,:) = 0.0_r8 + call t_stopf('MED:'//subname) + end subroutine med_diag_sum_master !=============================================================================== - subroutine med_phases_diag_atm(gcomp, rc) ! ------------------------------------------------------------------ @@ -585,9 +594,11 @@ subroutine med_phases_diag_atm(gcomp, rc) real(r8), pointer :: ofrac(:) => null() real(r8), pointer :: areas(:) => null() real(r8), pointer :: lats(:) => null() + type(ESMF_Field) :: lfield character(*), parameter :: subName = '(med_phases_diag_atm) ' !------------------------------------------------------------------------------- + call t_startf('MED:'//subname) rc = ESMF_SUCCESS nullify(is_local%wrap) @@ -595,22 +606,24 @@ subroutine med_phases_diag_atm(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! Get fractions on atm mesh - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'lfrac', fldptr1=lfrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ifrac', fldptr1=ifrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compatm), 'ifrac', ifrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compatm), 'ofrac', fldptr1=ofrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compatm)%areas lats => is_local%wrap%mesh_info(compatm)%lats allocate(afrac(size(areas))) afrac = 1.0_R8 + !------------------------------- - ! from atm to mediator + ! from atm to mediator (_recv suffix is what the mediator is receiving) !------------------------------- ip = period_inst + do n = 1,size(afrac) nf = f_area budget_local(nf,c_atm_recv ,ip) = budget_local(nf,c_atm_recv ,ip) - areas(n)*afrac(n) @@ -623,32 +636,35 @@ subroutine med_phases_diag_atm(gcomp, rc) end if end do - call diag_atm(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swnet', f_heat_swnet, & + call diag_atm_recv(is_local%wrap%FBImp(compatm,compatm), 'Faxa_swnet', f_heat_swnet, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call diag_atm(is_local%wrap%FBImp(compatm,compatm), 'Faxa_lwdn', f_heat_lwdn, & + call diag_atm_recv(is_local%wrap%FBImp(compatm,compatm), 'Faxa_lwdn', f_heat_lwdn, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call diag_atm(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc', f_watr_rain, & + ! Note that passing f_watr_rain twice will just add up contributions from Faxa_rainc and Faxa_rainl + call diag_atm_recv(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc', f_watr_rain, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call diag_atm(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainl', f_watr_rain, & + call diag_atm_recv(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainl', f_watr_rain, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call diag_atm(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowc', f_watr_snow, & + ! Note that passing f_watr_rain twice will just add up contributions from Faxa_snowc and Faxa_snowl + call diag_atm_recv(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowc', f_watr_snow, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call diag_atm(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowl', f_watr_snow, & + call diag_atm_recv(is_local%wrap%FBImp(compatm,compatm), 'Faxa_snowl', f_watr_snow, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call diag_atm_wiso(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainl_wiso', & + call diag_atm_wiso_recv(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc_wiso', & f_watr_rain_16O, f_watr_rain_18O, f_watr_rain_HDO, areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call diag_atm_wiso(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainc_wiso', & + call diag_atm_wiso_recv(is_local%wrap%FBImp(compatm,compatm), 'Faxa_rainl_wiso', & f_watr_rain_16O, f_watr_rain_18O, f_watr_rain_HDO, areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! heat implied by snow flux + + ! heat implied by snow flux from atm to mediator budget_local(f_heat_latf,c_atm_recv ,ip) = -budget_local(f_watr_snow,c_atm_recv ,ip)*shr_const_latice budget_local(f_heat_latf,c_lnd_arecv,ip) = -budget_local(f_watr_snow,c_lnd_arecv,ip)*shr_const_latice budget_local(f_heat_latf,c_ocn_arecv,ip) = -budget_local(f_watr_snow,c_ocn_arecv,ip)*shr_const_latice @@ -672,29 +688,29 @@ subroutine med_phases_diag_atm(gcomp, rc) end if end do - call diag_atm(is_local%wrap%FBExp(compatm), 'Faxx_lwup', f_heat_lwup, & + call diag_atm_send(is_local%wrap%FBExp(compatm), 'Faxx_lwup', f_heat_lwup, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call diag_atm(is_local%wrap%FBExp(compatm), 'Faxx_lat', f_heat_latvap, & + call diag_atm_send(is_local%wrap%FBExp(compatm), 'Faxx_lat', f_heat_latvap, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call diag_atm(is_local%wrap%FBExp(compatm), 'Faxx_sen', f_heat_sen, & + call diag_atm_send(is_local%wrap%FBExp(compatm), 'Faxx_sen', f_heat_sen, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call diag_atm(is_local%wrap%FBExp(compatm), 'Faxx_evap', f_watr_evap, & + call diag_atm_send(is_local%wrap%FBExp(compatm), 'Faxx_evap', f_watr_evap, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! water isotopes - call diag_atm_wiso(is_local%wrap%FBImp(compatm,compatm), 'Faxa_evap_wiso', & + call diag_atm_wiso_send(is_local%wrap%FBImp(compatm,compatm), 'Faxa_evap_wiso', & f_watr_evap_16O, f_watr_evap_18O, f_watr_evap_HDO, & areas, lats, afrac, lfrac, ofrac, ifrac, budget_local, rc=rc) - !----------- + call t_stopf('MED:'//subname) + contains - !----------- - subroutine diag_atm(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifrac, budget, rc) + subroutine diag_atm_recv(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifrac, budget, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB character(len=*) , intent(in) :: fldname @@ -709,27 +725,64 @@ subroutine diag_atm(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifrac, bu integer , intent(out) :: rc ! local variables integer :: n, ip + type(ESMF_field) :: lfield real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr1=data , rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata1d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1,size(data) - budget(nf,c_atm_send,ip) = budget(nf,c_atm_send,ip) - areas(n)*afrac(n)*data(n) - budget(nf,c_lnd_asend,ip) = budget(nf,c_lnd_asend,ip) + areas(n)*lfrac(n)*data(n) - budget(nf,c_ocn_asend,ip) = budget(nf,c_ocn_asend,ip) + areas(n)*ofrac(n)*data(n) + budget(nf,c_atm_recv,ip) = budget(nf,c_atm_recv,ip) - areas(n)*data(n)*afrac(n) + budget(nf,c_lnd_arecv,ip) = budget(nf,c_lnd_arecv,ip) + areas(n)*data(n)*lfrac(n) + budget(nf,c_ocn_arecv,ip) = budget(nf,c_ocn_arecv,ip) + areas(n)*data(n)*ofrac(n) if (lats(n) > 0.0_r8) then - budget(nf,c_inh_asend,ip) = budget(nf,c_inh_asend,ip) + areas(n)*ifrac(n)*data(n) + budget(nf,c_inh_arecv,ip) = budget(nf,c_inh_arecv,ip) + areas(n)*data(n)*ifrac(n) else - budget(nf,c_ish_asend,ip) = budget(nf,c_ish_asend,ip) + areas(n)*ifrac(n)*data(n) + budget(nf,c_ish_arecv,ip) = budget(nf,c_ish_arecv,ip) + areas(n)*data(n)*ifrac(n) end if end do end if - end subroutine diag_atm + end subroutine diag_atm_recv - subroutine diag_atm_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, & + subroutine diag_atm_send(FB, fldname, nf, areas, lats, afrac, lfrac, ofrac, ifrac, budget, rc) + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + character(len=*) , intent(in) :: fldname + integer , intent(in) :: nf + real(r8) , intent(in) :: areas(:) + real(r8) , intent(in) :: lats(:) + real(r8) , intent(in) :: afrac(:) + real(r8) , intent(in) :: lfrac(:) + real(r8) , intent(in) :: ofrac(:) + real(r8) , intent(in) :: ifrac(:) + real(r8) , intent(inout) :: budget(:,:,:) + integer , intent(out) :: rc + ! local variables + integer :: n, ip + type(ESMF_field) :: lfield + real(r8), pointer :: data(:) => null() + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata1d(FB, trim(fldname), data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ip = period_inst + do n = 1,size(data) + budget(nf,c_atm_send,ip) = budget(nf,c_atm_send,ip) - areas(n)*data(n)*afrac(n) + budget(nf,c_lnd_asend,ip) = budget(nf,c_lnd_asend,ip) + areas(n)*data(n)*lfrac(n) + budget(nf,c_ocn_asend,ip) = budget(nf,c_ocn_asend,ip) + areas(n)*data(n)*ofrac(n) + if (lats(n) > 0.0_r8) then + budget(nf,c_inh_asend,ip) = budget(nf,c_inh_asend,ip) + areas(n)*data(n)*ifrac(n) + else + budget(nf,c_ish_asend,ip) = budget(nf,c_ish_asend,ip) + areas(n)*data(n)*ifrac(n) + end if + end do + end if + end subroutine diag_atm_send + + subroutine diag_atm_wiso_recv(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, & afrac, lfrac, ofrac, ifrac, budget, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB @@ -747,11 +800,12 @@ subroutine diag_atm_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, & integer , intent(out) :: rc ! local variables integer :: n, ip + type(ESMF_Field) :: lfield real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata2d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1,size(data, dim=2) @@ -783,15 +837,71 @@ subroutine diag_atm_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, & end if end do end if - end subroutine diag_atm_wiso + end subroutine diag_atm_wiso_recv + + subroutine diag_atm_wiso_send(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, & + afrac, lfrac, ofrac, ifrac, budget, rc) + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + character(len=*) , intent(in) :: fldname + integer , intent(in) :: nf_16O + integer , intent(in) :: nf_18O + integer , intent(in) :: nf_HDO + real(r8) , intent(in) :: areas(:) + real(r8) , intent(in) :: lats(:) + real(r8) , intent(in) :: afrac(:) + real(r8) , intent(in) :: lfrac(:) + real(r8) , intent(in) :: ofrac(:) + real(r8) , intent(in) :: ifrac(:) + real(r8) , intent(inout) :: budget(:,:,:) + integer , intent(out) :: rc + ! local variables + integer :: n, ip + type(ESMF_Field) :: lfield + real(r8), pointer :: data(:,:) => null() + ! ------------------------------------------------------------------ + rc = ESMF_SUCCESS + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata2d(FB, trim(fldname), data, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ip = period_inst + do n = 1,size(data, dim=2) + budget(nf_16O,c_atm_send,ip) = budget(nf_16O,c_atm_send,ip) - areas(n)*afrac(n)*data(1,n) + budget(nf_16O,c_lnd_asend,ip) = budget(nf_16O,c_lnd_asend,ip) + areas(n)*lfrac(n)*data(1,n) + budget(nf_16O,c_ocn_asend,ip) = budget(nf_16O,c_ocn_asend,ip) + areas(n)*ofrac(n)*data(1,n) + if (lats(n) > 0.0_r8) then + budget(nf_16O,c_inh_asend,ip) = budget(nf_16O,c_inh_asend,ip) + areas(n)*ifrac(n)*data(1,n) + else + budget(nf_16O,c_ish_asend,ip) = budget(nf_16O,c_ish_asend,ip) + areas(n)*ifrac(n)*data(1,n) + end if + + budget(nf_18O,c_atm_send,ip) = budget(nf_18O,c_atm_send,ip) - areas(n)*afrac(n)*data(2,n) + budget(nf_18O,c_lnd_asend,ip) = budget(nf_18O,c_lnd_asend,ip) + areas(n)*lfrac(n)*data(2,n) + budget(nf_18O,c_ocn_asend,ip) = budget(nf_18O,c_ocn_asend,ip) + areas(n)*ofrac(n)*data(2,n) + if (lats(n) > 0.0_r8) then + budget(nf_18O,c_inh_asend,ip) = budget(nf_18O,c_inh_asend,ip) + areas(n)*ifrac(n)*data(2,n) + else + budget(nf_18O,c_ish_asend,ip) = budget(nf_18O,c_ish_asend,ip) + areas(n)*ifrac(n)*data(2,n) + end if + + budget(nf_HDO,c_atm_send,ip) = budget(nf_HDO,c_atm_send,ip) - areas(n)*afrac(n)*data(3,n) + budget(nf_HDO,c_lnd_asend,ip) = budget(nf_HDO,c_lnd_asend,ip) + areas(n)*lfrac(n)*data(3,n) + budget(nf_HDO,c_ocn_asend,ip) = budget(nf_HDO,c_ocn_asend,ip) + areas(n)*ofrac(n)*data(3,n) + if (lats(n) > 0.0_r8) then + budget(nf_HDO,c_inh_asend,ip) = budget(nf_HDO,c_inh_asend,ip) + areas(n)*ifrac(n)*data(3,n) + else + budget(nf_HDO,c_ish_asend,ip) = budget(nf_HDO,c_ish_asend,ip) + areas(n)*ifrac(n)*data(3,n) + end if + end do + end if + end subroutine diag_atm_wiso_send end subroutine med_phases_diag_atm !=============================================================================== - subroutine med_phases_diag_lnd( gcomp, rc) - ! ------------------------------------------------------------------ + ! ------------------------------------------------------------------ ! Compute global lnd input/output flux diagnostics ! ------------------------------------------------------------------ @@ -806,9 +916,11 @@ subroutine med_phases_diag_lnd( gcomp, rc) real(r8), pointer :: lfrac(:) => null() integer :: n,ip, ic real(r8), pointer :: areas(:) => null() + type(ESMF_Field) :: lfield character(*), parameter :: subName = '(med_phases_diag_lnd) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) rc = ESMF_SUCCESS nullify(is_local%wrap) @@ -816,7 +928,7 @@ subroutine med_phases_diag_lnd( gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! get fractions on lnd mesh - call FB_getFldPtr(is_local%wrap%FBfrac(complnd), 'lfrac', lfrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(complnd), 'lfrac', lfrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(complnd)%areas @@ -887,10 +999,10 @@ subroutine med_phases_diag_lnd( gcomp, rc) budget_local(f_heat_ioff,ic,ip) = -budget_local(f_watr_ioff,ic,ip)*shr_const_latice budget_local(f_heat_latf,ic,ip) = -budget_local(f_watr_snow,ic,ip)*shr_const_latice - !----------- - contains - !----------- + call t_stopf('MED:'//subname) + + contains subroutine diag_lnd(FB, fldname, nf, ic, areas, lfrac, budget, minus, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB @@ -904,12 +1016,13 @@ subroutine diag_lnd(FB, fldname, nf, ic, areas, lfrac, budget, minus, rc) integer , intent(out) :: rc ! local variables integer :: n, ip + type(ESMF_field) :: lfield real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata1d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data) @@ -937,12 +1050,13 @@ subroutine diag_lnd_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, lfrac, integer , intent(out) :: rc ! local variables integer :: n, ip + type(ESMF_field) :: lfield real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata2d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data, dim=2) @@ -962,7 +1076,6 @@ end subroutine diag_lnd_wiso end subroutine med_phases_diag_lnd !=============================================================================== - subroutine med_phases_diag_rof( gcomp, rc) ! ------------------------------------------------------------------ @@ -982,6 +1095,7 @@ subroutine med_phases_diag_rof( gcomp, rc) character(*), parameter :: subName = '(med_phases_diag_rof) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) rc = ESMF_SUCCESS nullify(is_local%wrap) @@ -1031,10 +1145,10 @@ subroutine med_phases_diag_rof( gcomp, rc) f_watr_ioff_16O, f_watr_ioff_18O, f_watr_ioff_HDO, ic, areas, budget_local, rc=rc) budget_local(f_heat_ioff,ic,ip) = -budget_local(f_watr_ioff,ic,ip)*shr_const_latice - !----------- - contains - !----------- + call t_stopf('MED:'//subname) + + contains subroutine diag_rof(FB, fldname, nf, ic, areas, budget, minus, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB @@ -1048,12 +1162,13 @@ subroutine diag_rof(FB, fldname, nf, ic, areas, budget, minus, rc) ! local variables integer :: n, ip + type(ESMF_field) :: lfield real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata1d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data) @@ -1081,12 +1196,13 @@ subroutine diag_rof_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, budget, ! local variables integer :: n, ip + type(ESMF_field) :: lfield real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata2d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data, dim=2) @@ -1106,14 +1222,13 @@ end subroutine diag_rof_wiso end subroutine med_phases_diag_rof !=============================================================================== - subroutine med_phases_diag_glc( gcomp, rc) ! ------------------------------------------------------------------ ! Compute global glc output ! ------------------------------------------------------------------ - use esmFlds, only : compglc + use esmFlds, only : compglc, num_icesheets ! input/output variables type(ESMF_GridComp) :: gcomp @@ -1121,36 +1236,39 @@ subroutine med_phases_diag_glc( gcomp, rc) ! local variables type(InternalState) :: is_local - integer :: ic, ip + integer :: ic, ip, ns real(r8), pointer :: areas(:) => null() character(*), parameter :: subName = '(med_phases_diag_glc) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) rc = ESMF_SUCCESS nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - areas => is_local%wrap%mesh_info(compglc)%areas !------------------------------- ! from glc to mediator !------------------------------- + ! TODO: this will not be correct if there is more than 1 ice sheet ic = c_glc_send ip = period_inst - call diag_glc(is_local%wrap%FBImp(compglc,compglc), 'Fogg_rofl', f_watr_roff, ic, areas, budget_local, minus=.true., rc=rc) - call diag_glc(is_local%wrap%FBImp(compglc,compglc), 'Fogg_rofi', f_watr_ioff, ic, areas, budget_local, minus=.true., rc=rc) - call diag_glc(is_local%wrap%FBImp(compglc,compglc), 'Figg_rofi', f_watr_ioff, ic, areas, budget_local, minus=.true., rc=rc) + do ns = 1,num_icesheets + areas => is_local%wrap%mesh_info(compglc(ns))%areas + call diag_glc(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 'Fogg_rofl', f_watr_roff, ic, areas, budget_local, minus=.true., rc=rc) + call diag_glc(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 'Fogg_rofi', f_watr_ioff, ic, areas, budget_local, minus=.true., rc=rc) + call diag_glc(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 'Figg_rofi', f_watr_ioff, ic, areas, budget_local, minus=.true., rc=rc) + end do budget_local(f_heat_ioff,ic,ip) = -budget_local(f_watr_ioff,ic,ip)*shr_const_latice - !----------- - contains - !----------- + call t_stopf('MED:'//subname) + contains subroutine diag_glc(FB, fldname, nf, ic, areas, budget, minus, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB @@ -1163,11 +1281,12 @@ subroutine diag_glc(FB, fldname, nf, ic, areas, budget, minus, rc) integer , intent(out) :: rc ! local variables integer :: n, ip + type(ESMF_field) :: lfield real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata1d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data) @@ -1183,7 +1302,6 @@ end subroutine diag_glc end subroutine med_phases_diag_glc !=============================================================================== - subroutine med_phases_diag_ocn( gcomp, rc) ! ------------------------------------------------------------------ @@ -1205,18 +1323,20 @@ subroutine med_phases_diag_ocn( gcomp, rc) real(r8), pointer :: sfrac(:) => null() ! sum of ifrac and ofrac real(r8), pointer :: areas(:) => null() real(r8), pointer :: data(:) => null() + type(ESMF_field) :: lfield character(*), parameter :: subName = '(med_phases_diag_ocn) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) rc = ESMF_SUCCESS nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compocn), 'ifrac', fldptr1=ifrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compocn), 'ifrac', ifrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compocn), 'ofrac', fldptr1=ofrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compocn), 'ofrac', ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(sfrac(size(ofrac))) sfrac(:) = ifrac(:) + ofrac(:) @@ -1233,8 +1353,8 @@ subroutine med_phases_diag_ocn( gcomp, rc) budget_local(f_area,ic,ip) = budget_local(f_area,ic,ip) + areas(n)*ofrac(n) end do - if ( FB_fldchk(is_local%wrap%FBImp(compocn,compocn), 'Fioo_q', rc=rc)) then - call FB_getFldPtr(is_local%wrap%FBImp(compocn,compocn), 'Fioo_q', fldptr1=data, rc=rc) + if ( fldbun_fldchk(is_local%wrap%FBImp(compocn,compocn), 'Fioo_q', rc=rc)) then + call fldbun_getdata1d(is_local%wrap%FBImp(compocn,compocn), 'Fioo_q', data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do n = 1,size(ifrac) wgt_o = areas(n) * ofrac(n) @@ -1272,7 +1392,8 @@ subroutine med_phases_diag_ocn( gcomp, rc) call diag_ocn(is_local%wrap%FBExp(compocn), 'Fioi_bergw', f_watr_melt , ic, areas, sfrac, budget_local, rc=rc) call diag_ocn(is_local%wrap%FBExp(compocn), 'Fioi_melth', f_heat_melt , ic, areas, sfrac, budget_local, rc=rc) call diag_ocn(is_local%wrap%FBExp(compocn), 'Fioi_bergh', f_heat_melt , ic, areas, sfrac, budget_local, rc=rc) - call diag_ocn(is_local%wrap%FBExp(compocn), 'Fioi_salt' , f_watr_salt , ic, areas, sfrac, budget_local, rc=rc) + call diag_ocn(is_local%wrap%FBExp(compocn), 'Fioi_salt' , f_watr_salt , ic, areas, sfrac, budget_local, & + scale=SFLXtoWFLX, rc=rc) call diag_ocn(is_local%wrap%FBExp(compocn), 'Foxx_swnet', f_heat_swnet , ic, areas, sfrac, budget_local, rc=rc) call diag_ocn(is_local%wrap%FBExp(compocn), 'Faxa_lwdn' , f_heat_lwdn , ic, areas, sfrac, budget_local, rc=rc) call diag_ocn(is_local%wrap%FBExp(compocn), 'Faxa_rain' , f_watr_rain , ic, areas, sfrac, budget_local, rc=rc) @@ -1293,11 +1414,12 @@ subroutine med_phases_diag_ocn( gcomp, rc) budget_local(f_heat_latf,ic,ip) = -budget_local(f_watr_snow,ic,ip)*shr_const_latice budget_local(f_heat_ioff,ic,ip) = -budget_local(f_watr_ioff,ic,ip)*shr_const_latice - !----------- + + call t_stopf('MED:'//subname) + contains - !----------- - subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, rc) + subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, scale, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB character(len=*) , intent(in) :: fldname @@ -1306,18 +1428,24 @@ subroutine diag_ocn(FB, fldname, nf, ic, areas, frac, budget, rc) real(r8) , intent(in) :: areas(:) real(r8) , intent(in) :: frac(:) real(r8) , intent(inout) :: budget(:,:,:) + real(r8), optional , intent(in) :: scale integer , intent(out) :: rc ! local variables integer :: n, ip + type(ESMF_field) :: lfield real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr1=data, rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata1d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data) - budget(nf,ic,ip) = budget(nf,ic,ip) + areas(n)*frac(n)*data(n) + if (present(scale)) then + budget(nf,ic,ip) = budget(nf,ic,ip) + areas(n)*frac(n)*data(n)*scale + else + budget(nf,ic,ip) = budget(nf,ic,ip) + areas(n)*frac(n)*data(n) + end if end do end if end subroutine diag_ocn @@ -1337,12 +1465,12 @@ subroutine diag_ocn_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, ic, areas, frac, b ! local variables integer :: n, ip + type(ESMF_field) :: lfield real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata2d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data, dim=2) @@ -1356,7 +1484,6 @@ end subroutine diag_ocn_wiso end subroutine med_phases_diag_ocn !=============================================================================== - subroutine med_phases_diag_ice_ice2med( gcomp, rc) ! ------------------------------------------------------------------ @@ -1376,18 +1503,20 @@ subroutine med_phases_diag_ice_ice2med( gcomp, rc) real(r8), pointer :: ifrac(:) => null() real(r8), pointer :: areas(:) => null() real(r8), pointer :: lats(:) => null() + type(ESMF_field) :: lfield character(*), parameter :: subName = '(med_phases_diag_ice_ice2med) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) rc = ESMF_SUCCESS nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ifrac', fldptr1=ifrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBFrac(compice), 'ifrac', ifrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ofrac', fldptr1=ofrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBFrac(compice), 'ofrac', ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compice)%areas @@ -1404,34 +1533,35 @@ subroutine med_phases_diag_ice_ice2med( gcomp, rc) budget_local(f_area ,ic,ip) = budget_local(f_area ,ic,ip) + areas(n)*ifrac(n) end do - call diag_ice(is_local%wrap%FBImp(compice,compice), 'Fioi_melth', f_heat_melt, & + call diag_ice_recv(is_local%wrap%FBImp(compice,compice), 'Fioi_melth', f_heat_melt, & areas, lats, ifrac, budget_local, minus=.true., rc=rc) - call diag_ice(is_local%wrap%FBImp(compice,compice), 'Fioi_meltw', f_watr_melt, & + call diag_ice_recv(is_local%wrap%FBImp(compice,compice), 'Fioi_meltw', f_watr_melt, & areas, lats, ifrac, budget_local, minus=.true., rc=rc) - call diag_ice(is_local%wrap%FBImp(compice,compice), 'Fioi_salt', f_watr_salt, & + call diag_ice_recv(is_local%wrap%FBImp(compice,compice), 'Fioi_salt', f_watr_salt, & areas, lats, ifrac, budget_local, minus=.true., scale=SFLXtoWFLX, rc=rc) - call diag_ice(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen', f_heat_swnet, & + call diag_ice_recv(is_local%wrap%FBImp(compice,compice), 'Fioi_swpen', f_heat_swnet, & areas, lats, ifrac, budget_local, minus=.true., rc=rc) - call diag_ice(is_local%wrap%FBImp(compice,compice), 'Faii_swnet', f_heat_swnet, & + call diag_ice_recv(is_local%wrap%FBImp(compice,compice), 'Faii_swnet', f_heat_swnet, & areas, lats, ifrac, budget_local, rc=rc) - call diag_ice(is_local%wrap%FBImp(compice,compice), 'Faii_lwup', f_heat_lwup, & + call diag_ice_recv(is_local%wrap%FBImp(compice,compice), 'Faii_lwup', f_heat_lwup, & areas, lats, ifrac, budget_local, rc=rc) - call diag_ice(is_local%wrap%FBImp(compice,compice), 'Faii_lat', f_heat_latvap, & + call diag_ice_recv(is_local%wrap%FBImp(compice,compice), 'Faii_lat', f_heat_latvap, & areas, lats, ifrac, budget_local, rc=rc) - call diag_ice(is_local%wrap%FBImp(compice,compice), 'Faii_sen', f_heat_sen, & + call diag_ice_recv(is_local%wrap%FBImp(compice,compice), 'Faii_sen', f_heat_sen, & areas, lats, ifrac, budget_local, rc=rc) - call diag_ice(is_local%wrap%FBImp(compice,compice), 'Faii_evap', f_watr_evap, & + call diag_ice_recv(is_local%wrap%FBImp(compice,compice), 'Faii_evap', f_watr_evap, & areas, lats, ifrac, budget_local, rc=rc) - call diag_ice_wiso(is_local%wrap%FBImp(compice,compice), 'Fioi_meltw_wiso', & + call diag_ice_recv_wiso(is_local%wrap%FBImp(compice,compice), 'Fioi_meltw_wiso', & f_watr_melt_16O, f_watr_melt_18O, f_watr_melt_HDO, areas, lats, ifrac, budget_local, rc=rc) - call diag_ice_wiso(is_local%wrap%FBImp(compice,compice), 'Faii_evap_wiso', & + call diag_ice_recv_wiso(is_local%wrap%FBImp(compice,compice), 'Faii_evap_wiso', & f_watr_evap_16O, f_watr_evap_18O, f_watr_evap_HDO, areas, lats, ifrac, budget_local, rc=rc) - !----------- + + call t_stopf('MED:'//subname) + contains - !----------- - subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, rc) + subroutine diag_ice_recv(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB character(len=*) , intent(in) :: fldname @@ -1445,11 +1575,12 @@ subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, r integer , intent(out) :: rc ! local variables integer :: n, ip + type(ESMF_Field) :: lfield real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr1=data , rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata1d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1,size(data) @@ -1473,9 +1604,9 @@ subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, r end if end do end if - end subroutine diag_ice + end subroutine diag_ice_recv - subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac, budget, minus, rc) + subroutine diag_ice_recv_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac, budget, minus, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB character(len=*) , intent(in) :: fldname @@ -1488,15 +1619,15 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac real(r8) , intent(inout) :: budget(:,:,:) logical, optional , intent(in) :: minus integer , intent(out) :: rc - ! local variables integer :: n, ip + type(ESMF_Field) :: lfield real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata2d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data, dim=2) @@ -1516,13 +1647,11 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac end if end do end if - end subroutine diag_ice_wiso - + end subroutine diag_ice_recv_wiso end subroutine med_phases_diag_ice_ice2med !=============================================================================== - subroutine med_phases_diag_ice_med2ice( gcomp, rc) ! ------------------------------------------------------------------ @@ -1544,18 +1673,20 @@ subroutine med_phases_diag_ice_med2ice( gcomp, rc) real(r8), pointer :: data(:) => null() real(r8), pointer :: areas(:) => null() real(r8), pointer :: lats(:) => null() + type(ESMF_Field) :: lfield character(*), parameter :: subName = '(med_phases_diag_ice_med2ice) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) rc = ESMF_SUCCESS nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ifrac', fldptr1=ifrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compice), 'ifrac', ifrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call FB_getFldPtr(is_local%wrap%FBfrac(compice), 'ofrac', fldptr1=ofrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compice), 'ofrac', ofrac, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return areas => is_local%wrap%mesh_info(compice)%areas @@ -1572,18 +1703,13 @@ subroutine med_phases_diag_ice_med2ice( gcomp, rc) budget_local(f_area ,ic,ip) = budget_local(f_area ,ic,ip) + areas(n)*ifrac(n) end do - call diag_ice(is_local%wrap%FBExp(compice), 'Faxa_lwdn', f_heat_lwdn, areas, lats, ifrac, budget_local, rc=rc) - call diag_ice(is_local%wrap%FBExp(compice), 'Faxa_rain', f_watr_rain, areas, lats, ifrac, budget_local, rc=rc) - call diag_ice(is_local%wrap%FBExp(compice), 'Faxa_snow', f_watr_snow, areas, lats, ifrac, budget_local, rc=rc) - call diag_ice(is_local%wrap%FBExp(compice), 'Fixx_rofi', f_watr_ioff, areas, lats, ifrac, budget_local, rc=rc) + call diag_ice_send(is_local%wrap%FBExp(compice), 'Faxa_lwdn', f_heat_lwdn, areas, lats, ifrac, budget_local, rc=rc) + call diag_ice_send(is_local%wrap%FBExp(compice), 'Faxa_rain', f_watr_rain, areas, lats, ifrac, budget_local, rc=rc) + call diag_ice_send(is_local%wrap%FBExp(compice), 'Faxa_snow', f_watr_snow, areas, lats, ifrac, budget_local, rc=rc) + call diag_ice_send(is_local%wrap%FBExp(compice), 'Fixx_rofi', f_watr_ioff, areas, lats, ifrac, budget_local, rc=rc) - call diag_ice_wiso(is_local%wrap%FBExp(compice), 'Faxa_rain_wiso', & - f_watr_rain_16O, f_watr_rain_18O, f_watr_rain_HDO, areas, lats, ifrac, budget_local, rc=rc) - call diag_ice_wiso(is_local%wrap%FBExp(compice), 'Faxa_snow_wiso', & - f_watr_snow_16O, f_watr_snow_18O, f_watr_snow_HDO, areas, lats, ifrac, budget_local, rc=rc) - - if ( FB_fldchk(is_local%wrap%FBExp(compice), 'Fioo_q', rc=rc)) then - call FB_getFldPtr(is_local%wrap%FBExp(compice), 'Fioo_q', fldptr1=data, rc=rc) + if ( fldbun_fldchk(is_local%wrap%FBExp(compice), 'Fioo_q', rc=rc)) then + call fldbun_getdata1d(is_local%wrap%FBExp(compice), 'Fioo_q', data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do n = 1,size(data) wgt_o = areas(n) * ofrac(n) @@ -1607,11 +1733,16 @@ subroutine med_phases_diag_ice_med2ice( gcomp, rc) budget_local(f_heat_ioff,ic,ip) = -budget_local(f_watr_ioff,ic,ip)*shr_const_latice budget_local(f_watr_frz ,ic,ip) = budget_local(f_heat_frz ,ic,ip)*HFLXtoWFLX - !----------- + call diag_ice_send_wiso(is_local%wrap%FBExp(compice), 'Faxa_rain_wiso', & + f_watr_rain_16O, f_watr_rain_18O, f_watr_rain_HDO, areas, lats, ifrac, budget_local, rc=rc) + call diag_ice_send_wiso(is_local%wrap%FBExp(compice), 'Faxa_snow_wiso', & + f_watr_snow_16O, f_watr_snow_18O, f_watr_snow_HDO, areas, lats, ifrac, budget_local, rc=rc) + + call t_stopf('MED:'//subname) + contains - !----------- - subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, rc) + subroutine diag_ice_send(FB, fldname, nf, areas, lats, ifrac, budget, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB character(len=*) , intent(in) :: fldname @@ -1620,42 +1751,29 @@ subroutine diag_ice(FB, fldname, nf, areas, lats, ifrac, budget, minus, scale, r real(r8) , intent(in) :: lats(:) real(r8) , intent(in) :: ifrac(:) real(r8) , intent(inout) :: budget(:,:,:) - logical, optional , intent(in) :: minus - real(r8), optional , intent(in) :: scale integer , intent(out) :: rc ! local variables integer :: n, ip + type(ESMF_Field) :: lfield real(r8), pointer :: data(:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr1=data , rc=rc) + ip = period_inst + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata1d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ip = period_inst do n = 1,size(data) if (lats(n) > 0.0_r8) then - ic = c_inh_recv + ic = c_inh_send else - ic = c_ish_recv + ic = c_ish_send endif - if (present(minus)) then - if (present(scale)) then - budget(nf ,ic,ip) = budget(nf ,ic,ip) - areas(n)*ifrac(n)*data(n)*scale - else - budget(nf ,ic,ip) = budget(nf ,ic,ip) - areas(n)*ifrac(n)*data(n) - end if - else - if (present(scale)) then - budget(nf ,ic,ip) = budget(nf ,ic,ip) + areas(n)*ifrac(n)*data(n)*scale - else - budget(nf ,ic,ip) = budget(nf ,ic,ip) + areas(n)*ifrac(n)*data(n) - end if - end if + budget(nf,ic,ip) = budget(nf,ic,ip) + areas(n)*ifrac(n)*data(n) end do end if - end subroutine diag_ice + end subroutine diag_ice_send - subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac, budget, minus, rc) + subroutine diag_ice_send_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac, budget, rc) ! input/output variables type(ESMF_FieldBundle) , intent(in) :: FB character(len=*) , intent(in) :: fldname @@ -1666,42 +1784,34 @@ subroutine diag_ice_wiso(FB, fldname, nf_16O, nf_18O, nf_HDO, areas, lats, ifrac real(r8) , intent(in) :: lats(:) real(r8) , intent(in) :: ifrac(:) real(r8) , intent(inout) :: budget(:,:,:) - logical, optional , intent(in) :: minus integer , intent(out) :: rc ! local variables integer :: n, ip + type(ESMF_Field) :: lfield real(r8), pointer :: data(:,:) => null() ! ------------------------------------------------------------------ rc = ESMF_SUCCESS - - if ( FB_fldchk(FB, trim(fldname), rc=rc)) then - call FB_GetFldPtr(FB, trim(fldname), fldptr2=data, rc=rc) + if ( fldbun_fldchk(FB, trim(fldname), rc=rc)) then + call fldbun_getdata2d(FB, trim(fldname), data, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ip = period_inst do n = 1, size(data, dim=2) if (lats(n) > 0.0_r8) then - ic = c_inh_recv + ic = c_inh_send else - ic = c_ish_recv + ic = c_ish_send endif - if (present(minus)) then - budget(nf_16O,ic,ip) = budget(nf_16O,ic,ip) - areas(n)*ifrac(n)*data(1,n) - budget(nf_18O,ic,ip) = budget(nf_18O,ic,ip) - areas(n)*ifrac(n)*data(2,n) - budget(nf_HDO,ic,ip) = budget(nf_HDO,ic,ip) - areas(n)*ifrac(n)*data(3,n) - else - budget(nf_16O,ic,ip) = budget(nf_16O,ic,ip) + areas(n)*ifrac(n)*data(1,n) - budget(nf_18O,ic,ip) = budget(nf_18O,ic,ip) + areas(n)*ifrac(n)*data(2,n) - budget(nf_HDO,ic,ip) = budget(nf_HDO,ic,ip) + areas(n)*ifrac(n)*data(3,n) - end if + budget(nf_16O,ic,ip) = budget(nf_16O,ic,ip) + areas(n)*ifrac(n)*data(1,n) + budget(nf_18O,ic,ip) = budget(nf_18O,ic,ip) + areas(n)*ifrac(n)*data(2,n) + budget(nf_HDO,ic,ip) = budget(nf_HDO,ic,ip) + areas(n)*ifrac(n)*data(3,n) end do end if - end subroutine diag_ice_wiso + end subroutine diag_ice_send_wiso end subroutine med_phases_diag_ice_med2ice !=============================================================================== - subroutine med_phases_diag_print(gcomp, rc) ! ------------------------------------------------------------------ @@ -1756,10 +1866,12 @@ subroutine med_phases_diag_print(gcomp, rc) write(logunit,' (a)') trim(subname)//": currtime = "//trim(currtimestr) endif #endif - if(firstcall) then + + if (firstcall) then firstcall = .false. return endif + sumdone = .false. do ip = 1,size(budget_diags%periods) @@ -1838,6 +1950,7 @@ subroutine med_phases_diag_print(gcomp, rc) deallocate(datagpr) endif ! output_level > 0 and mastertask end if ! if mastertask + !------------------------------------------------------------------------------- ! Zero budget data !------------------------------------------------------------------------------- @@ -1848,7 +1961,6 @@ subroutine med_phases_diag_print(gcomp, rc) end subroutine med_phases_diag_print !=============================================================================== - subroutine med_diag_print_atm(data, ip, cdate, curr_tod) ! --------------------------------------------------------- @@ -1866,7 +1978,7 @@ subroutine med_diag_print_atm(data, ip, cdate, curr_tod) integer :: ica,icl integer :: icn,ics,ico character(len=40) :: str ! string - character(*), parameter:: subName = '(med_phases_diag_print_level3) ' + character(*), parameter:: subName = '(med_phases_diag_print_atm) ' ! ------------------------------------------------------------------ do ic = 1,2 @@ -1997,7 +2109,6 @@ subroutine med_diag_print_atm(data, ip, cdate, curr_tod) end subroutine med_diag_print_atm !=============================================================================== - subroutine med_diag_print_lnd_ice_ocn(data, ip, cdate, curr_tod) ! --------------------------------------------------------- @@ -2015,7 +2126,7 @@ subroutine med_diag_print_lnd_ice_ocn(data, ip, cdate, curr_tod) integer :: icar,icas integer :: icxs,icxr character(len=40) :: str ! string - character(*), parameter :: subName = '(med_diag_print_lnd_ocn_ice) ' + character(*), parameter :: subName = '(med_diag_print_lnd_ice_ocn) ' ! ------------------------------------------------------------------ do ic = 1,4 @@ -2160,7 +2271,6 @@ subroutine med_diag_print_lnd_ice_ocn(data, ip, cdate, curr_tod) end subroutine med_diag_print_lnd_ice_ocn !=============================================================================== - subroutine med_diag_print_summary(data, ip, cdate, curr_tod) ! --------------------------------------------------------- @@ -2198,6 +2308,7 @@ subroutine med_diag_print_summary(data, ip, cdate, curr_tod) character(*), parameter:: subName = '(med_diag_print_summary) ' ! ------------------------------------------------------------------ + call t_startf('MED:'//subname) ! write out areas write(logunit,*) ' ' @@ -2352,10 +2463,10 @@ subroutine med_diag_print_summary(data, ip, cdate, curr_tod) end do end if + call t_stopf('MED:'//subname) end subroutine med_diag_print_summary !=============================================================================== - subroutine add_to_budget_diag(entries, index, name) ! input/output variablesn diff --git a/mediator/med_fraction_mod.F90 b/mediator/med_fraction_mod.F90 index bbcd7e388..26dec3237 100644 --- a/mediator/med_fraction_mod.F90 +++ b/mediator/med_fraction_mod.F90 @@ -89,24 +89,27 @@ module med_fraction_mod ! Note that the following FBImp field names are current hard-wired below ! TODO: this needs to be generalized - these names should be set dynamically at run time in the ! source component - ! is_local%wrap%FBImp(compglc,compglc) => 'frac' - ! is_local%wrap%FBImp(complnd,complnd) => 'Sl_lfrin' - ! is_local%wrap%FBImp(compice,compice) => 'Si_imask' - ! is_local%wrap%FBImp(compocn,compocn) => 'So_omask' - ! is_local%wrap%FBImp(compice,compice) => 'Si_ifrac' (runtime) + ! is_local%wrap%FBImp(compglc,compglc(:)) => 'frac' + ! is_local%wrap%FBImp(complnd,complnd) => 'Sl_lfrin' + ! is_local%wrap%FBImp(compice,compice) => 'Si_imask' + ! is_local%wrap%FBImp(compocn,compocn) => 'So_omask' + ! is_local%wrap%FBImp(compice,compice) => 'Si_ifrac' (runtime) ! !----------------------------------------------------------------------------- - 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 : dbug_flag => med_constants_dbug_flag - use med_constants_mod , only : czero => med_constants_czero - use med_utils_mod , only : chkErr => med_utils_ChkErr - use med_methods_mod , only : FB_init => med_methods_FB_init - use med_methods_mod , only : FB_reset => med_methods_FB_reset - use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_fldChk => med_methods_FB_fldChk + 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 : dbug_flag => med_constants_dbug_flag + use med_constants_mod , only : czero => med_constants_czero + use med_utils_mod , only : chkErr => med_utils_ChkErr + 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_getdata2d => med_methods_FB_getdata2d + use med_methods_mod , only : fldbun_getdata1d => med_methods_FB_getdata1d + use med_methods_mod , only : fldbun_init => med_methods_FB_init + use med_methods_mod , only : fldbun_reset => med_methods_FB_reset use med_map_mod , only : med_map_field - use esmFlds , only : ncomps + use esmFlds , only : ncomps, max_icesheets, num_icesheets implicit none private @@ -171,9 +174,9 @@ subroutine med_fraction_init(gcomp, rc) real(R8), pointer :: Sl_lfrin(:) => null() real(R8), pointer :: Si_imask(:) => null() real(R8), pointer :: So_omask(:) => null() - integer :: i,j,n,n1 + integer :: i,j,n,n1,ns integer :: maptype - logical, save :: first_call = .true. + logical, save :: first_call = .true. character(len=*),parameter :: subname=' (med_fraction_init)' !--------------------------------------- @@ -201,7 +204,9 @@ subroutine med_fraction_init(gcomp, rc) fraclist(1:size(fraclist_l),complnd) = fraclist_l fraclist(1:size(fraclist_r),comprof) = fraclist_r fraclist(1:size(fraclist_w),compwav) = fraclist_w - fraclist(1:size(fraclist_g),compglc) = fraclist_g + do ns = 1,num_icesheets + fraclist(1:size(fraclist_g),compglc(ns)) = fraclist_g + end do !--------------------------------------- ! Create field bundles and initialize them to zero @@ -213,10 +218,10 @@ subroutine med_fraction_init(gcomp, rc) if ( is_local%wrap%comp_present(n1) .and. & ESMF_StateIsCreated(is_local%wrap%NStateImp(n1),rc=rc)) then ! create FBFrac and zero out FBfrac(n1) - call FB_init(is_local%wrap%FBfrac(n1), is_local%wrap%flds_scalar_name, & + call fldbun_init(is_local%wrap%FBfrac(n1), is_local%wrap%flds_scalar_name, & STgeom=is_local%wrap%NStateImp(n1), fieldNameList=fraclist(:,n1), & name='FBfrac'//trim(compname(n1)), rc=rc) - call FB_reset(is_local%wrap%FBfrac(n1), value=czero, rc=rc) + call fldbun_reset(is_local%wrap%FBfrac(n1), value=czero, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end do @@ -229,15 +234,9 @@ subroutine med_fraction_init(gcomp, rc) !--------------------------------------- if (is_local%wrap%comp_present(complnd)) then - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd) , fieldname='Sl_lfrin', & - field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=Sl_lfrin, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBImp(complnd,complnd) , 'Sl_lfrin', Sl_lfrin, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(complnd) , fieldname='lfrac', & - field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=lfrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBFrac(complnd) , 'lfrac', lfrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return lfrac(:) = Sl_lfrin(:) end if @@ -249,15 +248,9 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compice)) then ! Set 'ifrac' FBFrac(compice) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compice,compice) , fieldname='Si_imask', & - field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=Si_imask, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBImp(compice,compice), 'Si_imask', Si_imask, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compice) , fieldname='ifrac', & - field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=ifrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBFrac(compice), 'ifrac', ifrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ifrac(:) = Si_imask(:) @@ -298,20 +291,15 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compocn)) then ! Set 'ofrac' in FBFrac(compocn) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compocn,compocn), fieldName='So_omask', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=So_omask, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compocn), fieldName='ofrac', field=lfield, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBImp(compocn,compocn), 'So_omask', So_omask, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=ofrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBFrac(compocn), 'ofrac', ofrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ofrac(:) = So_omask(:) ! Set 'ofrac' in FBFrac(compatm) - at this point this is the ocean mask mapped to the atm grid ! This is mapping the ocean mask to the atm grid - so in effect it is (1-land fraction) on the atm grid if (is_local%wrap%comp_present(compatm) .and. is_local%wrap%med_coupling_active(compocn,compatm)) then - if (med_map_RH_is_created(is_local%wrap%RH(compocn,compatm,:),mapfcopy, rc=rc)) then ! If ocn and atm are on the same mesh - a redist route handle has already been created maptype = mapfcopy @@ -366,6 +354,7 @@ subroutine med_fraction_init(gcomp, rc) call med_map_field(field_src, field_dst, is_local%wrap%RH(compatm,complnd,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if + !--------------------------------------- ! Set 'lfrac' in FBFrac(compatm) and correct 'ofrac' in FBFrac(compatm) ! --------------------------------------- @@ -379,13 +368,9 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compocn) .or. is_local%wrap%comp_present(compice)) then ! Ocean is present - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), 'lfrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=lfrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), 'ofrac', field=lfield, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=ofrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (is_local%wrap%comp_present(complnd)) then do n = 1,size(lfrac) @@ -422,13 +407,9 @@ subroutine med_fraction_init(gcomp, rc) call med_map_field(field_src, field_dst, is_local%wrap%RH(complnd,compatm,:), maptype, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), 'lfrac', field=lfield, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compatm), 'lfrac', lfrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=lfrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compatm), 'ofrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=ofrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compatm), 'ofrac', ofrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return do n = 1,size(lfrac) ofrac(n) = 1.0_R8 - lfrac(n) @@ -447,22 +428,15 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(comprof)) then ! Set 'rfrac' in FBFrac(comprof) - if ( FB_FldChk(is_local%wrap%FBfrac(comprof) , 'rfrac', rc=rc) .and. & - FB_FldChk(is_local%wrap%FBImp(comprof,comprof), 'frac' , rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBImp(comprof,comprof), 'frac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=frac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(comprof), 'rfrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=rfrac, rc=rc) + if ( fldbun_fldchk(is_local%wrap%FBfrac(comprof) , 'rfrac', rc=rc) .and. & + fldbun_fldchk(is_local%wrap%FBImp(comprof,comprof), 'frac' , rc=rc)) then + call fldbun_getdata1d(is_local%wrap%FBImp(comprof,comprof), 'frac', frac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call fldbun_getdata1d(is_local%wrap%FBfrac(comprof), 'rfrac', rfrac, rc) rfrac(:) = frac(:) else ! Set 'rfrac' in FBfrac(comprof) to 1. - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(comprof), 'rfrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=rfrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(comprof), 'rfrac', rfrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return rfrac(:) = 1.0_R8 endif @@ -490,47 +464,43 @@ subroutine med_fraction_init(gcomp, rc) ! Set 'gfrac' and 'lfrac' for FBFrac(compglc) !--------------------------------------- - if (is_local%wrap%comp_present(compglc)) then - ! Set 'gfrac' in FBFrac(compglc) - if ( FB_FldChk(is_local%wrap%FBfrac(compglc) , 'gfrac', rc=rc) .and. & - FB_FldChk(is_local%wrap%FBImp(compglc, compglc), 'frac' , rc=rc)) then - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), 'frac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=frac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compglc), 'gfrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=gfrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - gfrac(:) = frac(:) - else - ! Set 'gfrac' in FBfrac(compglc) to 1. - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compglc), 'gfrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=gfrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (ChkErr(rc,__LINE__,u_FILE_u)) return - gfrac(:) = 1.0_R8 - endif + do ns = 1,num_icesheets + if (is_local%wrap%comp_present(compglc(ns))) then - ! Set 'lfrac' in FBFrac(compglc) - if ( is_local%wrap%comp_present(complnd) .and. is_local%wrap%med_coupling_active(complnd,compglc)) then - maptype = mapconsd - if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compglc,:),maptype, rc=rc)) then - call med_map_routehandles_init( complnd, compglc, & - FBSrc=is_local%wrap%FBImp(complnd,complnd), & - FBDst=is_local%wrap%FBImp(complnd,compglc), & - mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) + ! Set 'gfrac' in FBFrac(compglc(ns)) + if ( fldbun_fldchk(is_local%wrap%FBfrac(compglc(ns)) , 'gfrac', rc=rc) .and. & + fldbun_fldchk(is_local%wrap%FBImp(compglc(ns), compglc(ns)), 'frac' , rc=rc)) then + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 'frac', frac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(complnd), 'lfrac', field=field_src, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compglc), 'lfrac', field=field_dst, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_map_field(field_src, field_dst, is_local%wrap%RH(complnd,compglc,:), maptype, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + call fldbun_getdata1d(is_local%wrap%FBfrac(compglc(ns)), 'gfrac', gfrac, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + gfrac(:) = frac(:) + else + ! Set 'gfrac' in FBfrac(compglc(ns)) to 1. + call fldbun_getdata1d(is_local%wrap%FBfrac(compglc(ns)), 'gfrac', gfrac, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + gfrac(:) = 1.0_R8 + endif + + ! Set 'lfrac' in FBFrac(compglc(ns)) + if ( is_local%wrap%comp_present(complnd) .and. is_local%wrap%med_coupling_active(complnd,compglc(ns))) then + maptype = mapconsd + if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compglc(ns),:),maptype, rc=rc)) then + call med_map_routehandles_init( complnd, compglc(ns), & + FBSrc=is_local%wrap%FBImp(complnd,complnd), & + FBDst=is_local%wrap%FBImp(complnd,compglc(ns)), & + mapindex=maptype, RouteHandle=is_local%wrap%RH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(complnd), 'lfrac', field=field_src, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compglc(ns)), 'lfrac', field=field_dst, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call med_map_field(field_src, field_dst, is_local%wrap%RH(complnd,compglc(ns),:), maptype, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + endif endif - endif + end do !--------------------------------------- ! Set 'wfrac' for FBFrac(compwav) @@ -538,9 +508,7 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compwav)) then ! Set 'wfrac' in FBfrac(compwav) to 1. - call ESMF_FieldBundleGet(is_local%wrap%FBfrac(compwav), 'wfrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=wfrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBfrac(compwav), 'wfrac', wfrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return wfrac(:) = 1.0_R8 endif @@ -552,7 +520,7 @@ subroutine med_fraction_init(gcomp, rc) if (is_local%wrap%comp_present(compice) .and. is_local%wrap%comp_present(compocn)) then if (.not. med_map_RH_is_created(is_local%wrap%RH(compice,compocn,:),mapfcopy, rc=rc)) then if (.not. ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(compice,compocn))) then - call FB_init(is_local%wrap%FBImp(compice,compocn), is_local%wrap%flds_scalar_name, & + call fldbun_init(is_local%wrap%FBImp(compice,compocn), is_local%wrap%flds_scalar_name, & STgeom=is_local%wrap%NStateImp(compocn), & STflds=is_local%wrap%NStateImp(compice), & name='FBImp'//trim(compname(compice))//'_'//trim(compname(compocn)), rc=rc) @@ -566,7 +534,7 @@ subroutine med_fraction_init(gcomp, rc) end if if (.not. med_map_RH_is_created(is_local%wrap%RH(compocn,compice,:),mapfcopy, rc=rc)) then if (.not. ESMF_FieldBundleIsCreated(is_local%wrap%FBImp(compocn,compice))) then - call FB_init(is_local%wrap%FBImp(compocn,compice), is_local%wrap%flds_scalar_name, & + call fldbun_init(is_local%wrap%FBImp(compocn,compice), is_local%wrap%flds_scalar_name, & STgeom=is_local%wrap%NStateImp(compice), & STflds=is_local%wrap%NStateImp(compocn), & name='FBImp'//trim(compname(compocn))//'_'//trim(compname(compice)), rc=rc) @@ -587,8 +555,7 @@ subroutine med_fraction_init(gcomp, rc) if (dbug_flag > 1) then do n = 1,ncomps if (ESMF_FieldBundleIsCreated(is_local%wrap%FBfrac(n),rc=rc)) then - call FB_diagnose(is_local%wrap%FBfrac(n), & - trim(subname) // trim(compname(n)), rc=rc) + call fldbun_diagnose(is_local%wrap%FBfrac(n), trim(subname) // trim(compname(n)), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end do @@ -663,23 +630,13 @@ subroutine med_fraction_set(gcomp, rc) ! Si_imask is the ice domain mask which is constant over time ! Si_ifrac is the time evolving ice fraction on the ice grid - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compice,compice), fieldName='Si_ifrac', field=lfield, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBImp(compice,compice), 'Si_ifrac', Si_ifrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=Si_ifrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBImp(compice,compice), 'Si_imask', Si_imask, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compice,compice), fieldName='Si_imask', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=Si_imask, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compice), fieldName='ifrac', field=lfield, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=ifrac, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(compice), fieldName='ofrac', field=lfield, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBFrac(compice), 'ifrac', ifrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayPtr=ofrac, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBFrac(compice), 'ofrac', ofrac, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! set ifrac = Si_ifrac * Si_imask @@ -763,7 +720,7 @@ subroutine med_fraction_set(gcomp, rc) if (dbug_flag > 1) then do n = 1,ncomps if (ESMF_FieldBundleIsCreated(is_local%wrap%FBfrac(n),rc=rc)) then - call FB_diagnose(is_local%wrap%FBfrac(n), trim(subname) // trim(compname(n))//' frac', rc=rc) + call fldbun_diagnose(is_local%wrap%FBfrac(n), trim(subname) // trim(compname(n))//' frac', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if enddo diff --git a/mediator/med_internalstate_mod.F90 b/mediator/med_internalstate_mod.F90 index f07ca8995..83558c9d1 100644 --- a/mediator/med_internalstate_mod.F90 +++ b/mediator/med_internalstate_mod.F90 @@ -17,30 +17,8 @@ module med_internalstate_mod logical, public :: mastertask=.false. ! is this the mastertask integer, public :: med_id ! needed currently in med_io_mod and set in esm.F90 - ! Active coupling definitions - ! This defines the med_mapping_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. As new connections - ! are allowed, just update the table below. - ! - the rows are the destination of coupling - ! - the columns are the source of coupling - ! - So, the second column indicates which models the atm is coupled to. - ! - And the second row indicates which models are coupled to the atm. - ! The mediator is not connected to any components because the mediator - ! doesn't have it's own grid and only acts as a hub. - - ! tcraig, turned off glc2ocn and glc2ice for time being - logical, public, parameter :: med_coupling_allowed(ncomps,ncomps) = & - reshape([ .false., .false., .false., .false., .false., .false., .false., .false., & ! med - .false., .false., .true. , .true. , .true. , .false., .false., .false., & ! atm - .false., .true. , .false., .false., .false., .true. , .false., .true. , & ! lnd - .false., .true. , .false., .false., .true. , .true. , .true. , .false., & ! ocn - .false., .true. , .false., .true. , .false., .true. , .false., .false., & ! ice - .false., .false., .true. , .false., .false., .false., .false., .false., & ! rof - .false., .true. , .false., .true. , .true. , .false., .false., .false., & ! wav - .false., .false., .true. , .false., .false., .false., .false., .false. ], & ! glc - shape(med_coupling_allowed)) - ! med atm lnd ocn ice rof wav glc + ! Active coupling definitions (will be initialize in med.F90) + logical, public :: med_coupling_allowed(ncomps, ncomps) type, public :: mesh_info_type real(r8), pointer :: areas(:) => null() @@ -121,10 +99,8 @@ module med_internalstate_mod end type InternalStateStruct - type, public :: InternalState + type, public :: InternalState type(InternalStateStruct), pointer :: wrap end type InternalState - !----------------------------------------------------------------------------- - end module med_internalstate_mod diff --git a/mediator/med_io_mod.F90 b/mediator/med_io_mod.F90 index 770229263..0a4fa7753 100644 --- a/mediator/med_io_mod.F90 +++ b/mediator/med_io_mod.F90 @@ -1,4 +1,5 @@ module med_io_mod + !------------------------------------------ ! Create mediator history files !------------------------------------------ @@ -12,9 +13,12 @@ module med_io_mod use NUOPC , only : NUOPC_FieldDictionaryGetEntry use NUOPC , only : NUOPC_FieldDictionaryHasEntry use pio , only : file_desc_t, iosystem_desc_t - use med_internalstate_mod , only : logunit - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag - use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_internalstate_mod , only : logunit, med_id + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN + use med_methods_mod , only : FB_getFldPtr => med_methods_FB_getFldPtr + use med_methods_mod , only : FB_getNameN => med_methods_FB_getNameN + use med_utils_mod , only : chkerr => med_utils_ChkErr implicit none private @@ -121,9 +125,7 @@ subroutine med_io_init() ! initialize pio !--------------- - use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat - use med_internalstate_mod , only : med_id - + use shr_pio_mod , only : shr_pio_getiosys, shr_pio_getiotype, shr_pio_getioformat #ifdef INTERNAL_PIO_INIT ! if CMEPS is the only component using PIO, then it needs to initialize PIO use shr_pio_mod , only : shr_pio_init1, shr_pio_init2 @@ -433,10 +435,11 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & integer :: ndims, nelements integer ,target :: dimid2(2) integer ,target :: dimid3(3) - integer ,pointer :: dimid(:) => null() + integer ,pointer :: dimid(:) type(var_desc_t) :: varid type(io_desc_t) :: iodesc integer(kind=Pio_Offset_Kind) :: frame + character(CL) :: itemc ! string converted to char character(CL) :: name1 ! var name character(CL) :: cunit ! var units character(CL) :: lname ! long name @@ -446,13 +449,13 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & logical :: luse_float integer :: lnx,lny real(r8) :: lfillvalue - integer, pointer :: minIndexPTile(:,:) => null() - integer, pointer :: maxIndexPTile(:,:) => null() + integer, pointer :: minIndexPTile(:,:) + integer, pointer :: maxIndexPTile(:,:) integer :: dimCount, tileCount - integer, pointer :: Dof(:) => null() + integer, pointer :: Dof(:) integer :: lfile_ind - real(r8), pointer :: fldptr1(:) => null() - real(r8), pointer :: fldptr2(:,:) => null() + real(r8), pointer :: fldptr1(:) + real(r8), pointer :: fldptr2(:,:) real(r8), allocatable :: ownedElemCoords(:), ownedElemCoords_x(:), ownedElemCoords_y(:) character(len=number_strlen) :: cnumber character(CL) :: tmpstr @@ -461,8 +464,6 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields integer :: gridToFieldMap(1) ! currently the size must equal 1 for rank 2 fields logical :: isPresent - character(CL) , pointer :: fieldnamelist(:) => null() - type(ESMF_Field), pointer :: fieldlist(:) => null() character(*),parameter :: subName = '(med_io_write_FB) ' !------------------------------------------------------------------------------- @@ -505,16 +506,11 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & luse_float = .false. if (present(use_float)) luse_float = use_float + lfile_ind = 0 if (present(file_ind)) lfile_ind=file_ind call ESMF_FieldBundleGet(FB, fieldCount=nf, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(fieldnamelist(nf)) - allocate(fieldlist(nf)) - call ESMF_FieldBundleGet(FB, fieldnamelist=fieldnamelist, fieldlist=fieldlist, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - write(tmpstr,*) subname//' field count = '//trim(lpre),nf call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) if (nf < 1) then @@ -526,12 +522,18 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & return endif - call ESMF_FieldGet(fieldlist(1), mesh=mesh, rc=rc) + call FB_getFieldN(FB, 1, field, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + + call ESMF_FieldGet(field, mesh=mesh, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh, elementDistgrid=distgrid, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh, spatialDim=ndims, numOwnedElements=nelements, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + write(tmpstr,*) subname, 'ndims, nelements = ', ndims, nelements call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) @@ -539,14 +541,17 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & allocate(ownedElemCoords(ndims*nelements)) allocate(ownedElemCoords_x(ndims*nelements/2)) allocate(ownedElemCoords_y(ndims*nelements/2)) + call ESMF_MeshGet(mesh, ownedElemCoords=ownedElemCoords, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + ownedElemCoords_x = ownedElemCoords(1::2) ownedElemCoords_y = ownedElemCoords(2::2) end if call ESMF_DistGridGet(distgrid, dimCount=dimCount, tileCount=tileCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(minIndexPTile(dimCount, tileCount), maxIndexPTile(dimCount, tileCount)) call ESMF_DistGridGet(distgrid, minIndexPTile=minIndexPTile, maxIndexPTile=maxIndexPTile, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -596,64 +601,72 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & write(tmpstr,*) subname,' dimid = ',dimid call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - ! TODO (mvertens, 2019-03-13): below is a temporary mod to NOT write hgt do k = 1,nf - if (trim(fieldnamelist(k)) == "hgt") then - CYCLE - end if + call FB_getNameN(FB, k, itemc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(fieldlist(k), ungriddedUBound=ungriddedUbound, rc=rc) + ! Determine rank of field with name itemc + call ESMF_FieldBundleGet(FB, itemc, field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUbound(1) > 0) then - ! Create a new output variable for each element of the undistributed dimension - write(cnumber,'(i0)') ungriddedUbound(1) - call ESMF_LogWrite(trim(subname)//':'//'field '//trim(fieldnamelist(k))// & - ' has an griddedUBound of '//trim(cnumber), ESMF_LOGMSG_INFO) - do n = 1,ungriddedUBound(1) - if (trim(fieldnamelist(k)) /= "hgt") then - write(cnumber,'(i0)') n - name1 = trim(lpre)//'_'//trim(fieldnamelist(k))//trim(cnumber) - call ESMF_LogWrite(trim(subname)//': defining '//trim(name1), ESMF_LOGMSG_INFO) - if (luse_float) then - rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_REAL, dimid, varid) - rcode = pio_put_att(io_file(lfile_ind), varid,"_FillValue",real(lfillvalue,r4)) - else - rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_DOUBLE, dimid, varid) - rcode = pio_put_att(io_file(lfile_ind),varid,"_FillValue",lfillvalue) - end if - if (NUOPC_FieldDictionaryHasEntry(trim(fieldnamelist(k)))) then - call NUOPC_FieldDictionaryGetEntry(fieldnamelist(k), canonicalUnits=cunit, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - rcode = pio_put_att(io_file(lfile_ind), varid, "units" , trim(cunit)) - end if - rcode = pio_put_att(io_file(lfile_ind), varid, "standard_name", trim(name1)) - if (present(tavg)) then - if (tavg) then - rcode = pio_put_att(io_file(lfile_ind), varid, "cell_methods", "time: mean") + call ESMF_FieldGet(lfield, rank=rank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! TODO (mvertens, 2019-03-13): this is a temporary mod to NOT write hgt + if (trim(itemc) /= "hgt") then + if (rank == 2) then + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + write(cnumber,'(i0)') ungriddedUbound(1) + call ESMF_LogWrite(trim(subname)//':'//'field '//trim(itemc)// & + ' has an griddedUBound of '//trim(cnumber), ESMF_LOGMSG_INFO) + + ! Create a new output variable for each element of the undistributed dimension + do n = 1,ungriddedUBound(1) + if (trim(itemc) /= "hgt") then + write(cnumber,'(i0)') n + name1 = trim(lpre)//'_'//trim(itemc)//trim(cnumber) + call ESMF_LogWrite(trim(subname)//': defining '//trim(name1), ESMF_LOGMSG_INFO) + if (luse_float) then + rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_REAL, dimid, varid) + rcode = pio_put_att(io_file(lfile_ind), varid,"_FillValue",real(lfillvalue,r4)) + else + rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_DOUBLE, dimid, varid) + rcode = pio_put_att(io_file(lfile_ind),varid,"_FillValue",lfillvalue) + end if + if (NUOPC_FieldDictionaryHasEntry(trim(itemc))) then + call NUOPC_FieldDictionaryGetEntry(itemc, canonicalUnits=cunit, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + rcode = pio_put_att(io_file(lfile_ind), varid, "units" , trim(cunit)) + end if + rcode = pio_put_att(io_file(lfile_ind), varid, "standard_name", trim(name1)) + if (present(tavg)) then + if (tavg) then + rcode = pio_put_att(io_file(lfile_ind), varid, "cell_methods", "time: mean") + endif endif + end if + end do + else + name1 = trim(lpre)//'_'//trim(itemc) + call ESMF_LogWrite(trim(subname)//':'//trim(itemc)//':'//trim(name1),ESMF_LOGMSG_INFO) + if (luse_float) then + rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_REAL, dimid, varid) + rcode = pio_put_att(io_file(lfile_ind), varid, "_FillValue", real(lfillvalue, r4)) + else + rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_DOUBLE, dimid, varid) + rcode = pio_put_att(io_file(lfile_ind), varid, "_FillValue", lfillvalue) + end if + if (NUOPC_FieldDictionaryHasEntry(trim(itemc))) then + call NUOPC_FieldDictionaryGetEntry(itemc, canonicalUnits=cunit, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + rcode = pio_put_att(io_file(lfile_ind), varid, "units", trim(cunit)) + end if + rcode = pio_put_att(io_file(lfile_ind), varid, "standard_name", trim(name1)) + if (present(tavg)) then + if (tavg) then + rcode = pio_put_att(io_file(lfile_ind), varid, "cell_methods", "time: mean") endif end if - end do - else - name1 = trim(lpre)//'_'//trim(fieldnamelist(k)) - call ESMF_LogWrite(trim(subname)//':'//trim(fieldnamelist(k))//':'//trim(name1),ESMF_LOGMSG_INFO) - if (luse_float) then - rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_REAL, dimid, varid) - rcode = pio_put_att(io_file(lfile_ind), varid, "_FillValue", real(lfillvalue, r4)) - else - rcode = pio_def_var(io_file(lfile_ind), trim(name1), PIO_DOUBLE, dimid, varid) - rcode = pio_put_att(io_file(lfile_ind), varid, "_FillValue", lfillvalue) - end if - if (NUOPC_FieldDictionaryHasEntry(trim(fieldnamelist(k)))) then - call NUOPC_FieldDictionaryGetEntry(fieldnamelist(k), canonicalUnits=cunit, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - rcode = pio_put_att(io_file(lfile_ind), varid, "units", trim(cunit)) - end if - rcode = pio_put_att(io_file(lfile_ind), varid, "standard_name", trim(name1)) - if (present(tavg)) then - if (tavg) then - rcode = pio_put_att(io_file(lfile_ind), varid, "cell_methods", "time: mean") - endif end if end if end do @@ -685,6 +698,7 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & end if if (lwdata) then + ! use distgrid extracted from field 1 above call ESMF_DistGridGet(distgrid, localDE=0, elementCount=ns, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -694,36 +708,51 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) call pio_initdecomp(io_subsystem, pio_double, (/lnx,lny/), dof, iodesc) + ! call pio_writedof(lpre, (/lnx,lny/), int(dof,kind=PIO_OFFSET_KIND), mpicom) + deallocate(dof) - ! TODO (mvertens, 2019-03-13): below is a temporary mod to NOT write hgt do k = 1,nf - if (trim(fieldnamelist(k)) == "hgt") then - CYCLE - end if - call ESMF_FieldGet(fieldlist(k), ungriddedUBound=ungriddedUbound, rc=rc) + call FB_getNameN(FB, k, itemc, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ungriddedUbound(1) > 0) then - ! Output for each ungriddedUbound index - call ESMF_FieldGet(fieldlist(k), farrayPtr=fldptr2, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,ungriddedUBound(1) - write(cnumber,'(i0)') n - name1 = trim(lpre)//'_'//trim(fieldnamelist(k))//trim(cnumber) + + call FB_getFldPtr(FB, itemc, & + fldptr1=fldptr1, fldptr2=fldptr2, rank=rank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! TODO (mvertens, 2019-03-13): this is a temporary mod to NOT write hgt + if (trim(itemc) /= "hgt") then + if (rank == 2) then + + ! Determine the size of the ungridded dimension and the index where the undistributed dimension is located + call ESMF_FieldBundleGet(FB, itemc, field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, gridToFieldMap=gridToFieldMap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! Output for each ungriddedUbound index + do n = 1,ungriddedUBound(1) + write(cnumber,'(i0)') n + name1 = trim(lpre)//'_'//trim(itemc)//trim(cnumber) + rcode = pio_inq_varid(io_file(lfile_ind), trim(name1), varid) + call pio_setframe(io_file(lfile_ind),varid,frame) + + if (gridToFieldMap(1) == 1) then + call pio_write_darray(io_file(lfile_ind), varid, iodesc, fldptr2(:,n), rcode, fillval=lfillvalue) + else if (gridToFieldMap(1) == 2) then + call pio_write_darray(io_file(lfile_ind), varid, iodesc, fldptr2(n,:), rcode, fillval=lfillvalue) + end if + end do + else if (rank == 1) then + name1 = trim(lpre)//'_'//trim(itemc) rcode = pio_inq_varid(io_file(lfile_ind), trim(name1), varid) call pio_setframe(io_file(lfile_ind),varid,frame) - call pio_write_darray(io_file(lfile_ind), varid, iodesc, fldptr2(n,:), rcode, fillval=lfillvalue) - end do - else - call ESMF_FieldGet(fieldlist(k), farrayPtr=fldptr1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - name1 = trim(lpre)//'_'//trim(fieldnamelist(k)) - rcode = pio_inq_varid(io_file(lfile_ind), trim(name1), varid) - call pio_setframe(io_file(lfile_ind),varid,frame) - call pio_write_darray(io_file(lfile_ind), varid, iodesc, fldptr1, rcode, fillval=lfillvalue) - end if ! end of if over ungriddedUbound - end do ! end loop over fields + call pio_write_darray(io_file(lfile_ind), varid, iodesc, fldptr1, rcode, fillval=lfillvalue) + end if ! end if rank is 2 or 1 + + end if ! end if not "hgt" + end do ! end loop over fields in FB ! Fill coordinate variables name1 = trim(lpre)//'_lon' @@ -740,9 +769,6 @@ subroutine med_io_write_FB(filename, iam, FB, whead, wdata, nx, ny, nt, & call pio_freedecomp(io_file(lfile_ind), iodesc) endif - deallocate(fieldlist) - deallocate(fieldnamelist) - if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) endif @@ -1201,7 +1227,7 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) use ESMF , only : ESMF_LOGMSG_ERROR, ESMF_FAILURE use ESMF , only : ESMF_FieldBundleIsCreated, ESMF_FieldBundleGet use ESMF , only : ESMF_FieldGet, ESMF_MeshGet, ESMF_DistGridGet - use pio , only : file_desc_t, var_desc_t, io_desc_t, pio_nowrite, pio_openfile + use pio , only : file_desc_T, var_desc_t, io_desc_t, pio_nowrite, pio_openfile use pio , only : pio_noerr, PIO_BCAST_ERROR, PIO_INTERNAL_ERROR use pio , only : pio_inq_varid use pio , only : pio_double, pio_get_att, pio_seterrorhandling, pio_freedecomp, pio_closefile @@ -1224,28 +1250,24 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) type(file_desc_t) :: pioid type(var_desc_t) :: varid type(io_desc_t) :: iodesc + character(CL) :: itemc ! string converted to char character(CL) :: name1 ! var name character(CL) :: lpre ! local prefix real(r8) :: lfillvalue integer :: tmp(1) integer :: rank, lsize - real(r8), pointer :: fldptr1(:) => null() - real(r8), pointer :: fldptr1_tmp(:) => null() - real(r8), pointer :: fldptr2(:,:) => null() + real(r8), pointer :: fldptr1(:), fldptr1_tmp(:) + real(r8), pointer :: fldptr2(:,:) character(CL) :: tmpstr character(len=16) :: cnumber integer(kind=Pio_Offset_Kind) :: lframe - integer :: ungriddedUBound(1) - character(CL) , pointer :: fieldnamelist(:) => null() - type(ESMF_Field), pointer :: fieldlist(:) => null() + integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fieldds + integer :: gridToFieldMap(1) ! currently the size must equal 1 for rank 2 fieldds character(*),parameter :: subName = '(med_io_read_FB) ' !------------------------------------------------------------------------------- rc = ESMF_Success - - if (dbug_flag > 5) then - call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return - end if + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) + if (chkerr(rc,__LINE__,u_FILE_u)) return lpre = ' ' if (present(pre)) then @@ -1256,34 +1278,31 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) else lframe = 1 endif - if (.not. ESMF_FieldBundleIsCreated(FB,rc=rc)) then call ESMF_LogWrite(trim(subname)//" FB "//trim(lpre)//" not created", ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + if (chkerr(rc,__LINE__,u_FILE_u)) return + endif return endif call ESMF_FieldBundleGet(FB, fieldCount=nf, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + write(tmpstr,*) subname//' field count = '//trim(lpre),nf + call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + if (chkerr(rc,__LINE__,u_FILE_u)) return if (nf < 1) then call ESMF_LogWrite(trim(subname)//" FB "//trim(lpre)//" empty", ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + if (chkerr(rc,__LINE__,u_FILE_u)) return + endif return endif - allocate(fieldnamelist(nf)) - allocate(fieldlist(nf)) - call ESMF_FieldBundleGet(FB, fieldnamelist=fieldnamelist, fieldlist=fieldlist, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - write(tmpstr,*) subname//' field count = '//trim(lpre),nf - call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! Check if file exists if (med_io_file_exists(vm, iam, trim(filename))) then rcode = pio_openfile(io_subsystem, pioid, pio_iotype, trim(filename),pio_nowrite) call ESMF_LogWrite(trim(subname)//' open file '//trim(filename), ESMF_LOGMSG_INFO) @@ -1298,35 +1317,57 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) call pio_seterrorhandling(pioid, PIO_BCAST_ERROR) do k = 1,nf - call ESMF_FieldGet(fieldlist(k), ungriddedUBound=ungriddedUbound, rc=rc) + ! Get name of field + call FB_getNameN(FB, k, itemc, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Get iodesc for all fields based on iodesc of first field (assumes that all fields have ! the same iodesc) if (k == 1) then - if (ungriddedUbound(1) > 0) then - name1 = trim(lpre)//'_'//trim(fieldnamelist(k))//'1' - else - name1 = trim(lpre)//'_'//trim(fieldnamelist(k)) + call ESMF_FieldBundleGet(FB, itemc, field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, rank=rank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (rank == 2) then + name1 = trim(lpre)//'_'//trim(itemc)//'1' + else if (rank == 1) then + name1 = trim(lpre)//'_'//trim(itemc) end if call med_io_read_init_iodesc(FB, name1, pioid, iodesc, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return end if - call ESMF_LogWrite(trim(subname)//' reading field '//trim(fieldnamelist(k)), ESMF_LOGMSG_INFO) + + call ESMF_LogWrite(trim(subname)//' reading field '//trim(itemc), ESMF_LOGMSG_INFO) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Get pointer to field bundle field - if (ungriddedUbound(1) > 0) then - ! Ungridded dimension is present in field - call ESMF_FieldGet(fieldlist(k), farrayPtr=fldptr2, rc=rc) + ! Field bundle might be 2d or 1d - but field on mediator history or restart file will always be 1d + call FB_getFldPtr(FB, itemc, & + fldptr1=fldptr1, fldptr2=fldptr2, rank=rank, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (rank == 2) then + + ! Determine the size of the ungridded dimension and the + ! index where the undistributed dimension is located + call ESMF_FieldBundleGet(FB, itemc, field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - lsize = size(fldptr2, dim=2) + call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound, gridToFieldMap=gridToFieldMap, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + if (gridToFieldMap(1) == 1) then + lsize = size(fldptr2, dim=1) + else if (gridToFieldMap(1) == 2) then + lsize = size(fldptr2, dim=2) + end if allocate(fldptr1_tmp(lsize)) + do n = 1,ungriddedUBound(1) ! Creat a name for the 1d field on the mediator history or restart file based on the ! ungridded dimension index of the field bundle 2d fiedl write(cnumber,'(i0)') n - name1 = trim(lpre)//'_'//trim(fieldnamelist(k))//trim(cnumber) + name1 = trim(lpre)//'_'//trim(itemc)//trim(cnumber) + rcode = pio_inq_varid(pioid, trim(name1), varid) if (rcode == pio_noerr) then call ESMF_LogWrite(trim(subname)//' read field '//trim(name1), ESMF_LOGMSG_INFO) @@ -1343,14 +1384,18 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) else fldptr1_tmp = 0.0_r8 endif - fldptr2(n,:) = fldptr1_tmp(:) + if (gridToFieldMap(1) == 1) then + fldptr2(:,n) = fldptr1_tmp(:) + else if (gridToFieldMap(1) == 2) then + fldptr2(n,:) = fldptr1_tmp(:) + end if end do + deallocate(fldptr1_tmp) - else - ! No ungridded dimensions - call ESMF_FieldGet(fieldlist(k), farrayPtr=fldptr1, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - name1 = trim(lpre)//'_'//trim(fieldnamelist(k)) + + else if (rank == 1) then + name1 = trim(lpre)//'_'//trim(itemc) + rcode = pio_inq_varid(pioid, trim(name1), varid) if (rcode == pio_noerr) then call ESMF_LogWrite(trim(subname)//' read field '//trim(name1), ESMF_LOGMSG_INFO) @@ -1365,12 +1410,13 @@ subroutine med_io_read_FB(filename, vm, iam, FB, pre, frame, rc) if (fldptr1(n) == lfillvalue) fldptr1(n) = 0.0_r8 enddo else - fldptr1(:) = 0.0_r8 + fldptr1 = 0.0_r8 endif end if enddo ! end of loop over fields call pio_seterrorhandling(pioid,PIO_INTERNAL_ERROR) + call pio_freedecomp(pioid, iodesc) call pio_closefile(pioid) @@ -1406,17 +1452,16 @@ subroutine med_io_read_init_iodesc(FB, name1, pioid, iodesc, rc) integer :: rcode integer :: ns,ng integer :: n,ndims - integer, pointer :: dimid(:) => null() + integer, pointer :: dimid(:) type(var_desc_t) :: varid integer :: lnx,lny integer :: tmp(1) - integer, pointer :: minIndexPTile(:,:) => null() - integer, pointer :: maxIndexPTile(:,:) => null() + integer, pointer :: minIndexPTile(:,:) + integer, pointer :: maxIndexPTile(:,:) integer :: dimCount, tileCount - integer, pointer :: Dof(:) => null() + integer, pointer :: Dof(:) character(CL) :: tmpstr - integer :: fieldcount - type(ESMF_Field), pointer :: fieldlist(:) => null() + integer :: rank character(*),parameter :: subName = '(med_io_read_init_iodesc) ' !------------------------------------------------------------------------------- @@ -1445,17 +1490,18 @@ subroutine med_io_read_init_iodesc(FB, name1, pioid, iodesc, rc) call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) ng = lnx * lny - call ESMF_FieldBundleGet(FB, fieldCount=fieldcount, rc=rc) + call FB_getFieldN(FB, 1, field, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist(fieldcount)) - call ESMF_FieldBundleGet(FB, fieldlist=fieldlist, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(fieldlist(1), mesh=mesh, rc=rc) + + call ESMF_FieldGet(field, mesh=mesh, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_MeshGet(mesh, elementDistgrid=distgrid, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_DistGridGet(distgrid, dimCount=dimCount, tileCount=tileCount, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + allocate(minIndexPTile(dimCount, tileCount), maxIndexPTile(dimCount, tileCount)) call ESMF_DistGridGet(distgrid, minIndexPTile=minIndexPTile, & maxIndexPTile=maxIndexPTile, rc=rc) @@ -1478,11 +1524,11 @@ subroutine med_io_read_init_iodesc(FB, name1, pioid, iodesc, rc) call ESMF_DistGridGet(distgrid, localDE=0, seqIndexList=dof, rc=rc) write(tmpstr,*) subname,' dof = ',ns,size(dof),dof(1),dof(ns) !,minval(dof),maxval(dof) call ESMF_LogWrite(trim(tmpstr), ESMF_LOGMSG_INFO) + call pio_initdecomp(io_subsystem, pio_double, (/lnx,lny/), dof, iodesc) deallocate(dof) deallocate(minIndexPTile, maxIndexPTile) - deallocate(fieldlist) end if ! end if rcode check diff --git a/mediator/med_map_mod.F90 b/mediator/med_map_mod.F90 index 85e9a720d..2467d56a3 100644 --- a/mediator/med_map_mod.F90 +++ b/mediator/med_map_mod.F90 @@ -176,7 +176,7 @@ subroutine med_map_routehandles_initfrom_fieldbundle(n1, n2, FBsrc, FBdst, mapin ! local variables type(ESMF_Field) :: fldsrc type(ESMF_Field) :: flddst - character(len=*), parameter :: subname=' (module_MED_map:med_map_routehandles_init_fields) ' + character(len=*), parameter :: subname=' (module_MED_map:med_map_routehandles_initfrom_fieldbundle) ' !--------------------------------------------- call t_startf('MED:'//subname) @@ -246,9 +246,6 @@ subroutine med_map_routehandles_initfrom_field(n1, n2, fldsrc, flddst, mapindex, end if mapname = trim(mapnames(mapindex)) - if (mastertask) then - write(6,*)'DEBUG: mapindex, mapname= ',mapindex,trim(mapname) - end if if (trim(coupling_mode) == 'cesm') then dstMaskValue = ispval_mask @@ -406,7 +403,7 @@ logical function med_map_RH_is_created_RH3d(RHs,n1,n2,mapindex,rc) ! local variables integer :: rc1, rc2 - character(len=*), parameter :: subname=' (module_MED_map:med_map_RH_is_created) ' + character(len=*), parameter :: subname=' (module_MED_map:med_map_RH_is_created_RH3d) ' !----------------------------------------------------------- rc = ESMF_SUCCESS @@ -616,7 +613,7 @@ subroutine med_map_packed_field_create(destcomp, flds_scalar_name, & type(ESMF_Field), pointer :: fieldlist_src(:) => null() type(ESMF_Field), pointer :: fieldlist_dst(:) => null() character(CL), allocatable :: fieldNameList(:) - character(len=*), parameter :: subname=' (module_MED_map:med_packed_fieldbundles_create) ' + character(len=*), parameter :: subname=' (module_MED_map:med_packed_field_create) ' !----------------------------------------------------------- rc = ESMF_SUCCESS diff --git a/mediator/med_merge_mod.F90 b/mediator/med_merge_mod.F90 index 704ac531d..3d0d6bbd4 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 @@ -231,7 +237,7 @@ subroutine med_merge_auto_field(merge_type, field_out, ungriddedUBound_out, & real(R8), pointer :: dpf1(:) => null() real(R8), pointer :: dpf2(:,:) => null() ! intput pointers to 1d and 2d fields real(R8), pointer :: dpw1(:) => null() ! weight pointer - character(len=*),parameter :: subname=' (med_merge_mod: med_merge)' + character(len=*),parameter :: subname=' (med_merge_mod: med_merge_auto_field)' !--------------------------------------- rc = ESMF_SUCCESS @@ -439,7 +445,7 @@ subroutine med_merge_field_1D(FBout, fnameout, & integer :: lb1,ub1,i,j,n logical :: wgtfound, FBinfound integer :: dbrc - character(len=*),parameter :: subname='(med_merge_fieldo_1d)' + character(len=*),parameter :: subname='(med_merge_field_1D)' ! ---------------------------------------------- if (dbug_flag > 10) then diff --git a/mediator/med_methods_mod.F90 b/mediator/med_methods_mod.F90 index ed360087f..63eb4890c 100644 --- a/mediator/med_methods_mod.F90 +++ b/mediator/med_methods_mod.F90 @@ -54,15 +54,23 @@ module med_methods_mod public med_methods_FB_getNumflds public med_methods_FB_Field_diagnose public med_methods_FB_GeomPrint + public med_methods_FB_getdata2d + public med_methods_FB_getdata1d + public med_methods_FB_getmesh + public med_methods_State_reset public med_methods_State_diagnose public med_methods_State_GeomPrint public med_methods_State_SetScalar public med_methods_State_GetScalar public med_methods_State_GetNumFields + + public med_methods_Field_getdata1d + public med_methods_Field_getdata2d public med_methods_Field_diagnose public med_methods_Field_GeomPrint public med_methods_FieldPtr_compare + public med_methods_Clock_TimePrint private med_methods_Mesh_Print @@ -694,7 +702,6 @@ subroutine med_methods_State_getNumFields(State, fieldnum, rc) end subroutine med_methods_State_getNumFields !----------------------------------------------------------------------------- - subroutine med_methods_FB_reset(FB, value, rc) ! ---------------------------------------------- ! Set all fields to value in FB @@ -1148,7 +1155,7 @@ subroutine med_methods_FB_Field_diagnose(FB, fieldname, string, rc) real(R8), pointer :: dataPtr2d(:,:) => null() type(ESMF_Field) :: lfield integer :: ungriddedUBound(1) ! currently the size must equal 1 for rank 2 fields - character(len=*),parameter :: subname='(med_methods_FB_FieldDiagnose)' + character(len=*),parameter :: subname='(med_methods_FB_Field_diagnose)' ! ---------------------------------------------- if (dbug_flag > 10) then @@ -1213,7 +1220,7 @@ subroutine med_methods_Field_diagnose(field, fieldname, string, rc) character(len=CS) :: lstring real(R8), pointer :: dataPtr1d(:) => null() real(R8), pointer :: dataPtr2d(:,:) => null() - character(len=*),parameter :: subname='(med_methods_FB_FieldDiagnose)' + character(len=*),parameter :: subname='(med_methods_Field_diagnose)' ! ---------------------------------------------- if (dbug_flag > 10) then @@ -2336,7 +2343,6 @@ subroutine med_methods_State_SetScalar(scalar_value, scalar_id, State, flds_scal end subroutine med_methods_State_SetScalar !----------------------------------------------------------------------------- - subroutine med_methods_FB_getNumFlds(FB, string, nflds, rc) ! ---------------------------------------------- @@ -2352,7 +2358,6 @@ subroutine med_methods_FB_getNumFlds(FB, string, nflds, rc) integer , intent(out) :: nflds integer , intent(inout) :: rc ! ---------------------------------------------- - rc = ESMF_SUCCESS if (.not. ESMF_FieldBundleIsCreated(FB)) then @@ -2371,4 +2376,111 @@ subroutine med_methods_FB_getNumFlds(FB, string, nflds, rc) end subroutine med_methods_FB_getNumFlds + !----------------------------------------------------------------------------- + subroutine med_methods_FB_getdata2d(FB, fieldname, dataptr2d, rc) + + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field, ESMF_FieldGet + + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + character(len=*) , intent(in) :: fieldname + real(r8) , pointer :: dataptr2d(:,:) + integer , intent(inout) :: rc + + ! local variables + type(ESMF_Field) :: lfield + ! ---------------------------------------------- + rc = ESMF_SUCCESS + + call ESMF_FieldBundleGet(FB, fieldname=trim(fieldname), field=lfield, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(lfield, farrayptr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + end subroutine med_methods_FB_getdata2d + + !----------------------------------------------------------------------------- + subroutine med_methods_FB_getdata1d(FB, fieldname, dataptr1d, rc) + + use ESMF, only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_Field, ESMF_FieldGet + + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + character(len=*) , intent(in) :: fieldname + real(r8) , pointer :: dataptr1d(:) + integer , intent(inout) :: rc + + ! local variables + type(ESMF_Field) :: lfield + ! ---------------------------------------------- + rc = ESMF_SUCCESS + + call ESMF_FieldBundleGet(FB, fieldname=trim(fieldname), 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 + + end subroutine med_methods_FB_getdata1d + + !----------------------------------------------------------------------------- + subroutine med_methods_Field_getdata2d(field, dataptr2d, rc) + + use ESMF, only : ESMF_Field, ESMF_FieldGet + + ! input/output variables + type(ESMF_Field) , intent(in) :: field + real(r8) , pointer :: dataptr2d(:,:) + integer , intent(inout) :: rc + ! ---------------------------------------------- + rc = ESMF_SUCCESS + + call ESMF_FieldGet(field, farrayptr=dataptr2d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + end subroutine med_methods_Field_getdata2d + + !----------------------------------------------------------------------------- + subroutine med_methods_Field_getdata1d(field, dataptr1d, rc) + + use ESMF, only : ESMF_Field, ESMF_FieldGet + + ! input/output variables + type(ESMF_Field) , intent(in) :: field + real(r8) , pointer :: dataptr1d(:) + integer , intent(inout) :: rc + ! ---------------------------------------------- + rc = ESMF_SUCCESS + + call ESMF_FieldGet(field, farrayptr=dataptr1d, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + end subroutine med_methods_Field_getdata1d + + !----------------------------------------------------------------------------- + subroutine med_methods_FB_getmesh(FB, mesh, rc) + + use ESMF, only : ESMF_FieldBundle, ESMF_Field, ESMF_Mesh, ESMF_FieldBundleGet, ESMF_FieldGet + + ! input/output variables + type(ESMF_FieldBundle) , intent(in) :: FB + type(ESMF_Mesh) , intent(out) :: mesh + integer , intent(inout) :: rc + + ! local variables + integer :: fieldCount + type(ESMF_Field), pointer :: fieldlist(:) => null() + ! ---------------------------------------------- + rc = ESMF_SUCCESS + + call ESMF_FieldBundleGet(FB, fieldCount=fieldCount, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + allocate(fieldlist(fieldcount)) + call ESMF_FieldBundleGet(FB, fieldlist=fieldlist, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldGet(fieldlist(1), mesh=mesh, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + deallocate(fieldlist) + + end subroutine med_methods_FB_getmesh + end module med_methods_mod diff --git a/mediator/med_phases_aofluxes_mod.F90 b/mediator/med_phases_aofluxes_mod.F90 index eb2c76ec9..e967cbf9b 100644 --- a/mediator/med_phases_aofluxes_mod.F90 +++ b/mediator/med_phases_aofluxes_mod.F90 @@ -109,7 +109,7 @@ subroutine med_phases_aofluxes_run(gcomp, rc) type(InternalState) :: is_local type(aoflux_type), save :: aoflux logical, save :: first_call = .true. - character(len=*),parameter :: subname='(med_phases_aofluxes)' + character(len=*),parameter :: subname='(med_phases_aofluxes_run)' !--------------------------------------- rc = ESMF_SUCCESS @@ -154,17 +154,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 @@ -216,7 +205,7 @@ subroutine med_aofluxes_init(gcomp, aoflux, FBAtm, FBOcn, FBFrac, FBMed_aoflux, integer :: flux_max_iteration ! maximum number of iterations for convergence logical :: coldair_outbreak_mod ! cold air outbreak adjustment (Mahrt & Sun 1995,MWR) logical :: isPresent, isSet - character(*),parameter :: subName = '(med_aofluxes_init) ' + character(*),parameter :: subName = '(med_aofluxes_init) ' !----------------------------------------------------------------------- if (dbug_flag > 5) then @@ -439,6 +428,40 @@ subroutine med_aofluxes_init(gcomp, aoflux, FBAtm, FBOcn, FBFrac, FBMed_aoflux, ! call FB_getFldPtr(FBFrac , fldname='ifrac' , fldptr1=ifrac, rc=rc) ! if (chkerr(rc,__LINE__,u_FILE_u)) return ! where (ofrac(:) + ifrac(:) <= 0.0_R8) mask(:) = 0 + !---------------------------------- + ! Get config variables on first call + !---------------------------------- + + call NUOPC_CompAttributeGet(gcomp, name='coldair_outbreak_mod', value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + read(cvalue,*) coldair_outbreak_mod + else + coldair_outbreak_mod = .false. + end if + + call NUOPC_CompAttributeGet(gcomp, name='flux_max_iteration', value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + read(cvalue,*) flux_max_iteration + else + flux_max_iteration = 1 + end if + + call NUOPC_CompAttributeGet(gcomp, name='flux_convergence', value=cvalue, isPresent=isPresent, isSet=isSet, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (isPresent .and. isSet) then + read(cvalue,*) flux_convergence + else + flux_convergence = 0.0_r8 + end if + + call shr_flux_adjust_constants(& + flux_convergence_tolerance=flux_convergence, & + flux_convergence_max_iteration=flux_max_iteration, & + coldair_outbreak_mod=coldair_outbreak_mod) + + if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90 index 743ee75af..7cfe09b57 100644 --- a/mediator/med_phases_history_mod.F90 +++ b/mediator/med_phases_history_mod.F90 @@ -196,7 +196,7 @@ subroutine med_phases_history_write(gcomp, rc) use ESMF , only : operator(==), operator(-) use ESMF , only : ESMF_ALARMLIST_ALL, ESMF_ClockGetAlarmList use NUOPC , only : NUOPC_CompAttributeGet - use esmFlds , only : compatm, complnd, compocn, compice, comprof, compglc, ncomps, compname + use esmFlds , only : compatm, compocn, ncomps, compname use esmFlds , only : fldListFr, fldListTo use NUOPC_Model, only : NUOPC_ModelGet diff --git a/mediator/med_phases_ocnalb_mod.F90 b/mediator/med_phases_ocnalb_mod.F90 index 11822da64..fff255591 100644 --- a/mediator/med_phases_ocnalb_mod.F90 +++ b/mediator/med_phases_ocnalb_mod.F90 @@ -570,7 +570,7 @@ subroutine med_phases_ocnalb_orbital_update(clock, logunit, mastertask, eccen, character(len=CL) :: msgstr ! temporary logical :: lprint logical :: first_time = .true. - character(len=*) , parameter :: subname = "(lnd_orbital_update)" + character(len=*) , parameter :: subname = "(med_phases_ocnalb_orbital_update)" !------------------------------------------- #ifdef CESMCOUPLED 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..5b7b23f13 --- /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..21f4f243e --- /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_lnd + 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_lnd(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..d0d00b970 --- /dev/null +++ b/mediator/med_phases_post_ocn_mod.F90 @@ -0,0 +1,93 @@ +module med_phases_post_ocn_mod + + !----------------------------------------------------------------------------- + ! Mediator post ocn phase - maps ocn->ice, accumulate glc input from ocn + !----------------------------------------------------------------------------- + + implicit none + private + + public :: med_phases_post_ocn + + logical :: ocn2glc_coupling + + 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 med_phases_prep_glc_mod , only : med_phases_prep_glc_accum_ocn + use esmFlds , only : compice, compglc, compocn, 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_ocn)' + !--------------------------------------- + + 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 + + ! Accumulate ocn input for glc if there is ocn->glc coupling + if (first_call) then + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(compocn,compglc(ns))) then + ocn2glc_coupling = .true. + exit + end if + end do + first_call = .false. + end if + if (ocn2glc_coupling) then + call med_phases_prep_glc_accum_ocn(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_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 2a0ba3ece..ba1a18962 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__ @@ -65,146 +65,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 24dc79e2b..adff495d5 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -4,82 +4,115 @@ module med_phases_prep_glc_mod ! Mediator phases for preparing glc export from mediator !----------------------------------------------------------------------------- + ! TODO: determine the number of ice sheets that are present + 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 NUOPC_Model , only : NUOPC_ModelGet use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR, ESMF_SUCCESS, ESMF_FAILURE - use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_VMAllReduce, ESMF_REDUCE_SUM - use ESMF , only : ESMF_Clock,ESMF_ClockGetAlarm - use ESMF , only : ESMF_Alarm, ESMF_AlarmIsRinging, ESMF_AlarmRingerOff + use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_VMAllReduce, ESMF_REDUCE_SUM, ESMF_REDUCE_MAX + use ESMF , only : ESMF_Clock, ESMF_ClockCreate, ESMF_ClockGetAlarm, ESMF_ClockAdvance, ESMF_ClockGet + use ESMF , only : ESMF_Time, ESMF_TimeGet + use ESMF , only : ESMF_Alarm, ESMF_AlarmCreate, ESMF_AlarmSet, ESMF_AlarmGet + use ESMF , only : ESMF_AlarmIsRinging, ESMF_AlarmRingerOff use ESMF , only : ESMF_GridComp, ESMF_GridCompGet use ESMF , only : ESMF_FieldBundle, ESMF_FieldBundleGet, ESMF_FieldBundleAdd use ESMF , only : ESMF_FieldBundleCreate, ESMF_FieldBundleIsCreated use ESMF , only : ESMF_Field, ESMF_FieldGet, ESMF_FieldCreate - use ESMF , only : ESMF_Array, ESMF_ArrayGet, ESMF_ArrayCreate, ESMF_ArrayDestroy - use ESMF , only : ESMF_DistGrid, ESMF_AttributeSet - use ESMF , only : ESMF_Mesh, ESMF_MeshGet, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8 - use esmFlds , only : compglc, complnd, mapbilnr, mapconsd, mapconsf, compname + use ESMF , only : ESMF_Mesh, ESMF_MESHLOC_ELEMENT, ESMF_TYPEKIND_R8, ESMF_KIND_R8 + use ESMF , only : ESMF_DYNAMICMASK, ESMF_DynamicMaskSetR8R8R8, ESMF_DYNAMICMASKELEMENTR8R8R8 + use ESMF , only : ESMF_FieldRegrid + use esmFlds , only : complnd, compocn, mapbilnr, mapconsd, compname + use esmFlds , only : max_icesheets, num_icesheets, compglc, ocn2glc_coupling use med_internalstate_mod , only : InternalState, mastertask, logunit - use med_constants_mod , only : dbug_flag=>med_constants_dbug_flag use med_map_mod , only : med_map_routehandles_init, med_map_rh_is_created use med_map_mod , only : med_map_field_normalized, med_map_field - use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_reset => med_methods_FB_reset - use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_constants_mod , only : dbug_flag => med_constants_dbug_flag + use med_constants_mod , only : czero => med_constants_czero + use med_methods_mod , only : fldbun_getmesh => med_methods_FB_getmesh + use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d + 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 : field_getdata2d => med_methods_Field_getdata2d + use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d + use med_utils_mod , only : chkerr => med_utils_ChkErr + use med_time_mod , only : med_time_alarmInit use glc_elevclass_mod , only : glc_get_num_elevation_classes use glc_elevclass_mod , only : glc_get_elevation_classes use glc_elevclass_mod , only : glc_get_fractional_icecov use perf_mod , only : t_startf, t_stopf + use shr_const_mod , only : shr_const_pi, shr_const_spval + use shr_mpi_mod , only : shr_mpi_sum 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 ! called from nuopc run sequence + public :: med_phases_prep_glc_accum_lnd ! called from med_phases_post_lnd + public :: med_phases_prep_glc_accum_ocn ! called from med_phases_post_ocn - private :: map_lnd2glc + private :: med_phases_prep_glc_init + private :: med_phases_prep_glc_map_lnd2glc private :: med_phases_prep_glc_renormalize_smb + ! ----------------- + ! lnd -> glc + ! ----------------- + ! glc fields with multiple elevation classes: lnd->glc ! - fields sent from lnd->med to glc ARE IN multiple elevation classes ! - fields sent from med->glc from land ARE NOT IN multiple elevation classes ! Need to keep track of the lnd->med fields destined for glc in the FBlndAccum field bundle. - ! Needed for standard lnd->glc mapping - type(ESMF_FieldBundle) :: FBlndAccum_lnd - type(ESMF_FieldBundle) :: FBlndAccum_glc - 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 '/) - ! Whether to renormalize the SMB for conservation. ! Should be set to true for 2-way coupled runs with evolving ice sheets. ! Does not need to be true for 1-way coupling. logical :: smb_renormalize - ! Needed if renormalize SMB - type(ESMF_Field) :: field_glc_icemask_g - type(ESMF_Field) :: field_glc_icemask_l - type(ESMF_Field) :: field_glc_frac_g - type(ESMF_Field) :: field_glc_frac_l - type(ESMF_Field) :: field_glc_frac_g_ec - type(ESMF_Field) :: field_glc_frac_l_ec - type(ESMF_Field) :: field_lnd_icemask_l - type(ESMF_Field) :: field_lfrac_g - - real(r8) , pointer :: aream_l(:) => null() ! cell areas on land grid, for mapping - real(r8) , pointer :: aream_g(:) => null() ! cell areas on glc grid, for mapping - - character(len=*), parameter :: qice_fieldname = 'Flgl_qice' ! Name of flux field giving surface mass balance + type(ESMF_FieldBundle) :: FBlndAccum_l + 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 :: toglc_frlnd_type + character(CS) :: name + type(ESMF_FieldBundle) :: FBlndAccum_g + type(ESMF_Field) :: field_icemask_g + type(ESMF_Field) :: field_frac_g + type(ESMF_Field) :: field_frac_g_ec + type(ESMF_Field) :: field_lfrac_g + type(ESMF_Mesh) :: mesh_g + end type toglc_frlnd_type + type(toglc_frlnd_type) :: toglc_frlnd(max_icesheets) ! TODO: make this allocatable for number of actual ice sheets + + type(ESMF_Field) :: field_normdst_l + type(ESMF_Field) :: field_icemask_l + type(ESMF_Field) :: field_frac_l + type(ESMF_Field) :: field_frac_l_ec + type(ESMF_Field) :: field_lnd_icemask_l + real(r8) , pointer :: aream_l(:) => null() ! cell areas on land grid, for mapping + + character(len=*), parameter :: qice_fieldname = 'Flgl_qice' ! Name of flux field giving surface mass balance character(len=*), parameter :: Sg_frac_fieldname = 'Sg_ice_covered' character(len=*), parameter :: Sg_topo_fieldname = 'Sg_topo' character(len=*), parameter :: Sg_icemask_fieldname = 'Sg_icemask' - - ! Size of undistributed dimension from land - integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) - - logical :: init_prep_glc = .false. - + integer :: ungriddedCount ! this equals the number of elevation classes + 1 (for bare land) + + ! ----------------- + ! ocn -> glc + ! ----------------- + + type(ESMF_FieldBundle) :: FBocnAccum_o + integer :: FBocnAccumCnt + character(len=14) :: fldnames_fr_ocn(2) = (/'So_t_depth','So_s_depth'/) ! TODO: what else needs to be added here + type(ESMF_DynamicMask) :: dynamicOcnMask + integer, parameter :: num_ocndepths = 7 + logical :: ocn_sends_depths = .false. + + logical :: lnd2glc_coupling = .false. + logical :: init_prep_glc = .false. + type(ESMF_Clock) :: prepglc_clock character(*), parameter :: u_FILE_u = & __FILE__ @@ -90,7 +123,8 @@ 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 lnd accumulation field bundles on lnd and and glc mesh and initialize accumulation count + ! Create ocn accumulation field bundle on onc mesh and initialize accumulation count !--------------------------------------- ! input/output variables @@ -99,23 +133,22 @@ subroutine med_phases_prep_glc_init(gcomp, rc) ! local variables type(InternalState) :: is_local - integer :: i,n,ncnt - type(ESMF_Mesh) :: lmesh_glc - type(ESMF_Mesh) :: lmesh_lnd + integer :: i,n,ns,nf + type(ESMF_Mesh) :: mesh_l + type(ESMF_Mesh) :: mesh_o type(ESMF_Field) :: lfield real(r8), pointer :: data2d_in(:,:) => null() real(r8), pointer :: data2d_out(:,:) => null() - real(r8), pointer :: dataptr1d(:) => null() character(len=CS) :: glc_renormalize_smb logical :: glc_coupled_fluxes - type(ESMF_Array) :: larray - type(ESMF_DistGrid) :: ldistgrid - integer :: lsize - logical :: isPresent - integer :: fieldCount - type(ESMF_Field), pointer :: fieldlist(:) => null() integer :: ungriddedUBound_output(1) ! currently the size must equal 1 for rank 2 fieldds - character(len=*),parameter :: subname='(med_phases_prep_glc_init)' + type(ESMF_Clock) :: med_clock + type(ESMF_ALARM) :: glc_avg_alarm + logical :: glc_present + character(len=CS) :: glc_avg_period + integer :: glc_cpl_dt + character(len=CS) :: cvalue + character(len=*),parameter :: subname=' (med_phases_prep_glc_init) ' !--------------------------------------- call t_startf('MED:'//subname) @@ -125,109 +158,166 @@ subroutine med_phases_prep_glc_init(gcomp, rc) endif 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 + + ! ------------------------------- + ! Initialize prepglc_clock + ! ------------------------------- - !--------------------------------------- - ! Count the number of fields outside of scalar data - !--------------------------------------- + ! Initialize prepglc_clock from mclock - THIS CALL DOES NOT COPY ALARMS + call NUOPC_ModelGet(gcomp, modelClock=med_clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + prepglc_clock = ESMF_ClockCreate(med_clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) 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) + ! Set alarm glc averaging interval + call NUOPC_CompAttributeGet(gcomp, name="glc_avg_period", value=glc_avg_period, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (trim(glc_avg_period) == 'yearly') then + call med_time_alarmInit(prepglc_clock, glc_avg_alarm, 'nyears', opt_n=1, alarmname='alarm_glc_avg', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (mastertask) then + write(logunit,'(a,i10)') trim(subname)//& + ' created alarm with averaging period for export to glc is yearly' + end if + else if (trim(glc_avg_period) == 'glc_coupling_period') then + call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", value=cvalue, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + read(cvalue,*) glc_cpl_dt + call med_time_alarmInit(prepglc_clock, glc_avg_alarm, 'nseconds', opt_n=glc_cpl_dt, alarmname='alarm_glc_avg', rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (mastertask) then + write(logunit,'(a,i10)') trim(subname)//& + ' created alarm with averaging period for export to glc (in seconds) ',glc_cpl_dt + end if else - ! The scalar field has been removed from all mediator field bundles - so determine ncnt for below - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldCount=ncnt, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(trim(subname)// ": ERROR glc_avg_period = "//trim(glc_avg_period)//" not supported", & + ESMF_LOGMSG_INFO) + rc = ESMF_FAILURE + RETURN end if + call ESMF_AlarmSet(glc_avg_alarm, clock=prepglc_clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - ! Create field bundles for the fldnames_fr_lnd that have an - ! undistributed dimension corresponding to elevation classes - !--------------------------------------- + ! ------------------------------- + ! If lnd->glc couplng is active + ! ------------------------------- + + do ns = 1,num_icesheets + if (is_local%wrap%med_coupling_active(complnd,compglc(ns))) then + lnd2glc_coupling = .true. + exit + end if + end do + if (lnd2glc_coupling) then + + ! Determine if renormalize smb + call NUOPC_CompAttributeGet(gcomp, name='glc_renormalize_smb', value=glc_renormalize_smb, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - if (ncnt > 0) then + ! TODO: talk to Bill Sacks to determine if this is the correct logic + glc_coupled_fluxes = is_local%wrap%med_coupling_active(compglc(1),complnd) - ! Create accumulation field bundle from land on the land grid (including bare land) + ! Note glc_coupled_fluxes should be false in the no_evolve cases + ! Goes back to the zero-gcm fluxes variable - if zero-gcm fluxes is true than do not renormalize + ! The user can set this to true in an evolve cases + + select case (glc_renormalize_smb) + case ('on') + smb_renormalize = .true. + case ('off') + smb_renormalize = .false. + case ('on_if_glc_coupled_fluxes') + if (.not. glc_coupled_fluxes) then + ! Do not renormalize if med_coupling_active is not true for compglc->complnd + ! In this case, conservation is not important + smb_renormalize = .false. + else + smb_renormalize = .true. + end if + case default + write(logunit,*) subname,' ERROR: unknown value for glc_renormalize_smb: ', trim(glc_renormalize_smb) + call ESMF_LogWrite(trim(subname)//' ERROR: unknown value for glc_renormalize_smb: '// trim(glc_renormalize_smb), & + ESMF_LOGMSG_ERROR, line=__LINE__, file=__FILE__) + rc = ESMF_FAILURE + return + end select + + ! Create field bundles for the fldnames_fr_lnd that have an + ! undistributed dimension corresponding to elevation classes (including bare land) call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fldnames_fr_lnd(1), field=lfield, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound_output, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ungriddedCount = ungriddedUBound_output(1) - ! TODO: check that ungriddedCount = glc_nec+1 - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldCount=fieldCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist(fieldcount)) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldlist=fieldlist, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(fieldlist(1), mesh=lmesh_lnd, rc=rc) + + ! Get land mesh + call fldbun_getmesh(is_local%wrap%FBImp(complnd,complnd), mesh_l, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fieldlist) - FBlndAccum_lnd = ESMF_FieldBundleCreate(name='FBlndAccum_lnd', rc=rc) + FBlndAccum_l = ESMF_FieldBundleCreate(name='FBlndAccum_l', rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do n = 1,size(fldnames_fr_lnd) - lfield = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, name=fldnames_fr_lnd(n), & + lfield = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, name=fldnames_fr_lnd(n), & meshloc=ESMF_MESHLOC_ELEMENT, & ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(FBlndAccum_lnd, (/lfield/), rc=rc) + call ESMF_FieldBundleAdd(FBlndAccum_l, (/lfield/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_LogWrite(trim(subname)//' adding field '//trim(fldnames_fr_lnd(n))//' to FBLndAccum_lnd', & + call ESMF_LogWrite(trim(subname)//' adding field '//trim(fldnames_fr_lnd(n))//' to FBLndAccum_l', & ESMF_LOGMSG_INFO) end do - call FB_reset(FBlndAccum_lnd, value=0.0_r8, rc=rc) + call fldbun_reset(FBlndAccum_l, value=0.0_r8, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Create accumulation field bundle from land on the glc grid + ! Create accumulation field bundles from land on each glc ice sheet mesh ! Determine glc mesh from the mesh from the first export field to glc - ! However FBlndAccum_glc has the fields fldnames_fr_lnd BUT ON the glc grid - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc), fieldCount=fieldCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist(fieldcount)) - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc), fieldlist=fieldlist, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(fieldlist(1), mesh=lmesh_glc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fieldlist) + ! However FBlndAccum_g has the fields fldnames_fr_lnd BUT ON the glc grid + do ns = 1,num_icesheets + ! get mesh on glc grid + call fldbun_getmesh(is_local%wrap%FBExp(compglc(ns)), toglc_frlnd(ns)%mesh_g, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - FBlndAccum_glc = ESMF_FieldBundleCreate(name='FBlndAccum_glc', rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1,size(fldnames_fr_lnd) - lfield = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, name=fldnames_fr_lnd(n), & - meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + ! create accumulation field bundle on glc grid + toglc_frlnd(ns)%FBlndAccum_g = ESMF_FieldBundleCreate(rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleAdd(FBlndAccum_glc, (/lfield/), rc=rc) + do nf = 1,size(fldnames_fr_lnd) + lfield = ESMF_FieldCreate(toglc_frlnd(ns)%mesh_g, ESMF_TYPEKIND_R8, name=fldnames_fr_lnd(nf), & + meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(toglc_frlnd(ns)%FBlndAccum_g, (/lfield/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end do + call fldbun_reset(toglc_frlnd(ns)%FBlndAccum_g, value=0.0_r8, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - end do - call FB_reset(FBlndAccum_glc, value=0.0_r8, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Create land fraction field on glc mesh (this is just needed for normalization mapping) - field_lfrac_g = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! create land fraction field on glc mesh (this is just needed for normalization mapping) + toglc_frlnd(ns)%field_lfrac_g = ESMF_FieldCreate(toglc_frlnd(ns)%mesh_g, ESMF_TYPEKIND_R8, & + meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Create route handle if it has not been created - if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compglc,:),mapbilnr,rc=rc)) then - call ESMF_LogWrite(trim(subname)//" mapbilnr is not created for lnd->glc mapping", & - ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) - rc = ESMF_FAILURE - return - end if + ! create route handle if it has not been created + if (.not. med_map_RH_is_created(is_local%wrap%RH(complnd,compglc(ns),:),mapbilnr,rc=rc)) then + call ESMF_LogWrite(trim(subname)//" mapbilnr is not created for lnd->glc mapping", & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return + end if + end do + ! ------------------------------- ! Determine if renormalize smb + ! ------------------------------- call NUOPC_CompAttributeGet(gcomp, name='glc_renormalize_smb', value=glc_renormalize_smb, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! TODO: talk to Bill Sacks to determine if this is the correct logic - glc_coupled_fluxes = is_local%wrap%med_coupling_active(compglc,complnd) + glc_coupled_fluxes = is_local%wrap%med_coupling_active(compglc(1),complnd) ! Note glc_coupled_fluxes should be false in the no_evolve cases ! Goes back to the zero-gcm fluxes variable - if zero-gcm fluxes is true than do not renormalize ! The user can set this to true in an evolve cases @@ -252,67 +342,100 @@ subroutine med_phases_prep_glc_init(gcomp, rc) rc = ESMF_FAILURE return end select + if (mastertask) then + write(logunit,'(a,l4)') trim(subname)//' smb_renormalize is ',smb_renormalize + end if - ! ------------------------------- - ! If smb will be renormalized then... - ! ------------------------------- if (smb_renormalize) then - - ! determine areas on land mesh - call ESMF_MeshGet(lmesh_lnd, numOwnedElements=lsize, elementDistGrid=ldistgrid, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - allocate(aream_l(lsize), dataptr1d(lsize)) - lArray = ESMF_ArrayCreate(ldistgrid, dataptr1d, rc=rc) - call ESMF_MeshGet(lmesh_lnd, elemMaskArray=lArray, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - aream_l(:) = dataptr1d(:) - call ESMF_ArrayDestroy(larray, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - deallocate(dataptr1d) - - ! determine areas on glc mesh - call ESMF_MeshGet(lmesh_glc, numOwnedElements=lsize, elementDistGrid=ldistgrid, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - allocate(aream_g(lsize), dataptr1d(lsize)) - lArray = ESMF_ArrayCreate(ldistgrid, dataptr1d, rc=rc) - call ESMF_MeshGet(lmesh_glc, elemMaskArray=lArray, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - aream_g(:) = dataptr1d(:) - call ESMF_ArrayDestroy(larray, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - deallocate(dataptr1d) - - ! ice mask without elevation classes on glc and lnd - field_glc_icemask_g = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - field_glc_icemask_l = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + ! field used in the normalization for the mapping + field_normdst_l = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! ice fraction without multiple elevation classes on glc and lnd - field_glc_frac_g = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + ! ice mask without elevation classes on lnd + 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_glc_frac_l = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + + ! ice fraction without multiple elevation classes on lnd + field_frac_l = ESMF_FieldCreate(mesh_l, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - ! ice fraction in multiple elevation classes on glc and lnd - NOTE that this includes bare land - field_glc_frac_g_ec = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & + ! ice fraction in multiple elevation classes on lnd - NOTE that this includes bare land + 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_glc_frac_l_ec = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, & - ungriddedLbound=(/1/), ungriddedUbound=(/ungriddedCount/), gridToFieldMap=(/2/), rc=rc) + + ! Loop over ice sheets + do ns = 1,num_icesheets + ! ice mask without elevation classes on glc + toglc_frlnd(ns)%field_icemask_g = ESMF_FieldCreate(toglc_frlnd(ns)%mesh_g, & + ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! ice fraction without multiple elevation classes on glc + toglc_frlnd(ns)%field_frac_g = ESMF_FieldCreate(toglc_frlnd(ns)%mesh_g, & + ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + ! ice fraction in multiple elevation classes on glc - NOTE that this includes bare land + toglc_frlnd(ns)%field_frac_g_ec = ESMF_FieldCreate(toglc_frlnd(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 - this will be needed to map the fractions + if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc(ns),complnd,:),mapconsd, rc=rc)) then + call med_map_routehandles_init( compglc(ns), complnd, & + FBSrc=is_local%wrap%FBImp(compglc(ns),compglc(ns)), & + FBDst=is_local%wrap%FBImp(compglc(ns),complnd), & + mapindex=mapconsd, & + RouteHandle=is_local%wrap%RH, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + end if + end do + end if + end if + + ! ------------------------------- + ! If ocn->glc couplng is active + ! ------------------------------- + + if (ocn2glc_coupling) then + ! Get ocean mesh + call fldbun_getmesh(is_local%wrap%FBImp(compocn,compocn), mesh_o, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + + FBocnAccum_o = ESMF_FieldBundleCreate(name='FBocnAccum_o', rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do n = 1,size(fldnames_fr_ocn) + lfield = ESMF_FieldCreate(mesh_o, ESMF_TYPEKIND_R8, name=fldnames_fr_ocn(n), & + meshloc=ESMF_MESHLOC_ELEMENT, & + ungriddedLbound=(/1/), ungriddedUbound=(/num_ocndepths/), gridToFieldMap=(/2/), rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_FieldBundleAdd(FBocnAccum_o, (/lfield/), rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call ESMF_LogWrite(trim(subname)//' adding field '//trim(fldnames_fr_ocn(n))//' to FBOcnAccum_o', & + ESMF_LOGMSG_INFO) + end do + call fldbun_reset(FBocnAccum_o, value=czero, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! Create route handle if it has not been created - this will be needed to map the fractions - if (.not. med_map_RH_is_created(is_local%wrap%RH(compglc,complnd,:),mapconsf,rc=rc)) then - call med_map_routehandles_init( compglc, complnd, & - FBSrc=is_local%wrap%FBImp(compglc,compglc), & - FBDst=is_local%wrap%FBImp(compglc,complnd), & - mapindex=mapconsf, & - RouteHandle=is_local%wrap%RH, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! create route handle if it has not been created + do ns = 1,num_icesheets + if (.not. med_map_RH_is_created(is_local%wrap%RH(compocn,compglc(ns),:),mapbilnr,rc=rc)) then + call ESMF_LogWrite(trim(subname)//" mapbilnr is not created for ocn->glc mapping", & + ESMF_LOGMSG_ERROR, line=__LINE__, file=u_FILE_u) + rc = ESMF_FAILURE + return end if + end do + + ! Create a dynamic mask object + ! The dynamic mask object further holds a pointer to the routine that will be called in order to + ! handle dynamically masked elements - in this case its DynOcnMaskProc (see below) + call ESMF_DynamicMaskSetR8R8R8(dynamicOcnMask, dynamicSrcMaskValue=czero, & + dynamicMaskRoutine=DynOcnMaskProc, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - end if end if if (dbug_flag > 5) then @@ -323,12 +446,15 @@ subroutine med_phases_prep_glc_init(gcomp, rc) end subroutine med_phases_prep_glc_init !================================================================================================ - subroutine med_phases_prep_glc_accum(gcomp, rc) + subroutine med_phases_prep_glc_accum_lnd(gcomp, rc) !--------------------------------------- - ! Carry out accumulation for the land-ice (glc) component - ! Accumulation and averaging is done on the land input to the river component on the land grid - ! Mapping from the land to the glc grid is then done with the time averaged fields + ! Carry out accumulation for the lnd->glc and ocn->glc + ! Accumulation and averaging is done on + ! - on the land mesh for land input + ! - on the ocean mesh for ocean input + ! Mapping from the land to the glc grid and from the ocean to the glc grid + ! is then done after the accumulated fields have been time averaged !--------------------------------------- ! input/output variables @@ -338,86 +464,66 @@ subroutine med_phases_prep_glc_accum(gcomp, rc) ! local variables type(InternalState) :: is_local type(ESMF_Field) :: lfield - integer :: i,n,ncnt + integer :: i,n real(r8), pointer :: data2d_in(:,:) => null() real(r8), pointer :: data2d_out(:,:) => null() - character(len=*),parameter :: subname='(med_phases_prep_glc_accum)' + character(len=*),parameter :: subname=' (med_phases_prep_glc_accum) ' !--------------------------------------- call t_startf('MED:'//subname) - if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) endif + rc = ESMF_SUCCESS - !--------------------------------------- - ! Get the internal state - !--------------------------------------- + if (.not. init_prep_glc) then + call med_phases_prep_glc_init(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + init_prep_glc = .true. + end if + + ! Advance prepglc_clock - this will make the prepglc_clock in sync with the mediator clock + ! TODO: this assumes that the land is in the fast time loop + call ESMF_ClockAdvance(prepglc_clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! Get the internal state nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - ! Count the number of fields outside of scalar data - !--------------------------------------- - - 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 determine ncnt for below - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldCount=ncnt, rc=rc) + ! Accumulate fields from land on land mesh that will be sent to glc + do n = 1, size(fldnames_fr_lnd) + call fldbun_getdata2d(is_local%wrap%FBImp(complnd,complnd), fldnames_fr_lnd(n), data2d_in, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - end if - - !--------------------------------------- - ! accumulator land input to glc on land grid - !--------------------------------------- - - if (ncnt > 0) then - ! Initialize module variables needed to accumulate input to glc - if (.not. init_prep_glc) then - call med_phases_prep_glc_init(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - init_prep_glc = .true. - end if - - do n = 1, size(fldnames_fr_lnd) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldname=trim(fldnames_fr_lnd(n)), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=data2d_in, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(FBlndAccum_lnd, fieldname=fldnames_fr_lnd(n), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=data2d_out, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - do i = 1,size(data2d_out, dim=2) - data2d_out(:,i) = data2d_out(:,i) + data2d_in(:,i) - end do + call fldbun_getdata2d(FBlndAccum_l, fldnames_fr_lnd(n), data2d_out, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do i = 1,size(data2d_out, dim=2) + data2d_out(:,i) = data2d_out(:,i) + data2d_in(:,i) end do - - FBlndAccumCnt = FBlndAccumCnt + 1 - - if (dbug_flag > 1) then - call FB_diagnose(FBlndAccum_lnd, string=trim(subname)// ' FBlndAccum_lnd ', rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - end if + end do + FBlndAccumCnt = FBlndAccumCnt + 1 + if (dbug_flag > 1) then + call fldbun_diagnose(FBlndAccum_l, string=trim(subname)// ' FBlndAccum_l ', rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return end if - if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) end if call t_stopf('MED:'//subname) - end subroutine med_phases_prep_glc_accum + end subroutine med_phases_prep_glc_accum_lnd !================================================================================================ - subroutine med_phases_prep_glc_avg(gcomp, rc) + subroutine med_phases_prep_glc_accum_ocn(gcomp, rc) !--------------------------------------- - ! Prepare the GLC export Fields from the mediator + ! Carry out accumulation for ocn->glc + ! Accumulation and averaging is done on + ! - on the ocean mesh for ocean input + ! Mapping from from the ocean to the glc grid is then done after + ! the accumulated fields have been time averaged !--------------------------------------- ! input/output variables @@ -425,154 +531,228 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) integer, intent(out) :: rc ! local variables - type(InternalState) :: is_local - type(ESMF_Clock) :: clock - type(ESMF_Alarm) :: alarm - type(ESMF_Field) :: lfield - integer :: i, n, ncnt ! counters - real(r8), pointer :: data2d(:,:) => null() - real(r8), pointer :: data2d_import(:,:) => null() - character(len=*) , parameter :: subname='(med_phases_prep_glc_avg)' + type(InternalState) :: is_local + type(ESMF_Field) :: lfield + integer :: i,n + real(r8), pointer :: data2d_in(:,:) => null() + real(r8), pointer :: data2d_out(:,:) => null() + character(len=*),parameter :: subname=' (med_phases_prep_glc_accum) ' !--------------------------------------- call t_startf('MED:'//subname) if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) - end if + endif + rc = ESMF_SUCCESS - !--------------------------------------- - ! Get the internal state - !--------------------------------------- + if (.not. init_prep_glc) then + call med_phases_prep_glc_init(gcomp, rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + init_prep_glc = .true. + 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 + ! Advance prepglc_clock - this will make the prepglc_clock in sync with the mediator clock + ! TODO: do we need 2 clocks? one for the lnd and one for the ocean? + ! call ESMF_ClockAdvance(prepglc_clock, rc=rc) + ! if (ChkErr(rc,__LINE__,u_FILE_u)) return + + ! Accumulate fields from ocean on ocean mesh that will be sent to glc + do n = 1, size(fldnames_fr_ocn) + call fldbun_getdata2d(is_local%wrap%FBImp(compocn,compocn), fldnames_fr_ocn(n), data2d_in, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call fldbun_getdata2d(FBocnAccum_o, fldnames_fr_ocn(n), data2d_out, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + do i = 1,size(data2d_out, dim=2) + data2d_out(:,i) = data2d_out(:,i) + data2d_in(:,i) + end do + end do + FBocnAccumCnt = FBocnAccumCnt + 1 + if (dbug_flag > 1) then + call fldbun_diagnose(FBocnAccum_o, string=trim(subname)// ' FBocnAccum_o ', rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end if + + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) + end if + call t_stopf('MED:'//subname) + + end subroutine med_phases_prep_glc_accum_ocn + + !================================================================================================ + subroutine med_phases_prep_glc(gcomp, rc) + !--------------------------------------- - ! Count the number of fields outside of scalar data, if zero, then return + ! Create module clock (prepglc_clock) + ! Prepare the GLC export Fields from the mediator !--------------------------------------- - ! 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 + ! input/output variables + type(ESMF_GridComp) :: gcomp + integer, intent(out) :: rc - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc), fieldCount=ncnt, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return + ! local variables + type(InternalState) :: is_local + type(ESMF_Field) :: lfield_src + type(ESMF_Field) :: lfield_dst + type(ESMF_Clock) :: med_clock + type(ESMF_Time) :: med_currtime + type(ESMF_Time) :: prepglc_currtime + type(ESMF_ALARM) :: glc_avg_alarm + character(len=CS) :: glc_avg_period + integer :: glc_cpl_dt + integer :: yr_med, mon_med, day_med, sec_med + integer :: yr_prepglc, mon_prepglc, day_prepglc, sec_prepglc + type(ESMF_Alarm) :: alarm + integer :: i, n, ns + real(r8), pointer :: data2d(:,:) => null() + real(r8), pointer :: data2d_import(:,:) => null() + character(len=*) , parameter :: subname=' (med_phases_prep_glc) ' + !--------------------------------------- - if (ncnt == 0) then - call ESMF_LogWrite(trim(subname)//": only scalar data is present in FBExp(compglc), returning", & - ESMF_LOGMSG_INFO) - call t_stopf('MED:'//subname) - RETURN + call t_startf('MED:'//subname) + + if (dbug_flag > 5) then + call ESMF_LogWrite(trim(subname)//": called", ESMF_LOGMSG_INFO) end if + rc = ESMF_SUCCESS - ! Initialize module variables needed to accumulate input to glc if (.not. init_prep_glc) then - call med_phases_prep_glc_init(gcomp, rc) + call med_phases_prep_glc_init(gcomp, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return init_prep_glc = .true. end if - !--------------------------------------- - ! Determine if avg alarm is ringing - and if not ringing then return - !--------------------------------------- + ! Get the internal state + nullify(is_local%wrap) + call ESMF_GridCompGetInternalState(gcomp, is_local, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_GridCompGet(gcomp, clock=clock, rc=rc) + ! Check time + call NUOPC_ModelGet(gcomp, modelClock=med_clock, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGet(med_clock, currtime=med_currtime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeGet(med_currtime,yy=yr_med, mm=mon_med, dd=day_med, s=sec_med, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_ClockGet(prepglc_clock, currtime=prepglc_currtime, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_TimeGet(prepglc_currtime,yy=yr_prepglc, mm=mon_prepglc, dd=day_prepglc, s=sec_prepglc, rc=rc) + if (mastertask) then + write(logunit,'(a,4(i8,2x))') trim(subname)//'med clock yr, mon, day, sec = ',& + yr_med,mon_med,day_med,sec_med + write(logunit,'(a,4(i8,2x))') trim(subname)//'prep glc clock yr, mon, day, sec = ',& + yr_prepglc,mon_prepglc,day_prepglc,sec_prepglc + end if - call ESMF_ClockGetAlarm(clock, alarmname='alarm_glc_avg', alarm=alarm, rc=rc) + ! Determine if the alarm is ringing + call ESMF_ClockGetAlarm(prepglc_clock, alarmname='alarm_glc_avg', alarm=alarm, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (.not. ESMF_AlarmIsRinging(alarm, rc=rc)) then + ! Do nothing if the alarm is not ringing + call ESMF_LogWrite(trim(subname)//": glc_avg alarm is not ringing - returning", ESMF_LOGMSG_INFO) + else + call ESMF_LogWrite(trim(subname)//": glc_avg alarm is ringing - averaging input from lnd and ocn to glc", & + ESMF_LOGMSG_INFO) + if (mastertask) then + write(logunit,'(a)') trim(subname)//"glc_avg alarm is ringing - averaging input from lnd and ocn to glc" + end if - ! If the is ringing - turn it off and continue - otherwise reset field bundle to zero and return - if (ESMF_AlarmIsRinging(alarm, rc=rc)) then + ! Turn off the alarm call ESMF_AlarmRingerOff( alarm, rc=rc ) if (ChkErr(rc,__LINE__,u_FILE_u)) return - else - call ESMF_LogWrite(trim(subname)//": glc_avg alarm is not ringing - returning", ESMF_LOGMSG_INFO) - ! Reset export field bundle to zero - call FB_reset(is_local%wrap%FBExp(compglc), value=0.0_r8, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - ! turn on stop timer and return - call t_stopf('MED:'//subname) - ! return - RETURN - end if - - !--------------------------------------- - ! Average import from accumulated land import FB - !--------------------------------------- - - call ESMF_LogWrite(trim(subname)//": glc_avg alarm is ringing - averaging input from lnd to glc", ESMF_LOGMSG_INFO) - do n = 1, size(fldnames_fr_lnd) - call ESMF_FieldBundleGet(FBlndAccum_lnd, fieldname=fldnames_fr_lnd(n), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=data2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - if (FBlndAccumCnt > 0) then - ! If accumulation count is greater than 0, do the averaging - data2d(:,:) = data2d(:,:) / real(FBlndAccumCnt) - else - ! If accumulation count is 0, then simply set the averaged field bundle values from the land - ! to the import field bundle values - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldname=fldnames_fr_lnd(n), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=data2d_import, rc=rc) + ! Average import from accumulated land import data + do n = 1, size(fldnames_fr_lnd) + call fldbun_getdata2d(FBlndAccum_l, fldnames_fr_lnd(n), data2d, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - data2d(:,:) = data2d_import(:,:) - end if - end do - - if (dbug_flag > 1) then - call FB_diagnose(FBlndAccum_lnd, string=trim(subname)//' FBlndAccum for after avg for field bundle ', rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - end if - - !--------------------------------------- - ! Map accumulated field bundle from land grid (with elevation classes) to glc grid (without elevation classes) - ! and set FBExp(compglc) data - !--------------------------------------- - - call FB_reset(FBlndAccum_glc, value=0.0_r8, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - call map_lnd2glc(gcomp, rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - - if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(compglc), string=trim(subname)//' FBexp(compglc) ', rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - endif - - !--------------------------------------- - ! zero accumulator and accumulated field bundles - !--------------------------------------- + if (FBlndAccumCnt > 0) then + ! If accumulation count is greater than 0, do the averaging + data2d(:,:) = data2d(:,:) / real(FBlndAccumCnt) + else + ! If accumulation count is 0, then simply set the averaged field bundle values from the land + ! to the import field bundle values + call fldbun_getdata2d(is_local%wrap%FBImp(complnd,complnd), fldnames_fr_lnd(n), data2d_import, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + data2d(:,:) = data2d_import(:,:) + end if + end do - FBlndAccumCnt = 0 + if (ocn2glc_coupling) then + ! Average import from accumulated ocn import data + do n = 1, size(fldnames_fr_ocn) + call fldbun_getdata2d(FBocnAccum_o, fldnames_fr_ocn(n), data2d, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + if (FBocnAccumCnt > 0) then + ! If accumulation count is greater than 0, do the averaging + data2d(:,:) = data2d(:,:) / real(FBocnAccumCnt) + else + ! If accumulation count is 0, then simply set the averaged field bundle values from the ocn + ! to the import field bundle values + call fldbun_getdata2d(is_local%wrap%FBImp(compocn,compocn), fldnames_fr_ocn(n), data2d_import, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + data2d(:,:) = data2d_import(:,:) + end if + end do + if (dbug_flag > 1) then + call fldbun_diagnose(FBocnAccum_o, string=trim(subname)//' FBocnAccum for after avg for field bundle ', rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end if - call FB_reset(FBlndAccum_lnd, value=0.0_r8, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - call FB_reset(FBlndAccum_glc, value=0.0_r8, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return + ! Map accumulated ocean field from ocean mesh to land mesh and set FBExp(compglc(ns)) data + ! Zero land accumulator and accumulated field bundles on ocean grid + do n = 1,size(fldnames_fr_ocn) + call ESMF_FieldBundleGet(FBocnAccum_o, fldnames_fr_ocn(n), field=lfield_src, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + do ns = 1,num_icesheets + call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc(ns)), fldnames_fr_ocn(n), field=lfield_dst, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + ! Do mapping of ocn to glc with dynamic masking + call ESMF_FieldRegrid(lfield_src, lfield_dst, & + routehandle=is_local%wrap%RH(compocn,compglc(ns),mapbilnr), dynamicMask=dynamicOcnMask, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end do + end do + FBocnAccumCnt = 0 + call fldbun_reset(FBocnAccum_o, value=czero, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end if - !--------------------------------------- - ! update local scalar data - set valid input flag to .true. TODO: - !--------------------------------------- + if (lnd2glc_coupling) then + ! Map accumulated field bundle from land grid (with elevation classes) to glc grid (without elevation classes) + ! and set FBExp(compglc(ns)) data + ! Zero land accumulator and accumulated field bundles on land grid + call med_phases_prep_glc_map_lnd2glc(gcomp, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + FBlndAccumCnt = 0 + call fldbun_reset(FBlndAccum_l, value=czero, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end if - !call med_infodata_set_valid_glc_input(.true., med_infodata, rc=rc) ! TODO: fix this - !if (chkErr(rc,__LINE__,u_FILE_u)) return + if (dbug_flag > 1) then + do ns = 1,num_icesheets + call fldbun_diagnose(is_local%wrap%FBExp(compglc(ns)), string=trim(subname)//' FBexp(compglc) ', rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end do + endif + end if if (dbug_flag > 5) then call ESMF_LogWrite(trim(subname)//": done", ESMF_LOGMSG_INFO) 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 @@ -596,19 +776,18 @@ subroutine map_lnd2glc(gcomp, rc) real(r8) :: elev_l, elev_u ! lower and upper elevations in interpolation range real(r8) :: d_elev ! elev_u - elev_l integer :: nfld, ec - integer :: i,j,n,g,lsize_g + integer :: i,j,n,g,lsize_g,ns integer :: ungriddedUBound_output(1) - integer :: fieldCount type(ESMF_Field) :: lfield type(ESMF_Field) :: field_lfrac_l + integer :: fieldCount + character(len=3) :: cnum type(ESMF_Field), pointer :: fieldlist_lnd(:) => null() type(ESMF_Field), pointer :: fieldlist_glc(:) => null() - character(len=*) , parameter :: subname='(med_phases_prep_glc_mod:med_phases_prep_glc_map_lnd2glc)' + character(len=*) , parameter :: subname=' (med_phases_prep_glc_map_lnd2glc) ' !--------------------------------------- - !--------------------------------------- ! Get the internal state - !--------------------------------------- nullify(is_local%wrap) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -618,193 +797,197 @@ subroutine map_lnd2glc(gcomp, rc) ! to the glc grid (in multiple elevation classes) using bilinear interpolation ! ------------------------------------------------------------------------ + ! Initialize accumulated field bundle on the glc grid to zero before doing the mapping + do ns = 1,num_icesheets + call fldbun_reset(toglc_frlnd(ns)%FBlndAccum_g, value=0.0_r8, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end do + ! TODO(wjs, 2015-01-20) This implies that we pass data to CISM even in places that ! CISM says is ocean (so CISM will ignore the incoming value). This differs from the ! current glint implementation, which sets acab and artm to 0 over ocean (although ! notes that this could lead to a loss of conservation). Figure out how to handle ! this case. - ! get fieldlist from FBlndAccum_lnd - call ESMF_FieldBundleGet(FBlndAccum_lnd, fieldCount=fieldCount, rc=rc) + ! get fieldlist from FBlndAccum_l + call ESMF_FieldBundleGet(FBlndAccum_l, fieldCount=fieldCount, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(fieldlist_lnd(fieldcount)) - call ESMF_FieldBundleGet(FBlndAccum_lnd, fieldlist=fieldlist_lnd, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return allocate(fieldlist_glc(fieldcount)) - call ESMF_FieldBundleGet(FBlndAccum_glc, fieldlist=fieldlist_glc, rc=rc) + call ESMF_FieldBundleGet(FBlndAccum_l, fieldlist=fieldlist_lnd, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! get land fraction field on land mesh - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(complnd), fieldname='lfrac', field=field_lfrac_l, rc=rc) + call ESMF_FieldBundleGet(is_local%wrap%FBFrac(complnd), 'lfrac', field=field_lfrac_l, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return ! TODO: is this needed? - call FB_reset(FBlndAccum_glc, value=0.0_r8, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + do ns = 1,num_icesheets + call fldbun_reset(toglc_frlnd(ns)%FBlndAccum_g, value=0.0_r8, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end do - ! map accumlated land fields and normalize by the land fraction - do n = 1,fieldcount - call med_map_field_normalized( & - field_src=fieldlist_lnd(n), & - field_dst=fieldlist_glc(n), & - routehandles=is_local%wrap%RH(complnd,compglc,:), & - maptype=mapbilnr, & - field_normsrc=field_lfrac_l, & - field_normdst=field_lfrac_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + ! map accumlated land fields to each ice sheet (normalize by the land fraction in the mapping) + do ns = 1,num_icesheets + call ESMF_FieldBundleGet(toglc_frlnd(ns)%FBlndAccum_g, fieldlist=fieldlist_glc, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + do nfld = 1,fieldcount + call med_map_field_normalized( & + field_src=fieldlist_lnd(nfld), & + field_dst=fieldlist_glc(nfld), & + routehandles=is_local%wrap%RH(complnd,compglc(ns),:), & + maptype=mapbilnr, & + field_normsrc=field_lfrac_l, & + field_normdst=toglc_frlnd(ns)%field_lfrac_g, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + end do end do + deallocate(fieldlist_lnd) + deallocate(fieldlist_glc) + if (dbug_flag > 1) then - call FB_diagnose(FBlndAccum_lnd, string=trim(subname)//' FBlndAccum_lnd ', rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - call FB_diagnose(is_local%wrap%FBfrac(complnd), string=trim(subname)//' FBFrac ', rc=rc) + call fldbun_diagnose(FBlndAccum_l, string=trim(subname)//' FBlndAccum_l ', rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - call FB_diagnose(FBlndAccum_glc, string=trim(subname)//' FBlndAccum_glc ', rc=rc) + call fldbun_diagnose(is_local%wrap%FBfrac(complnd), string=trim(subname)//' FBFrac ', rc=rc) if (chkErr(rc,__LINE__,u_FILE_u)) return + do ns = 1,num_icesheets + call fldbun_diagnose(toglc_frlnd(ns)%FBlndAccum_g, string=trim(subname)//& + ' FBlndAccum_glc '//compname(compglc(ns)), rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end do endif ! ------------------------------------------------------------------------ - ! Determine elevation class of each glc point on glc grid (output is topoglc_g) - ! ------------------------------------------------------------------------ - - if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBImp(compglc,compglc), & - string=trim(subname)//' FBImp(compglc,compglc) ', rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - end if - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname=trim(Sg_frac_fieldname), field=lfield, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=ice_covered_g, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname=trim(Sg_topo_fieldname), field=lfield, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=topoglc_g, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - - ! get elevation classes with bare land - ! for grid cells that are ice-free, the elevation class is set to 0. - lsize_g = size(ice_covered_g) - allocate(elevclass_g(lsize_g)) - call glc_get_elevation_classes(ice_covered_g, topoglc_g, elevclass_g, logunit) - - ! ------------------------------------------------------------------------ - ! Determine topo field in multiple elevation classes on the glc grid + ! Determine elevation class of each glc grid gridcell (elevclass_g) ! ------------------------------------------------------------------------ - call ESMF_FieldBundleGet(FBlndAccum_glc, fieldname='Sl_topo_elev', field=lfield, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=topolnd_g_ec, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return + ! Loop over ice sheets + do ns = 1,num_icesheets + if (dbug_flag > 1) then + write(cnum,'(a3)') ns + call fldbun_diagnose(is_local%wrap%FBImp(compglc(ns),compglc(ns)), & + string=trim(subname)//' FBImp(compglc,compglc) '//' for ice sheet '//trim(cnum), rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + end if - ! ------------------------------------------------------------------------ - ! Loop over fields in export field bundle to GLC - ! ------------------------------------------------------------------------ + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_frac_fieldname, ice_covered_g, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_topo_fieldname, topoglc_g, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return - ! TODO(wjs, 2015-01-20) This implies that we pass data to CISM even in places that - ! CISM says is ocean (so CISM will ignore the incoming value). This differs from the - ! current glint implementation, which sets acab and artm to 0 over ocean (although - ! notes that this could lead to a loss of conservation). Figure out how to handle this case. + ! get elevation classes including bare land + ! for grid cells that are ice-free, the elevation class is set to 0. + lsize_g = size(ice_covered_g) + allocate(elevclass_g(lsize_g)) + call glc_get_elevation_classes(ice_covered_g, topoglc_g, elevclass_g, logunit) - allocate(data_ice_covered_g(lsize_g)) - do nfld = 1, size(fldnames_to_glc) + ! Determine topo field in multiple elevation classes on the glc grid + call fldbun_getdata2d(toglc_frlnd(ns)%FBlndAccum_g, 'Sl_topo_elev', topolnd_g_ec, rc=rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return ! ------------------------------------------------------------------------ - ! Perform vertical interpolation of data onto ice sheet topography + ! Loop over fields in export field bundle to glc for ice sheet ns and + ! perform vertical interpolation of data onto ice sheet topography ! This maps all of the input elevation classes into an export to glc without elevation classes ! ------------------------------------------------------------------------ - ! Get a pointer to the land data in multiple elevation classes on the glc grid - call ESMF_FieldBundleGet(FBlndAccum_glc, fieldname=trim(fldnames_fr_lnd(nfld)), & - field=lfield, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=dataptr2d, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - - ! Get a pointer to the data for the field that will be sent to glc (without elevation classes) - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc), fieldname=trim(fldnames_to_glc(nfld)), & - field=lfield, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=dataexp_g, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - - ! First set data_ice_covered_g to bare land everywehre - data_ice_covered_g(:) = 0._r8 + ! TODO(wjs, 2015-01-20) This implies that we pass data to CISM even in places that + ! CISM says is ocean (so CISM will ignore the incoming value). This differs from the + ! current glint implementation, which sets acab and artm to 0 over ocean (although + ! notes that this could lead to a loss of conservation). Figure out how to handle this case. - ! Now overwrite with valid values - do n = 1, lsize_g + allocate(data_ice_covered_g(lsize_g)) + do nfld = 1, size(fldnames_to_glc) - ! For each ice sheet point, find bounding EC values... - if (topoglc_g(n) < topolnd_g_ec(2,n)) then - - ! lower than lowest mean EC elevation value - data_ice_covered_g(n) = dataptr2d(2,n) + ! Get a pointer to the land data in multiple elevation classes on the glc grid + call fldbun_getdata2d(toglc_frlnd(ns)%FBlndAccum_g, fldnames_fr_lnd(nfld), dataptr2d, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return - else if (topoglc_g(n) >= topolnd_g_ec(ungriddedCount, n)) then + ! Get a pointer to the data for the field that will be sent to glc (without elevation classes) + call fldbun_getdata1d(is_local%wrap%FBExp(compglc(ns)), fldnames_to_glc(nfld), dataexp_g, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return - ! higher than highest mean EC elevation value - data_ice_covered_g(n) = dataptr2d(ungriddedCount,n) + ! First set data_ice_covered_g to bare land everywehre + data_ice_covered_g(:) = 0._r8 + + ! Loop over land points and overwrite with valid values + do n = 1, lsize_g + + ! For each ice sheet point, find bounding EC values... + if (topoglc_g(n) < topolnd_g_ec(2,n)) then + + ! lower than lowest mean EC elevation value + data_ice_covered_g(n) = dataptr2d(2,n) + + else if (topoglc_g(n) >= topolnd_g_ec(ungriddedCount, n)) then + + ! higher than highest mean EC elevation value + data_ice_covered_g(n) = dataptr2d(ungriddedCount,n) + + else + + ! do linear interpolation of data in the vertical + do ec = 3, ungriddedCount + if (topoglc_g(n) < topolnd_g_EC(ec,n)) then + elev_l = topolnd_g_EC(ec-1,n) + elev_u = topolnd_g_EC(ec ,n) + d_elev = elev_u - elev_l + if (d_elev <= 0) then + ! This shouldn't happen, but handle it in case it does. In this case, + ! let's arbitrarily use the mean of the two elevation classes, rather + ! than the weighted mean. + write(logunit,*) subname//' WARNING: topo diff between elevation classes <= 0' + write(logunit,*) 'n, ec, elev_l, elev_u = ', n, ec, elev_l, elev_u + write(logunit,*) 'Simply using mean of the two elevation classes,' + write(logunit,*) 'rather than the weighted mean.' + data_ice_covered_g(n) = dataptr2d(ec-1,n) * 0.5_r8 & + + dataptr2d(ec ,n) * 0.5_r8 + else + data_ice_covered_g(n) = dataptr2d(ec-1,n) * (elev_u - topoglc_g(n)) / d_elev & + + dataptr2d(ec ,n) * (topoglc_g(n) - elev_l) / d_elev + end if + exit + end if + end do + end if ! topoglc_g(n) - else + if (elevclass_g(n) /= 0) then + ! ice-covered cells have interpolated values + dataexp_g(n) = data_ice_covered_g(n) + else + ! non ice-covered cells have bare land value + dataexp_g(n) = real(dataptr2d(1,n)) + end if - ! do linear interpolation of data in the vertical - do ec = 3, ungriddedCount - if (topoglc_g(n) < topolnd_g_EC(ec,n)) then - elev_l = topolnd_g_EC(ec-1,n) - elev_u = topolnd_g_EC(ec ,n) - d_elev = elev_u - elev_l - if (d_elev <= 0) then - ! This shouldn't happen, but handle it in case it does. In this case, - ! let's arbitrarily use the mean of the two elevation classes, rather - ! than the weighted mean. - write(logunit,*) subname//' WARNING: topo diff between elevation classes <= 0' - write(logunit,*) 'n, ec, elev_l, elev_u = ', n, ec, elev_l, elev_u - write(logunit,*) 'Simply using mean of the two elevation classes,' - write(logunit,*) 'rather than the weighted mean.' - data_ice_covered_g(n) = dataptr2d(ec-1,n) * 0.5_r8 & - + dataptr2d(ec ,n) * 0.5_r8 - else - data_ice_covered_g(n) = dataptr2d(ec-1,n) * (elev_u - topoglc_g(n)) / d_elev & - + dataptr2d(ec ,n) * (topoglc_g(n) - elev_l) / d_elev - end if - exit - end if - end do - end if ! topoglc_g(n) + end do ! end of loop over land points - if (elevclass_g(n) /= 0) then - ! ice-covered cells have interpolated values - dataexp_g(n) = data_ice_covered_g(n) - else - ! non ice-covered cells have bare land value - dataexp_g(n) = real(dataptr2d(1,n)) - end if - end do ! lsize_g + end do ! end loop over fields (nflds) ! ------------------------------------------------------------------------ ! Renormalize surface mass balance (smb, here named dataexp_g) so that the global ! integral on the glc grid is equal to the global integral on the land grid. ! ------------------------------------------------------------------------ - + ! No longer need to make a preemptive adjustment to qice_g to account for area differences ! between CISM and the coupler. In NUOPC, the area correction is done in! the cap not in the ! mediator, so to preserve the bilinear mapping values, do not need to do any area correction ! scaling in the CISM NUOPC cap - + if (smb_renormalize) then call med_phases_prep_glc_renormalize_smb(gcomp, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return end if - end do ! end of loop over fields + ! clean up memory that is ice sheet dependent + deallocate(elevclass_g) + deallocate(data_ice_covered_g) - ! clean up memory - deallocate(elevclass_g) - deallocate(data_ice_covered_g) + 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) !------------------ @@ -838,46 +1021,63 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) ! and mass in these cases. So in these cases, it's okay that the LND integral computed ! here differs from the integral that LND itself would compute.) ! + ! A note on the areas used in the global sums, with this CMEPS implementation: For + ! glc, we use the internal model areas (sent from glc to the mediator), whereas for + ! lnd, we use the mesh areas (which are the same as the areas used in mapping). The + ! reason for this difference is that for lnd (as for most components), we plan to do + ! area correction (correcting for the discrepancy between internal areas and mesh + ! areas) in the cap, so that the fluxes received by the mediator are expressed + ! per-unit-area according to the mesh areas. However, we are currently *not* planning + ! to do this area correction for glc, because there are some fields that shouldn't be + ! area corrected. Thus, for fluxes sent to glc, they are specified per-unit-area + ! according to the internal areas, so we need to use glc's internal areas in the + ! global sums. (If we did the area correction for qice sent to glc, we would probably + ! want to make a preemptive adjustment to qice, multiplying by the inverse of the area + ! corrections, as we did in MCT / CPL7. This ends up giving the same answer at the + ! cost of additional complexity, and still requires sending glc's internal areas to + ! the mediator so that it can do this preemptive adjustment.) + ! + ! Note: Sg_icemask defines where the ice sheet model can receive a + ! nonzero SMB from the land model. + ! ! For high-level design, see: ! https://docs.google.com/document/d/1H_SuK6SfCv1x6dK91q80dFInPbLYcOkUj_iAa6WRnqQ/edit !------------------ ! input/output variables - type(ESMF_GridComp) :: gcomp - integer , intent(out) :: rc ! return error code + type(ESMF_GridComp) :: gcomp + integer , intent(out) :: rc ! return error code ! local variables - ! Note: Sg_icemask defines where the ice sheet model can receive a nonzero SMB from the land model. type(InternalState) :: is_local type(ESMF_VM) :: vm type(ESMF_Field) :: lfield - real(r8) , pointer :: qice_g(:) => null() ! SMB (Flgl_qice) on glc grid without elev classes - real(r8) , pointer :: qice_l_ec(:,:) => null() ! SMB (Flgl_qice) on land grid with elev classes - real(r8) , pointer :: glc_topo_g(:) => null() ! ice topographic height on the glc grid cell - real(r8) , pointer :: glc_frac_g(:) => null() ! total ice fraction in each glc cell - real(r8) , pointer :: glc_frac_g_ec(:,:) => null() ! total ice fraction in each glc cell - real(r8) , pointer :: glc_frac_l_ec(:,:) => null() ! EC fractions (Sg_ice_covered) on land grid - real(r8) , pointer :: Sg_icemask_g(:) => null() ! icemask on glc grid - real(r8) , pointer :: Sg_icemask_l(:) => null() ! icemask on land grid - real(r8) , pointer :: lfrac(:) => null() ! land fraction on land grid - real(r8) , pointer :: dataptr1d(:) => null() ! temporary 1d pointer - real(r8) , pointer :: dataptr2d(:,:) => null() ! temporary 2d pointer - integer :: ec ! loop index over elevation classes - integer :: n + real(r8) , pointer :: qice_g(:) => null() ! SMB (Flgl_qice) on glc grid without elev classes + real(r8) , pointer :: qice_l_ec(:,:) => null() ! SMB (Flgl_qice) on land grid with elev classes + real(r8) , pointer :: topo_g(:) => null() ! ice topographic height on the glc grid cell + real(r8) , pointer :: frac_g(:) => null() ! total ice fraction in each glc cell + real(r8) , pointer :: frac_g_ec(:,:) => null() ! total ice fraction in each glc cell + real(r8) , pointer :: frac_l_ec(:,:) => null() ! EC fractions (Sg_ice_covered) on land grid + real(r8) , pointer :: icemask_g(:) => null() ! icemask on glc grid + real(r8) , pointer :: icemask_l(:) => null() ! icemask on land grid + real(r8) , pointer :: lfrac(:) => null() ! land fraction on land grid + real(r8) , pointer :: dataptr1d(:) => null() ! temporary 1d pointer + real(r8) , pointer :: dataptr2d(:,:) => null() ! temporary 2d pointer + integer :: ec ! loop index over elevation classes + integer :: n, ns ! local and global sums of accumulation and ablation; used to compute renormalization factors - real(r8), target :: local_accum_lnd(1), global_accum_lnd(1) - real(r8), target :: local_accum_glc(1), global_accum_glc(1) - real(r8), target :: local_ablat_lnd(1), global_ablat_lnd(1) - real(r8), target :: local_ablat_glc(1), global_ablat_glc(1) + real(r8) :: local_accum_lnd(1), global_accum_lnd(1) + real(r8) :: local_accum_glc(1), global_accum_glc(1) + real(r8) :: local_ablat_lnd(1), global_ablat_lnd(1) + real(r8) :: local_ablat_glc(1), global_ablat_glc(1) ! renormalization factors (should be close to 1, e.g. in range 0.95 to 1.05) real(r8) :: accum_renorm_factor ! ratio between global accumulation on the two grids real(r8) :: ablat_renorm_factor ! ratio between global ablation on the two grids - - real(r8) :: effective_area ! grid cell area multiplied by min(lfrac,Sg_icemask_l). - ! This is the area that can contribute SMB to the ice sheet model. - character(len=*), parameter :: subname='(med_phases_prep_glc_renormalize_smb)' + real(r8) :: effective_area ! grid cell area multiplied by min(lfrac,icemask_l). + real(r8), pointer :: area_g(:) ! areas on glc grid + character(len=*), parameter :: subname=' (renormalize_smb) ' !--------------------------------------------------------------- call t_startf('MED:'//subname) @@ -895,168 +1095,211 @@ subroutine med_phases_prep_glc_renormalize_smb(gcomp, rc) call ESMF_GridCompGetInternalState(gcomp, is_local, rc) if (chkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - ! Map Sg_icemask_g from the glc grid to the land grid. - !--------------------------------------- + do ns = 1,num_icesheets - ! determine Sg_icemask_g and set as contents of FBglc_icemask - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname=trim(Sg_icemask_fieldname), 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 - call ESMF_FieldGet(field_glc_icemask_g, farrayptr=Sg_icemask_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - Sg_icemask_g(:) = dataptr1d(:) - - ! map ice mask from glc to lnd with no normalization - ! BUG(wjs, 2017-05-11, #1516) I think we actually want norm = .false. here, but this needs more thought - ! Below the implementation is without normalization - this should be checked moving forwards - call med_map_field( & - field_src=field_glc_icemask_g, & - field_dst=field_glc_icemask_l, & - routehandles=is_local%wrap%RH(compglc,complnd,:), & - maptype=mapconsf, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return + !--------------------------------------- + ! Map icemask_g from the glc grid to the land grid. + !--------------------------------------- + + ! determine icemask_g and set as contents of field_icemask_g + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_icemask_fieldname, dataptr1d, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata1d(toglc_frlnd(ns)%field_icemask_g, icemask_g, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + icemask_g(:) = dataptr1d(:) + + ! map ice mask from glc to lnd with no normalization + call med_map_field( & + field_src=toglc_frlnd(ns)%field_icemask_g, & + field_dst=field_icemask_l, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & + maptype=mapconsd, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! ------------------------------------------------------------------------ - ! Map frac_field on glc grid without elevation classes to frac_field on land grid with elevation classes - ! ------------------------------------------------------------------------ + ! get icemask_l + call field_getdata1d(field_icemask_l, icemask_l, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return - ! set FBglc_frac on the glc grid (fractional ice coverage per elevation class) - ! glc_topo_g(:) is the topographic height of each glc gridcell - ! glc_frac_g(:) is the total ice fraction in each glc gridcell - ! glc_frac_g_ec(:,:) are the glc fractions on the glc grid for each elevation class (inner dimension) - ! setting glc_frac_g_ec (in the call to glc_get_fractional_icecov) sets the contents of FBglc_frac - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname=trim(Sg_topo_fieldname), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=glc_topo_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname=trim(Sg_frac_fieldname), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=glc_frac_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_glc_frac_g, farrayptr=glc_frac_g, rc=rc) ! module field - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_glc_frac_g_ec, farrayptr=glc_frac_g_ec, rc=rc) ! module field - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! note that nec = ungriddedCount - 1 - call glc_get_fractional_icecov(ungriddedCount-1, glc_topo_g, glc_frac_g, glc_frac_g_ec, logunit) - - ! map fraction in each elevation class from the glc grid to the land grid and normalize by the icemask on the - ! glc grid - call med_map_field_normalized( & - field_src=field_glc_frac_g_ec, & - field_dst=field_glc_frac_l_ec, & - routehandles=is_local%wrap%RH(compglc,complnd,:), & - maptype=mapconsf, & - field_normsrc=field_glc_icemask_g, & - field_normdst=field_glc_icemask_l, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! get fractional ice coverage for each elevation class on the land grid, glc_frac_l_ec(:,:) - call ESMF_FieldGet(field_glc_frac_l_ec, farrayptr=glc_frac_l_ec, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return + ! ------------------------------------------------------------------------ + ! Map frac_field on glc grid without elevation classes to frac_field on land grid with elevation classes + ! ------------------------------------------------------------------------ - ! determine fraction on land grid, lfrac(:) - call ESMF_FieldBundleGet(is_local%wrap%FBFrac(complnd), fieldname='lfrac', field=lfield, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=lfrac, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return + ! get topo_g(:), the topographic height of each glc gridcell + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), Sg_topo_fieldname, topo_g, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - ! get Sg_icemask_l(:) - call ESMF_FieldGet(field_glc_icemask_l, farrayptr=Sg_icemask_l, rc=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_fieldname, dataptr1d, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata1d(toglc_frlnd(ns)%field_lfrac_g, frac_g, rc) ! module field + frac_g(:) = dataptr1d(:) - ! determine qice_l_ec - call ESMF_FieldBundleGet(FBlndAccum_lnd, trim(qice_fieldname)//'_elev', field=lfield, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=qice_l_ec, rc=rc) - if (chkErr(rc,__LINE__,u_FILE_u)) return + ! get frac_g_ec - the glc_elevclass gives the elevation class of each + ! glc grid cell, assuming that the grid cell is ice-covered, spans [1 -> ungriddedcount] + call field_getdata2d(toglc_frlnd(ns)%field_frac_g_ec, frac_g_ec, rc=rc) ! module field + if (chkerr(rc,__LINE__,u_FILE_u)) return + call glc_get_fractional_icecov(ungriddedCount-1, topo_g, frac_g, frac_g_ec, logunit) - !--------------------------------------- - ! Sum qice_l_ec over all elevation classes for each local land grid cell then do a global sum - !--------------------------------------- + ! map fraction in each elevation class from the glc grid to the land grid and normalize by the icemask on the + ! glc grid + call med_map_field_normalized( & + field_src=toglc_frlnd(ns)%field_frac_g_ec, & + field_dst=field_frac_l_ec, & + routehandles=is_local%wrap%RH(compglc(ns),complnd,:), & + maptype=mapconsd, & + field_normsrc=toglc_frlnd(ns)%field_icemask_g, & + field_normdst=field_normdst_l, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - local_accum_lnd(1) = 0.0_r8 - local_ablat_lnd(1) = 0.0_r8 - do n = 1, size(lfrac) - ! Calculate effective area for sum - need the mapped Sg_icemask_l - effective_area = min(lfrac(n), Sg_icemask_l(n)) * aream_l(n) + !--------------------------------------- + ! Sum qice_l_ec over all elevation classes for each local land grid cell then do a global sum + !--------------------------------------- - do ec = 1, ungriddedCount - if (qice_l_ec(ec,n) >= 0.0_r8) then - local_accum_lnd(1) = local_accum_lnd(1) + effective_area * glc_frac_l_ec(ec,n) * qice_l_ec(ec,n) - else - local_ablat_lnd(1) = local_ablat_lnd(1) + effective_area * glc_frac_l_ec(ec,n) * qice_l_ec(ec,n) - endif - enddo ! ec - enddo ! n - call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMAllreduce(vm, senddata=local_accum_lnd, recvdata=global_accum_lnd, count=1, reduceflag=ESMF_REDUCE_SUM, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_VMAllreduce(vm, senddata=local_ablat_lnd, recvdata=global_ablat_lnd, count=1, reduceflag=ESMF_REDUCE_SUM, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return + ! get fractional ice coverage for each elevation class on the land grid, frac_l_ec(:,:) + call field_getdata2d(field_frac_l_ec, frac_l_ec, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return - !--------------------------------------- - ! Sum qice_g over local glc grid cells. - !--------------------------------------- + ! determine fraction on land grid, lfrac(:) + call fldbun_getdata1d(is_local%wrap%FBFrac(complnd), 'lfrac', lfrac, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return - ! TODO: is the following a problem - ! Note: This sum uses the coupler areas (aream_g), which differ from the native CISM areas. - ! But since the original qice_g (from bilinear remapping) has been multiplied by - ! area_g/aream_g above, this calculation is equivalent to multiplying the original qice_g - ! by the native CISM areas (area_g). - ! If Flgl_qice were changed to a state (and not included in seq_flds_x2g_fluxes), - ! then it would be appropriate to use the native CISM areas in this sum. - - ! determine qice_g - call ESMF_FieldBundleGet(is_local%wrap%FBExp(compglc), fieldname=trim(qice_fieldname), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=qice_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - local_accum_glc(1) = 0.0_r8 - local_ablat_glc(1) = 0.0_r8 - do n = 1, size(qice_g) - if (qice_g(n) >= 0.0_r8) then - local_accum_glc(1) = local_accum_glc(1) + Sg_icemask_g(n) * aream_g(n) * qice_g(n) - else - local_ablat_glc(1) = local_ablat_glc(1) + Sg_icemask_g(n) * aream_g(n) * qice_g(n) + ! get qice_l_ec + call fldbun_getdata2d(FBlndAccum_l, trim(qice_fieldname)//'_elev', qice_l_ec, rc) + if (chkErr(rc,__LINE__,u_FILE_u)) return + + local_accum_lnd(1) = 0.0_r8 + local_ablat_lnd(1) = 0.0_r8 + do n = 1, size(lfrac) + ! Calculate effective area for sum - need the mapped icemask_l + effective_area = min(lfrac(n), icemask_l(n)) * is_local%wrap%mesh_info(complnd)%areas(n) + if (effective_area > 0.0_r8) then + do ec = 1, ungriddedCount + if (qice_l_ec(ec,n) >= 0.0_r8) then + local_accum_lnd(1) = local_accum_lnd(1) + effective_area * frac_l_ec(ec,n) * qice_l_ec(ec,n) + else + local_ablat_lnd(1) = local_ablat_lnd(1) + effective_area * frac_l_ec(ec,n) * qice_l_ec(ec,n) + endif + end do ! ec + end if ! if landmaks > 0 + enddo ! n + + call ESMF_GridCompGet(gcomp, vm=vm, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMAllreduce(vm, senddata=local_accum_lnd, recvdata=global_accum_lnd, count=1, & + reduceflag=ESMF_REDUCE_SUM, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + call ESMF_VMAllreduce(vm, senddata=local_ablat_lnd, recvdata=global_ablat_lnd, count=1, & + reduceflag=ESMF_REDUCE_SUM, rc=rc) + if (ChkErr(rc,__LINE__,u_FILE_u)) return + if (mastertask) then + write(logunit,'(a,d21.10)') trim(subname)//'global_accum_lnd = ', global_accum_lnd + write(logunit,'(a,d21.10)') trim(subname)//'global_ablat_lnd = ', global_ablat_lnd endif - enddo ! n - call ESMF_VMAllreduce(vm, senddata=local_accum_glc, recvdata=global_accum_glc, count=1, reduceflag=ESMF_REDUCE_SUM, rc=rc) - call ESMF_VMAllreduce(vm, senddata=local_ablat_glc, recvdata=global_ablat_glc, count=1, reduceflag=ESMF_REDUCE_SUM, rc=rc) - ! Renormalize - if (global_accum_glc(1) > 0.0_r8) then - accum_renorm_factor = global_accum_lnd(1) / global_accum_glc(1) - else - accum_renorm_factor = 0.0_r8 - endif + !--------------------------------------- + ! Sum qice_g over local glc grid cells. + !--------------------------------------- - if (global_ablat_glc(1) < 0.0_r8) then ! negative by definition - ablat_renorm_factor = global_ablat_lnd(1) / global_ablat_glc(1) - else - ablat_renorm_factor = 0.0_r8 - endif + ! determine qice_g + call fldbun_getdata1d(is_local%wrap%FBExp(compglc(ns)), qice_fieldname, qice_g, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - if (mastertask) then - write(logunit,*) 'accum_renorm_factor = ', accum_renorm_factor - write(logunit,*) 'ablat_renorm_factor = ', ablat_renorm_factor - endif + ! get areas internal to glc grid + call fldbun_getdata1d(is_local%wrap%FBImp(compglc(ns),compglc(ns)), 'Sg_area', area_g, rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return - do n = 1, size(qice_g) - if (qice_g(n) >= 0.0_r8) then - qice_g(n) = qice_g(n) * accum_renorm_factor + local_accum_glc(1) = 0.0_r8 + local_ablat_glc(1) = 0.0_r8 + do n = 1, size(qice_g) + if (qice_g(n) >= 0.0_r8) then + local_accum_glc(1) = local_accum_glc(1) + icemask_g(n) * area_g(n) * qice_g(n) + else + local_ablat_glc(1) = local_ablat_glc(1) + icemask_g(n) * area_g(n) * qice_g(n) + endif + enddo ! n + call ESMF_VMAllreduce(vm, senddata=local_accum_glc, recvdata=global_accum_glc, count=1, & + reduceflag=ESMF_REDUCE_SUM, rc=rc) + call ESMF_VMAllreduce(vm, senddata=local_ablat_glc, recvdata=global_ablat_glc, count=1, & + reduceflag=ESMF_REDUCE_SUM, rc=rc) + if (mastertask) then + write(logunit,'(a,d21.10)') trim(subname)//'global_accum_glc = ', global_accum_glc + write(logunit,'(a,d21.10)') trim(subname)//'global_ablat_glc = ', global_ablat_glc + endif + + ! Renormalize + if (global_accum_glc(1) > 0.0_r8) then + accum_renorm_factor = global_accum_lnd(1) / global_accum_glc(1) else - qice_g(n) = qice_g(n) * ablat_renorm_factor + accum_renorm_factor = 0.0_r8 + endif + if (global_ablat_glc(1) < 0.0_r8) then ! negative by definition + ablat_renorm_factor = global_ablat_lnd(1) / global_ablat_glc(1) + else + ablat_renorm_factor = 0.0_r8 + endif + if (mastertask) then + write(logunit,'(a,d21.10)') trim(subname)//'accum_renorm_factor = ', accum_renorm_factor + write(logunit,'(a,d21.10)') trim(subname)//'ablat_renorm_factor = ', ablat_renorm_factor endif - enddo + + do n = 1, size(qice_g) + if (qice_g(n) >= 0.0_r8) then + qice_g(n) = qice_g(n) * accum_renorm_factor + else + qice_g(n) = qice_g(n) * ablat_renorm_factor + endif + enddo + + end do ! end of loop over ice sheets call t_stopf('MED:'//subname) end subroutine med_phases_prep_glc_renormalize_smb + !================================================================================================ + subroutine dynOcnMaskProc(dynamicMaskList, dynamicSrcMaskValue, dynamicDstMaskValue, rc) + + use ESMF, only : ESMF_RC_ARG_BAD + + ! input/output arguments + type(ESMF_DynamicMaskElementR8R8R8) , pointer :: dynamicMaskList(:) + real(ESMF_KIND_R8), intent(in), optional :: dynamicSrcMaskValue + real(ESMF_KIND_R8), intent(in), optional :: dynamicDstMaskValue + integer , intent(out) :: rc + + ! local variables + integer :: i, j + real(ESMF_KIND_R8) :: renorm + !--------------------------------------------------------------- + + rc = ESMF_SUCCESS + + ! Below - ONLY if you do NOT have the source masked out then do + ! the regridding (which is done explicitly here) + + if (associated(dynamicMaskList)) then + do i=1, size(dynamicMaskList) + dynamicMaskList(i)%dstElement = czero ! set to zero + renorm = 0.d0 ! reset + do j = 1, size(dynamicMaskList(i)%factor) + if (dynamicSrcMaskValue /= dynamicMaskList(i)%srcElement(j)) then + dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement + & + (dynamicMaskList(i)%factor(j) * dynamicMaskList(i)%srcElement(j)) + renorm = renorm + dynamicMaskList(i)%factor(j) + endif + enddo + if (renorm > 0.d0) then + dynamicMaskList(i)%dstElement = dynamicMaskList(i)%dstElement / renorm + else if (present(dynamicSrcMaskValue)) then + dynamicMaskList(i)%dstElement = dynamicSrcMaskValue + else + rc = ESMF_RC_ARG_BAD ! error detected + return + endif + enddo + endif + + end subroutine DynOcnMaskProc + end module med_phases_prep_glc_mod + diff --git a/mediator/med_phases_prep_ice_mod.F90 b/mediator/med_phases_prep_ice_mod.F90 index a315e2c15..df4c08c4f 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,78 @@ 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) - 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 ice + scalar_id=is_local%wrap%flds_scalar_index_nextsw_cday + if (scalar_id > 0 .and. mastertask) then + 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 + dataptr_scalar_ice(scalar_id,1) = dataptr_scalar_atm(scalar_id,1) + end if - 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 - 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 d8290aa37..fd2a32c95 100644 --- a/mediator/med_phases_prep_lnd_mod.F90 +++ b/mediator/med_phases_prep_lnd_mod.F90 @@ -4,58 +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 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, compglc, ncomps, compname, mapconsd - use esmFlds , only : fldListTo - use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_FldChk => med_methods_FB_fldchk - 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_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(ESMF_Field) :: field_icemask_g ! no elevation classes - type(ESMF_Field) :: field_icemask_l ! no elevation classes - type(ESMF_Field) :: field_frac_g_ec ! elevation classes - type(ESMF_Field) :: field_frac_l_ec ! elevation classes - type(ESMF_Field) :: field_frac_x_icemask_g_ec ! elevation classes - type(ESMF_Field) :: field_frac_x_icemask_l_ec ! elevation classes - type(ESMF_Field) :: field_topo_x_icemask_g_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) + real(r8), pointer :: dataptr_scalar_lnd(:,:) => null() + real(r8), pointer :: dataptr_scalar_atm(:,:) => null() character(*) , parameter :: u_FILE_u = & __FILE__ @@ -66,16 +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 - real(r8) :: nextsw_cday - logical :: first_call = .true. + 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)' !--------------------------------------- @@ -100,29 +77,13 @@ subroutine med_phases_prep_lnd(gcomp, rc) if (ncnt > 0) then - !--------------------------------------- - ! map to create FBimp(:,complnd) - !--------------------------------------- - - do n1 = 1,ncomps - if (is_local%wrap%med_coupling_active(n1,complnd)) 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 do - - !--------------------------------------- - ! auto merges to create FBExp(complnd) - !--------------------------------------- + ! 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 - ! (for glc these are Sg_icemask and Sg_icemask_coupled_fluxes) + call t_startf('MED:'//trim(subname)//' merge') call med_merge_auto(complnd, & is_local%wrap%med_coupling_active(:,complnd), & is_local%wrap%FBExp(complnd), & @@ -130,53 +91,48 @@ subroutine med_phases_prep_lnd(gcomp, rc) is_local%wrap%FBImp(:,complnd), & fldListTo(complnd), rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return + call t_stopf('MED:'//trim(subname)//' merge') - !--------------------------------------- - ! custom calculations - !--------------------------------------- - - ! The following is only done if glc->lnd coupling is active - if (is_local%wrap%comp_present(compglc) .and. (is_local%wrap%med_coupling_active(compglc,complnd))) 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 - ! 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) + 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(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 ! diagnose if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(complnd), & + call fldbun_diagnose(is_local%wrap%FBExp(complnd), & string=trim(subname)//' FBexp(complnd) ', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return end if end if + ! Set first call logical to false first_call = .false. if (dbug_flag > 5) then @@ -186,304 +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 - type(ESMF_Mesh) :: lmesh_lnd - type(ESMF_Mesh) :: lmesh_glc - integer :: ungriddedUBound_output(1) - integer :: fieldCount - 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), fieldname='Sg_topo_elev', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, ungriddedUBound=ungriddedUBound_output, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - ungriddedCount = ungriddedUBound_output(1) - ! TODO: check that ungriddedCount = glc_nec+1 - - !--------------------------------------- - ! Get the glc and land meshes - !--------------------------------------- - - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldCount=fieldCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist(fieldcount)) - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldlist=fieldlist, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(fieldlist(1), mesh=lmesh_lnd, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fieldlist) - - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldCount=fieldCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist(fieldcount)) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldlist=fieldlist, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(fieldlist(1), mesh=lmesh_glc, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fieldlist) - - ! ------------------------------- - ! Create module field bundles - ! ------------------------------- - - field_icemask_g = ESMF_FieldCreate(lmesh_glc, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - field_icemask_l = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - field_frac_g_ec = ESMF_FieldCreate(lmesh_glc, 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_l_ec = ESMF_FieldCreate(lmesh_lnd, 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_g_ec = ESMF_FieldCreate(lmesh_glc, 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(lmesh_lnd, 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_g_ec = ESMF_FieldCreate(lmesh_glc, 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(lmesh_lnd, 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,complnd,mapconsd), rc=rc)) then - call med_map_routehandles_init( compglc, complnd, field_icemask_g, field_icemask_l, & - mapindex=mapconsd, routehandles=is_local%wrap%rh(compglc,complnd,:), rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - - ! Currently cannot map hflx in multiple elevation classes from glc to land - if (FB_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 - integer :: ec, l, g - 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() ! topographic height of each glc cell (no elevation classes) - real(r8), pointer :: topo_l_ec(:,:) => null() ! topographic height in each land gridcell for each elevation 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() - 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 - - !--------------------------------- - ! Map fractional ice coverage to the land grid (multiple elevation classes) - !--------------------------------- - - ! Set contents of FBglc_ec to contain frac_g_ec - ! (fractional ice coverage for each elevation class on the glc grid) - - ! set FBglc_ec on the glc grid (fractional ice coverage per elevation class) - ! topo_g(:) is the topographic height of each glc gridcell - ! frac_g(:) is the total ice fraction in each glc gridcell - ! frac_g_ec(:,:) are the glc fractions on the glc grid for each elevation class (inner dimension) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname=trim(Sg_topo), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=topo_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - - ! compute frac_g_ec - call ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname=trim(Sg_frac), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=frac_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_frac_g_ec, farrayptr=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 ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname=trim(Sg_icemask), 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 - call ESMF_FieldGet(field_icemask_g, farrayptr=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 ESMF_FieldGet(field_frac_x_icemask_g_ec, farrayptr=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=field_frac_g_ec, & - field_dst=field_frac_l_ec, & - routehandles=is_local%wrap%RH(compglc,complnd,:), & - maptype=mapconsd, & - field_normsrc=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 - call ESMF_fieldGet(field_frac_l_ec, farrayptr=frac_l_ec, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_frac)//'_elev', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_fieldGet(lfield, farrayptr=dataptr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr2d(:,:) = frac_l_ec(:,:) - - !--------------------------------- - ! Map topo to the land grid (multiple elevation classes) - !--------------------------------- - - ! Note that all topo values in FBimp(compglc,compglc) 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 ESMF_FieldBundleGet(is_local%wrap%FBImp(compglc,compglc), fieldname=trim(Sg_topo), field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_fieldGet(lfield, farrayptr=topo_g, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_topo_x_icemask_g_ec, farrayptr=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=field_topo_x_icemask_g_ec, & - field_dst=field_topo_x_icemask_l_ec, & - routehandles=is_local%wrap%RH(compglc,complnd,:), & - maptype=mapconsd, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_topo_x_icemask_l_ec, farrayptr=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=field_frac_x_icemask_g_ec, & - field_dst=field_frac_x_icemask_l_ec, & - routehandles=is_local%wrap%RH(compglc,complnd,:), & - maptype=mapconsd, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_frac_x_icemask_l_ec, farrayptr=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. - call ESMF_FieldBundleGet(is_local%wrap%FBExp(complnd), fieldname=trim(Sg_topo)//'_elev', field=lfield, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(lfield, farrayptr=dataptr2d, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - 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(ec,l) <= 0._r8) then - dataptr2d(ec,l) = topo_virtual - else - if (frac_x_icemask_l_ec(ec,l) == 0.0_r8) then - dataptr2d(ec,l) = 0.0_r8 - else - dataptr2d(ec,l) = topo_l_ec(ec,l) / frac_x_icemask_l_ec(ec,l) - end if - end if - end do - 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 8f45201d0..e924058f8 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 @@ -116,7 +53,7 @@ subroutine med_phases_prep_ocn_merge(gcomp, rc) ! local variables type(InternalState) :: is_local integer :: n, ncnt - character(len=*), parameter :: subname='(med_phases_prep_ocn_merge)' + character(len=*), parameter :: subname='(med_phases_prep_ocn_accum)' !--------------------------------------- call t_startf('MED:'//subname) @@ -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_avg)' !--------------------------------------- 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 3c52851c9..d5fd94430 100644 --- a/mediator/med_phases_prep_rof_mod.F90 +++ b/mediator/med_phases_prep_rof_mod.F90 @@ -13,20 +13,25 @@ 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_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 - use med_methods_mod , only : FB_diagnose => med_methods_FB_diagnose - use med_methods_mod , only : FB_accum => med_methods_FB_accum - use med_methods_mod , only : FB_average => med_methods_FB_average + 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 + use med_methods_mod , only : fldbun_getmesh => med_methods_FB_getmesh + use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d + 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_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 use perf_mod , only : t_startf, t_stopf 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 @@ -44,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__ @@ -60,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 @@ -71,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)' !--------------------------------------- @@ -83,51 +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 FB_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 FB_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 @@ -138,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 @@ -159,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)' + character(CL), pointer :: lfieldnamelist(:) => null() + character(len=*),parameter :: subname='(med_phases_prep_rof_mod: med_phases_prep_rof)' !--------------------------------------- call t_startf('MED:'//subname) @@ -177,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) @@ -185,128 +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 - - if (ncnt == 0) then - call ESMF_LogWrite(trim(subname)//": only scalar data is present in FBexp(comprof), returning", & - ESMF_LOGMSG_INFO) - else - - !--------------------------------------- - ! average import from land accumuled FB - !--------------------------------------- + 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 - call FB_average(is_local%wrap%FBImpAccum(complnd,complnd), is_local%wrap%FBImpAccumCnt(complnd), rc=rc) + 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 (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBImpAccum(complnd,complnd), & - string=trim(subname)//' FBImpAccum(complnd,complnd) after avg ', rc=rc) + 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 - 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 FB_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 ) + 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 - ! This will ensure that no irrig is sent from the land - call ESMF_FieldBundleGet(is_local%wrap%FBImpAccum(complnd,comprof), fieldname=trim(irrig_flux_field), & - field=field_irrig_flux, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_irrig_flux, farrayptr=dataptr, rc=rc) + call field_getdata1d(lfield, dataptr1d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - dataptr(:) = 0._r8 + if (count == 0) then + dataptr1d(:) = czero + else + dataptr1d(:) = dataptr1d(:) / real(count, r8) + end if end if - endif + end if + end do + + 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 + + !--------------------------------------- + ! Map to create FBImpAccum(complnd,comprof) + !--------------------------------------- - !--------------------------------------- - ! auto merges to create FBExp(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 FB_diagnose(is_local%wrap%FBFrac(comprof), & - string=trim(subname)//' FBFrac(comprof) before merge ', 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 - 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 - - if (dbug_flag > 1) then - call FB_diagnose(is_local%wrap%FBExp(comprof), & - string=trim(subname)//' FBexp(comprof) ', rc=rc) + ! 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) + !--------------------------------------- - !--------------------------------------- - ! zero accumulator and FBAccum - !--------------------------------------- + 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 - is_local%wrap%FBImpAccumCnt(complnd) = 0 + 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 ESMF_FieldBundleGet(is_local%wrap%FBImpAccum(complnd,complnd), fieldCount=fieldCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist(fieldcount)) - call ESMF_FieldBundleGet(is_local%wrap%FBImpAccum(complnd,complnd), fieldlist=fieldlist, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - do n = 1, fieldCount - call ESMF_FieldGet(fieldlist(n), ungriddedUBound=ungriddedUBound, 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 + + !--------------------------------------- + ! zero accumulator and FBAccum + !--------------------------------------- + + ! zero counter + is_local%wrap%FBImpAccumCnt(complnd) = 0 + + ! 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 - if (ungriddedUbound(1) > 0) then - call ESMF_FieldGet(fieldlist(n), farrayPtr=dataptr2d, rc=rc) + 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 ESMF_FieldGet(fieldlist(n), farrayPtr=dataptr1d, rc=rc) + call field_getdata1d(lfield, dataptr1d, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return dataptr1d(:) = czero end if - end do - deallocate(fieldlist) + 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) @@ -332,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 @@ -375,7 +417,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) rc = ESMF_SUCCESS !--------------------------------------- - ! --- Get the internal state + ! Get the internal state !--------------------------------------- nullify(is_local%wrap) @@ -408,23 +450,10 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) .not. ESMF_FieldIsCreated(field_lfrac_rof)) then ! get fields in source and destination field bundles - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldCount=fieldCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist_lnd(fieldcount)) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(complnd,complnd), fieldlist=fieldlist_lnd, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(fieldlist_lnd(1), mesh=lmesh_lnd, rc=rc) + call fldbun_getmesh(is_local%wrap%FBImp(complnd,complnd), lmesh_lnd, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fieldlist_lnd) - - call ESMF_FieldBundleGet(is_local%wrap%FBImp(comprof,comprof), fieldCount=fieldCount, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - allocate(fieldlist_rof(fieldcount)) - call ESMF_FieldBundleGet(is_local%wrap%FBImp(comprof,comprof), fieldlist=fieldlist_rof, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(fieldlist_rof(1), mesh=lmesh_rof, rc=rc) + call fldbun_getmesh(is_local%wrap%FBImp(comprof,comprof), lmesh_rof, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - deallocate(fieldlist_rof) field_lndVolr = ESMF_FieldCreate(lmesh_lnd, ESMF_TYPEKIND_R8, meshloc=ESMF_MESHLOC_ELEMENT, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return @@ -456,12 +485,9 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) ! actually adds water to those cells). ! Create volr_r - call ESMF_FieldBundleGet(is_local%wrap%FBImp(comprof,comprof), fieldname=trim(volr_field), & - field=field_import_rof, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_import_rof, farrayptr=volr_r_import, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBImp(comprof,comprof), trim(volr_field), volr_r_import, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_rofVolr, farrayptr=volr_r, rc=rc) + call field_getdata1d(field_rofVolr, volr_r, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do r = 1, size(volr_r) if (volr_r_import(r) < 0._r8) then @@ -480,7 +506,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Get volr_l - call ESMF_FieldGet(field_lndVolr, farrayptr=volr_l, rc=rc) + call field_getdata1d(field_lndVolr, volr_l, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! ------------------------------------------------------------------------ @@ -499,16 +525,13 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) ! flux on the rof grid. ! First extract accumulated irrigation flux from land - call ESMF_FieldBundleGet(is_local%wrap%FBImpAccum(complnd,complnd), fieldname=trim(irrig_flux_field), & - field=field_irrig_flux, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_irrig_flux, farrayptr=irrig_flux_l, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBImpAccum(complnd,complnd), trim(irrig_flux_field), irrig_flux_l, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return ! Fill in values for irrig_normalized_l and irrig_volr0_l - call ESMF_FieldGet(field_lndIrrig, farrayptr=irrig_normalized_l, rc=rc) + call field_getdata1d(field_lndIrrig, irrig_normalized_l, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_lndIrrig0, farrayptr=irrig_volr0_l, rc=rc) + call field_getdata1d(field_lndIrrig0, irrig_volr0_l, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do l = 1, size(volr_l) @@ -528,6 +551,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) call ESMF_FieldBundleGet(is_local%wrap%FBFrac(complnd), 'lfrac', field=field_lfrac_lnd, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_field_normalized( & field_src=field_lndIrrig, & field_dst=field_rofIrrig, & @@ -536,6 +560,7 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) field_normsrc=field_lfrac_lnd, & field_normdst=field_lfrac_rof, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return + call med_map_field_normalized( & field_src=field_lndIrrig0, & field_dst=field_rofIrrig0, & @@ -544,18 +569,15 @@ subroutine med_phases_prep_rof_irrig(gcomp, rc) field_normsrc=field_lfrac_lnd, & field_normdst=field_lfrac_rof, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_rofIrrig, farrayptr=irrig_normalized_r, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_rofIrrig0, farrayptr=irrig_volr0_r, rc=rc) - if (chkerr(rc,__LINE__,u_FILE_u)) return ! Convert to a total irrigation flux on the ROF grid, and put this in the pre-merge FBImpAccum(complnd,comprof) - call ESMF_FieldBundleGet(is_local%wrap%FBImpAccum(complnd,comprof), fieldname=trim(irrig_flux_field), & - field=field_import_rof, rc=rc) + call field_getdata1d(field_rofIrrig, irrig_normalized_r, rc=rc) + if (chkerr(rc,__LINE__,u_FILE_u)) return + call field_getdata1d(field_rofIrrig0, irrig_volr0_r, rc=rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_import_rof, farrayptr=irrig_flux_r, rc=rc) + call fldbun_getdata1d(is_local%wrap%FBImpAccum(complnd,comprof), trim(irrig_flux_field), irrig_flux_r, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return - call ESMF_FieldGet(field_rofIrrig0, farrayptr=irrig_volr0_r, rc=rc) + call field_getdata1d(field_rofIrrig0, irrig_volr0_r, rc) if (chkerr(rc,__LINE__,u_FILE_u)) return do r = 1, size(irrig_flux_r) diff --git a/mediator/med_phases_profile_mod.F90 b/mediator/med_phases_profile_mod.F90 index ffc59dc77..447b1e4c2 100644 --- a/mediator/med_phases_profile_mod.F90 +++ b/mediator/med_phases_profile_mod.F90 @@ -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), & diff --git a/nems/util/CMakeLists.txt b/nems/util/CMakeLists.txt new file mode 100644 index 000000000..e99cfda83 --- /dev/null +++ b/nems/util/CMakeLists.txt @@ -0,0 +1,7 @@ +project(CMEPS_share Fortran) +include(ExternalProject) + +add_library(cmeps_share shr_abort_mod.F90 shr_flux_mod.F90 shr_log_mod.F90 shr_mpi_mod.F90 shr_sys_mod.F90 + glc_elevclass_mod.F90 perf_mod.F90 shr_const_mod.F90 shr_kind_mod.F90 shr_mem_mod.F90 shr_pio_mod.F90) + +target_include_directories (cmeps_share PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${ESMF_F90COMPILEPATHS} ${PIO_Fortran_INCLUDE_DIRS})